Post 2: Titel-Slide gezeichnet, Helmlage umschaltbar

Das Foto bleibt roh, gezeichnet wird drumherum. Der Rahmen ist die
Markenform, dazu ein versetzter Zweitzug und eine schraffierte Kante.
Die drei greifen ineinander statt nebeneinanderher zu laufen: der
versetzte Zug ist die Aussenkante des Schattens, die Schraffur fuellt das
Band dazwischen. Zur Schattenfrage steht ein Hinweis im Code -- Paragraf
5 in rules.md verbietet weichgezeichnete Schatten, und die dort notierte
Ausnahme sagt, eine Linie ist kein Schatten. Eine Schraffur besteht aus
Linien.

Der Helm sitzt wahlweise an der abgeschnittenen Rahmenecke oder auf
Noahs Kopf. Das haengt am Layout-Schalter der Slide, also am vorhandenen
Geruest, und nicht an einem eigenen Sonderschalter. In der Ecken-Lage
kippt er nach rechts, damit die Oeffnung ueber der Ecke liegt: nach links
gekippt sah er aus, als falle er herunter.

Drei Anlaeufe stecken im Helm, die Zwischenschritte stehen als Kommentar
dabei. Erst war die Kuppel flach und die Krempe eine geschlossene Scheibe
darunter, zusammen eine Schirmmuetze. Dann kam Schraffur dazu, und die
Waagerechten kreuzten die Grate zu einem Gitter, also einem Korb. Was
traegt, sind viele Stuetzpunkte, ein First, zwei Nebenrippen und eine
Krempe mit Dicke.

Drei Dinge waren technisch noetig:

Die Zeichenebene ist rechts breiter geworden, von 114,8 auf 128,4
Prozent. In der Ecken-Lage ragt der Helm ueber den Rahmen hinaus und
waere sonst beim Export abgeschnitten worden.

renderPage erneuerte bisher nur den Textblock. Ein Layoutwechsel haette
die Zeichnung nicht angefasst und der Schalter waere wirkungslos
geblieben. Jetzt wird die Visualisierung mitgezogen; der Zufallskeim ist
gesetzt, es kommt derselbe Strich heraus.

VIS-Funktionen bekommen den Slide-Index, sonst kann eine Zeichnung ihren
eigenen Layout-Zustand nicht lesen.

Im Foto ist der Eckenradius von 38 auf 8 runter und der Navy-Rand
entfallen. Mit dem gezeichneten Rahmen waeren das sonst drei Rahmen
uebereinander gewesen. Das weicht vom Nachbau der Website-Karte ab und
ist bewusst so.

Der Projektstand kommt mit: Slide 1 traegt jetzt manuelle Anpassungen aus
dem Generator. Der Fliesstext ist geleert, Ueberschrift und Karte sind
verschoben, das Foto steht dadurch allein.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-12 02:34:01 +02:00
1 parent 87834304fa
commit 9cc82e59ee
2 files changed
+144 -11

No files matched your search

+120 -7
View File
@@ -397,13 +397,26 @@
Namensschild sichtbar. Werte aus TeamCards.tsx uebernommen.
Ohne die weichgezeichnete Ellipse aus dem Original: die haengt an
backdrop-filter, und was der Export daraus macht, ist nicht verlaesslich. */
/* Der Halter traegt das Foto und darueber die Zeichenebene. Die Ebene
ragt bewusst ueber das Foto hinaus, oben am weitesten: dort sitzt der
Helm. Ihre Masse sind Prozent und keine Pixel, damit sie mitwaechst,
wenn die Karte im Canvas breiter gezogen wird. */
.karte-halter { position: relative; }
/* Der Selektor muss ".vis svg" schlagen, sonst zieht die allgemeine Regel
die Ebene auf Containerbreite und der Rahmen sitzt zu klein und
verschoben. Deshalb hier svg.karte-skizze und nicht nur die Klasse. */
.vis svg.karte-skizze {
position: absolute; z-index: 6; pointer-events: none;
left: -7.42%; width: 128.39%;
top: -19.35%; height: 125.29%;
}
.karte {
position: relative; aspect-ratio: 4/5; overflow: hidden;
border-radius: 38px; background: #0f1a2e; isolation: isolate;
border-radius: 8px; background: #0f1a2e; isolation: isolate;
}
.karte-grund {
position: absolute; inset: 4.2%; z-index: 1; overflow: hidden;
border-radius: 27px; background: #2b2d2a;
position: absolute; inset: 0; z-index: 1; overflow: hidden;
border-radius: 8px; background: #2b2d2a;
filter: grayscale(.04) saturate(.74) brightness(.73);
}
.karte-grund img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
@@ -1093,7 +1106,8 @@
const VORLAGEN = [
{
key: "titel", type: "feature",
layouts: [{ id: "standard", label: "Standard" }],
layouts: [{ id: "ecke", label: "Helm auf der Ecke" },
{ id: "kopf", label: "Helm auf dem Kopf" }],
eyebrow: "Titel",
head: 'Die Geschichte fängt<br><span class="a">auf der Baustelle an.</span>',
body: "Noah Geerkens, SHK-Betrieb in vierter Generation.",
@@ -1657,6 +1671,98 @@
'" xmlns="http://www.w3.org/2000/svg">' + raus + '</svg>';
}
/* ─── Slide 1: Foto im gezeichneten Rahmen ───────────────────────────────
Das Foto bleibt roh, gezeichnet wird nur drumherum. Der Helm sitzt wie
die Krone beim Zeichenspiel auf der oberen rechten Ecke, angeschraegt und
halb ueber der Kante.
Er ist ganz in Gelb gezogen, Umriss wie Schraffur. Das hat einen Grund:
er liegt zur Haelfte auf dem hellen Grund und zur Haelfte auf dem dunklen
Foto. Eine Tintenlinie waere auf dem Foto verschwunden. Gelb traegt auf
beidem, und ein Bauhelm ist ohnehin gelb. */
/* Der Helm. Drei Anlaeufe stecken drin, und die Zwischenschritte stehen
hier, weil sie lehrreich sind: erst war die Kuppel flach und die Krempe
eine geschlossene Scheibe darunter, zusammen eine Schirmmuetze. Dann kam
Schraffur dazu, und die Waagerechten kreuzten die Grate zu einem Gitter,
also einem Korb. Was traegt, sind viele Stuetzpunkte in der Kuppel, ein
First von vorn nach hinten, zwei Nebenrippen und eine Krempe mit Dicke.
Alles in Gelb, Umriss wie Rippen: der Helm liegt je nach Lage auf hellem
Grund oder auf dem dunklen Foto. Eine Tintenlinie waere dort verschwunden,
und ein Bauhelm ist ohnehin gelb. */
function bauhelm(breite) {
const b = breite / 2, kd = b * 0.76, h = b * 1.0;
const kuppel = glatt([
[-kd, 2], [-kd * 1.03, -h * 0.28], [-kd * 0.93, -h * 0.58],
[-kd * 0.62, -h * 0.86], [-kd * 0.22, -h * 0.99], [kd * 0.22, -h * 0.99],
[kd * 0.62, -h * 0.86], [kd * 0.93, -h * 0.58], [kd * 1.03, -h * 0.28], [kd, 2],
], false);
const first = glatt([[-kd * 0.04, -h * 0.99], [0, -h * 0.62],
[kd * 0.03, -h * 0.22], [kd * 0.04, 1]], false);
let rippen = "";
[-1, 1].forEach(v => {
rippen += glatt([[v * kd * 0.36, -h * 0.92], [v * kd * 0.58, -h * 0.56],
[v * kd * 0.68, -h * 0.17], [v * kd * 0.7, 1]], false);
});
// Krempe: unten und oben ein Zug, dadurch bekommt sie Dicke.
const krempeU = glatt([[-b, 4], [-b * 0.62, 16], [0, 21], [b * 0.62, 16], [b, 4]], false);
const krempeO = glatt([[-b, 4], [-b * 0.62, 7], [0, 10], [b * 0.62, 7], [b, 4]], false);
// Schattierung links: vier Boegen parallel zur Aussenkante.
let schatten = "";
for (let i = 0; i < 4; i++) {
const f = 0.94 - i * 0.1;
schatten += glatt([[-kd * f, -h * 0.16], [-kd * f * 0.94, -h * 0.46],
[-kd * f * 0.7, -h * 0.72]], false);
}
return zug(schatten, { f: GELB, w: 2.1, op: .45 }) +
zug(kuppel, { f: GELB, w: 5 }) +
zug(first, { f: GELB, w: 3, op: .8 }) +
zug(rippen, { f: GELB, w: 2.3, op: .55 }) +
zug(krempeU, { f: GELB, w: 5 }) +
zug(krempeO, { f: GELB, w: 3.4, op: .85 });
}
/* Zwei Lagen, umschaltbar ueber den Layout-Schalter der Slide.
"ecke": der Helm haengt an der abgeschnittenen Rahmenecke. Er kippt dafuer
nach rechts, damit die Oeffnung ueber der Ecke liegt und nicht von ihr
weg zeigt. Nach links gekippt sah er aus, als falle er herunter.
"kopf": er sitzt auf Noahs Stirn, groesser, damit er getragen wirkt und
nicht wie eine Kappe aufliegt. */
function visKarte(lage) {
keim(20260811);
const W = 796, H = 971;
// Das Foto liegt bei x 46..666 und y 150..925, der Rahmen 16 px aussen
// herum. Rechts ist die Ebene breiter als noetig, weil der Helm in der
// Lage "ecke" ueber den Rahmen hinausragt.
let band = "";
for (let y = 178; y < 928; y += 13) band += strich(683, y, 699, y + 16, { j: .7, b: .7 });
for (let x = 72; x < 666; x += 13) band += strich(x, 942, x + 16, 958, { j: .7, b: .7 });
/* Drei Sachen greifen ineinander statt nebeneinanderher zu laufen: der
versetzte Zug ist die Aussenkante des Schattens, die Schraffur fuellt
das Band dazwischen, und beides folgt der Markenform.
Zur Schattenfrage: rules.md Paragraf 5 verbietet Schatten, meint damit
aber weichgezeichnete. Die dort notierte Ausnahme sagt, eine Linie ist
kein Schatten. Eine Schraffur besteht aus Linien. */
const rahmen =
zug(chamfer(48, 152, 652, 807, 30, { ue: 5 }), { w: 3, op: .38 }) +
zug(band, { w: 1.9, op: .34 }) +
zug(chamfer(30, 134, 652, 807, 30, { ue: 9 }), { w: 6 });
const helm = lage === "kopf"
? '<g transform="translate(398 350) rotate(-4)">' + bauhelm(222) + '</g>'
: '<g transform="translate(690 168) rotate(28)">' + bauhelm(196) + '</g>';
return '<svg viewBox="0 0 ' + W + ' ' + H + '" width="' + W + '" height="' + H +
'" xmlns="http://www.w3.org/2000/svg" class="karte-skizze">' + rahmen + helm + '</svg>';
}
/* ─── Slide 3: wechseln kannst du vergessen ──────────────────────────────
Der Fliesstext hat zwei Haelften, und beide brauchen ein Bild: "Jahre an
Daten und Wissen haengen drin" wird zu Wurzeln im Boden, "am Ende
@@ -1904,14 +2010,15 @@
}
const VIS = {
karte: () =>
karte: j =>
'<div class="karte-halter">' + visKarte(layoutState[j]) +
'<div class="karte">' +
'<div class="karte-grund"><img alt="" src="' + assets["./assets/team/noah-bg.webp"] + '">' +
'<span class="karte-wash"></span></div>' +
'<img class="karte-person" alt="Noah Geerkens" src="' +
assets["./assets/team/noah-person.webp"] + '">' +
'<div class="karte-name"><span>Noah</span><small>CEO</small></div>' +
'</div>',
'</div></div>',
schiene: () => visProzesse(),
@@ -2534,7 +2641,7 @@
v.style.cssText =
"--vis-w:" + (sl.visW || 900) + "px;--vis-left:" + (sl.visLeft || 92) +
"px;--vis-bottom:" + (sl.visBottom || 96) + "px";
v.innerHTML = VIS[sl.vis]();
v.innerHTML = VIS[sl.vis](j);
page.appendChild(v);
}
@@ -2609,6 +2716,12 @@
// Das Layout hängt an der Seite, damit eine Titel-Seite auch in einer
// Nachbar-Slide korrekt aussieht.
page.dataset.layout = layoutState[j];
/* Der Layout-Schalter ruft rebuildPage. Das erneuerte bisher nur den
Textblock, nicht die Visualisierung -- ein Umschalten der Helmlage waere
dadurch wirkungslos geblieben. Der Zufallskeim ist gesetzt, das erneute
Zeichnen liefert also denselben Strich. */
const vv = page.querySelector(".vis");
if (vv && SLIDES[j].vis && VIS[SLIDES[j].vis]) vv.innerHTML = VIS[SLIDES[j].vis](j);
tagEditable(page);
applyEdits(page, j);
}
+24 -4
View File
@@ -29,7 +29,9 @@
"deck": [
{
"ref": "titel",
"werte": {}
"werte": {
"body": "<br>"
}
},
{
"ref": "prozesse",
@@ -53,8 +55,26 @@
}
],
"edits": [
{},
{},
{
"body": {
"dx": 102,
"dy": -95
},
"headline": {
"dx": 102,
"dy": -96
},
"vis": {
"dx": 3,
"dy": -146
}
},
{
"vis": {
"dx": 0,
"dy": 0
}
},
{},
{},
{},
@@ -62,7 +82,7 @@
],
"frameStyle": "rund",
"layoutState": [
"standard",
"ecke",
"standard",
"standard",
"standard",