Vom Kopf zum Blatt

Neun bis dreißig Köpfe auf einer Fläche, jeder an seinem Platz, jeder in derselben Größe – und einer davon jederzeit groß in der Mitte. Das ist weniger Verwaltung, als es klingt: das Blatt ist ein Raster, ein Maßstab, eine Reihenfolge und eine Zahl.

Das Raster

Die Spaltenzahl springt an vier festen Schwellen – 560, 900, 1300, 1800 Pixel. Keine Formel, sondern eine Tabelle: eine Formel träfe irgendwann eine Breite, bei der sie zwei Spalten oder elf vorschlägt, und beides ist kein Blatt. Die Reihen ergeben sich danach aus einer einzigen Bedingung – die Zellen sollen ungefähr quadratisch bleiben.

Im Zweifel lieber eine Spalte mehr als große Köpfe mit Luft drumherum. Ein Kopf, der im Breitbild allein in einer flachen Kachel steht, sieht verloren aus; sechs kleine Köpfe in einer Reihe sehen nach Blatt aus.

Der Seed einer Zelle ist blattSeed + r · spalten + c. Benachbarte Zellen haben also benachbarte Seeds – genau der Fall, für den der Generator im Kapitel Zufall acht Züge wegwirft. Ohne das Aufwärmen stünden hier Reihen von Verwandten.

Raumbedarf gegen platzIn

Der Stil sagt, was ein Kopf braucht (raum(dna)), die Zelle sagt, was sie hergibt (platzIn). Beide rechnen in Kopfeinheiten, damit sie überhaupt vergleichbar sind.

Nach unten wird nicht gemessen: dort steht der Name, und keine Frisur reicht so weit. Nach oben und zur Seite schon – der Afro ist rund und deutlich breiter als der Schädel, der Knoten eines Dutts sitzt obendrauf, und eine Hutkrempe ragt über jeden Kopf hinaus.

Verlangt eine Frisur mehr, als ihre Zelle hergibt, wird nicht dieser eine Kopf kleiner, sondern das ganze Blatt. Neun Köpfe in neun Maßstäben sehen aus wie ein Fehler; ein etwas kleineres Blatt sieht nach Absicht aus.

Meistens kommt 1 heraus. Die Zelle ist so bemessen, dass die üblichen Frisuren hineinpassen; der Faktor greift erst bei den größten Afro-Kugeln – und dann für alle.

Die Zeichenreihenfolge ist Teil der Korrektheit

Ein Kopf wird nicht zusammengesetzt, sondern gestapelt. Es gibt keine Verdeckungsrechnung, keinen Tiefenpuffer und keine Masken zwischen den Zügen – jeder Zug darf übermalen, was unter ihm liegt. Die Ordnung ist deshalb kein Ablauf, sondern eine Aussage darüber, was wovor liegt. (Die eine Ausnahme bleibt in einem Zug: der Wangenbogen beschneidet das Auge, zu dem er gehört, siehe Merkmale.)

Sie stand lange nirgends. Sie war die Reihenfolge von siebzehn Aufrufen in zeichneGesicht, und wer einen davon zwei Zeilen höher schob, verschob eine Verdeckung – ohne dass ihm etwas sagte, dass er gerade einen Vertrag angefasst hatte. Heute nennt jeder Zug seine Ebene, und die Ebenen stehen als Liste:

Die Züge werden gesammelt, stabil nach Ebene sortiert und dann gezeichnet. Stabil heißt: innerhalb einer Ebene gilt weiter, wer zuerst gesammelt wurde – sonst läge die Kontur unter ihrer eigenen Fläche und wäre weg.

EbeneWarum dort
halsGanz hinten. Der Kopf sitzt darauf und deckt den Ansatz.
hinter-dem-kopfZöpfe, die Afro-Kugel, die hintere Hutkrempe. Sie werden vor der Kopffläche gezeichnet und von ihr zur Hälfte verdeckt – das ist der ganze Trick.
ohrenDas abgewandte Ohr sitzt seitlich am Schädel, also unter seiner Fläche.
kopfDer Deckel über allem Hinteren – und die Kontur darüber, sonst frisst der Rand der Fläche die Linie an.
zugewandtes-ohrDas zugewandte Ohr liegt vor der Wange: dreht der Kopf, wandert sein Anker hinter die Silhouette, und die Kopffläche biss ihm die Wurzel ab. Welches Ohr hier landet, sagt seine Normale – nicht die Seite im Bild.
hautBacken, Augenringe, Schraffur, Stirnfalten: Farbe und blasse Nebenlinien auf der Haut, unter allen Zügen.
bartUnter der Nase, auch in der Ordnung. Was die Nase überlappt, verdeckt sie.
fernes-augeDas Auge auf der abgewandten Seite. Welches das ist, sagt seine Tiefe – nicht das Vorzeichen der Drehung.
naseSie hat Volumen und stellt sich frei – also verdeckt sie das Auge hinter sich.
nahes-augeVor der Nase gezeichnet radierte sie auch dieses weg.
mundÜber dem Bart, unter dem Rest.
frisurHaar und Kopfbedeckung: die Schale liegt auf dem Schädel, nicht darunter.
aufgesetztOhrring, Pflaster – am Kopf, aber nicht Teil von ihm.
davorVor dem Gesicht und deshalb über allem – auch über der Mütze, die auf dem Schädel sitzt und nicht davor.
Die Nase, die das Auge wegradiert

Symptom: Bei gedrehtem Kopf fehlt dem vorderen Auge ein Stück, als wäre es angeschnitten. Ursache: Die Nase ist keine Linie, sondern eine Form mit Fläche. Vor beiden Augen gezeichnet deckt sie nicht nur das ferne, sondern auch das nahe zu. Lösung: Drei Ebenen verschränken sich: fernes Auge, Nase, nahes Auge. Welches der beiden das ferne ist, entscheidet die Tiefe der Augen-Felder, nicht das Vorzeichen der Drehung – und eine Probe hält es fest: über vierhundert Seeds muss das zuletzt gezeichnete Auge das mit dem größeren z sein.

Die Großansicht ist eine Zahl

Kein zweites Element, kein Modal, kein zweites Canvas. fokus.t läuft zwischen 0 (der Kopf sitzt in seiner Zelle) und 1 (er steht in der Mitte), und der Ort wird daraus gerechnet.

Weil ohnehin jedes Bild neu gezeichnet wird – die Köpfe folgen dem Zeiger –, ist das der einfachere Weg und nebenbei der weichere: t nähert sich seinem Ziel jedes Bild um einen festen Anteil des Restwegs. Das ist in beide Richtungen „schnell los, weich an" und lässt sich mitten in der Bewegung umkehren, ohne dass etwas springt.

Der Schleier über dem Raster ist papierfarben, nicht grau. Das Blatt tritt zurück, statt dass ein Vorhang davorfällt – und am Ende deckt er ganz, damit hinter dem großen Kopf kein Raster durchschimmert.

Die Namen sind kein Teil des Bildes

Sie liegen als <span> über dem Canvas, an genau der Stelle, an der das Canvas sie sonst gemalt hätte – den Ort rechnet die App ohnehin aus, für den Zoom.

Gemalter Text

Symptom: Ein Name lässt sich nicht markieren, nicht kopieren, nicht suchen, und eine Vorlesesoftware findet auf dem Blatt nichts als ein leeres Rechteck. Ursache: Gemalter Text ist ein Bild. Lösung: Text bleibt Text. Das Canvas trägt ein aria-label, die Namen stehen darüber im DOM.

Der Gewinn ist nicht nur das Kopieren. Der Name in der Großansicht bekommt damit eine eigene Bewegung: er kommt einen Hauch von unten nach, wenn der Kopf schon steht, und geht schneller, als er kam. Ein Name, der so lange bräuchte wie der Kopf, würde mit ihm um die Aufmerksamkeit streiten.

Zwei Namen, nicht einer: wunsch ist, was dort stehen soll, gezeigt, was gerade dort steht. Die App fragt jedes Bild neu an – sechzig Mal in der Sekunde denselben Wunsch. Ohne diese Trennung liefe in jedem Bild ein neues Ausblenden an, und das Einblenden käme nie dran; der Name bliebe für immer halb da.

Prüfen ohne Bildschirm

Der Entwicklungsbau legt vier Griffe an window.presse: wuerfle(seed) stellt ein bestimmtes Blatt, schaue(x, y, s) rechnet die Federn ohne Bildschleife weiter, zellen() sagt, wo welcher Kopf sitzt und was er trägt, und abzug(name) schickt das Blatt in voller Auflösung per POST /__abzug an den Server, der es unter abzuege/ ablegt.

Die unsichtbare Seite steht still

Symptom: Eine automatisierte Prüfung sieht Köpfe, die stur geradeaus schauen – ob sie dem Zeiger folgen, lässt sich nur behaupten. Ursache: Ohne sichtbare Seite hält der Browser requestAnimationFrame an. Es gibt niemanden, der das nächste Bild malt. Lösung: schaue() rechnet die Federn in Schritten von 1/60 Sekunde selbst weiter und zeichnet einmal. Für den Abzug werden die Namen einmalig ins Canvas gemalt – das nächste Bild wischt sie wieder weg.

Der ganze Zweig existiert nur unter import.meta.env.DEV; im Bündel ist er entfernt. Ein Griff, der im Auslieferungsstand mitläuft, ist keine Prüfhilfe mehr, sondern eine Schnittstelle.