Repository navigation
Text, Größe und freie Positionierung dokumentieren und ermöglichen - #62
Conversation
Eine fremde Session kam mit der llms.txt nicht weiter: mehrere Texte,
andere Farben, Groesse, links- und rechtsbuendig — alles unklar. Zu
Recht. Teils war es undokumentiert, teils gab es die Faehigkeit gar
nicht.
Undokumentiert war, dass addText() ueberhaupt Optionen hat. Die Tabelle
sagte nur "Schlagzeile hinzufuegen"; Farbe, Schriftwahl, Ausrichtung,
Zeilenabstand und Schatten standen nirgends. Ebensowenig, dass addText()
beliebig oft aufgerufen werden kann.
Gefehlt hat:
- Mehrere Texte in render() ueber `texts`, jeder mit eigener Farbe,
Groesse und Position. Ohne das landet jeder weitere Text zentriert auf
dem vorigen.
- resize(faktor). Die Oberflaeche hat einen Groessenregler auf dem
ausgewaehlten Objekt, die Fassade legte ihn nur nicht frei. Ein
Schriftgroessenfeld gibt es nicht — Text wird auf 80 % der Bildbreite
skaliert, und das war die einzige Groesse, die ein Aufrufer bekam.
- Freie Koordinaten in place({x, y}) neben den neun Feldern. Die
Schutzzone gilt weiter; Werte ausserhalb 0 bis 1 werden abgelehnt statt
stillschweigend begrenzt, sonst waere die Zusage in der llms.txt
unwahr.
Der neue Abschnitt "Text im Detail" erklaert ausserdem die Verwechslung,
die am meisten Zeit kostet: `align` richtet die Zeilen INNERHALB des
Blocks aus, `place()` bewegt den Block auf dem Bild. Linksbuendig am
linken Rand braucht beides. Dazu eine Liste dessen, was NICHT geht —
keine freie Schriftgroesse in Punkt, keine freien Farben, kein
Textrahmen, keine Drehung — mit der Anweisung, das zu sagen statt etwas
Aehnliches zu liefern.
e2e/llms-examples.spec.js fuehrt jeden Codeblock der llms.txt gegen die
echte Seite aus. Ein Beispiel, das nicht laeuft, ist schlechter als
keines: Das Modell folgt ihm, bekommt einen Fehler, den es nicht deuten
kann, und improvisiert — genau der Fehlermodus, gegen den die
Schnittstelle gebaut ist. Der Test hat sofort ein Fragment ohne Kontext
gefunden, das jetzt vollstaendig ist.
VERSION auf 4.
Claude-Session: https://claude.ai/code/session_01Qtib9MPRZATQU3j9w7ymDk
Die llms.txt fuehrte "Keine Drehung" unter dem auf, was nicht geht. Das war ungeprueft. relativeScalingControlsOnly() setzt in canvas-utils.js:61 ausdruecklich mtr: true — der Drehgriff ist auf Text, Bildern, QR-Codes und Formen aktiv, und beim Ziehen rastet er bei 0, 90, 180 und 270 Grad mit zwei Grad Toleranz ein. Eine falsche Angabe unter "geht nicht" ist besonders schaedlich: Sie bringt ein Modell dazu, eine Anforderung abzulehnen, die das Werkzeug erfuellen kann. Neu: rotate(grad), dazu textRotate und rotate in den Element-Eintraegen von render(). Der Winkel ist absolut, nicht relativ; negative Werte werden normalisiert, -90 wird zu 270. Programmatisch wird exakt gesetzt, ohne Einrasten — das steht so in der llms.txt, damit sich niemand auf Verhalten verlaesst, das nur beim Ziehen mit der Maus greift. Dazu die Einordnung, dass gedrehte Headlines im Erscheinungsbild nicht vorgesehen sind, beim Stoerer und beim Wahlkreuz eine leichte Schraege dagegen ueblich ist. Ohne den Satz wuerde die neue Faehigkeit vermutlich ueberstrapaziert. Die verbleibende "geht nicht"-Liste: keine Schriftgroesse in Punkt, keine freien Farben, kein Textrahmen und keine Hintergrundflaeche hinter dem Text. VERSION auf 5. Claude-Session: https://claude.ai/code/session_01Qtib9MPRZATQU3j9w7ymDk
Nachtrag: Drehung geht dochDie
Eine falsche Angabe unter „geht nicht" ist besonders schädlich: Sie bringt ein Modell dazu, eine Anforderung abzulehnen, die das Werkzeug erfüllen kann. Ein fehlendes Feature lässt sich nachtragen, eine falsche Absage nicht bemerken. Neu ist Programmatisch wird der Winkel exakt gesetzt, ohne Einrasten — das steht so in der Dazu die Einordnung, dass gedrehte Headlines im Erscheinungsbild nicht vorgesehen sind, beim Störer und beim Wahlkreuz eine leichte Schräge dagegen üblich ist — so zeigt es auch der CD-Quickguide. Ohne den Satz würde die neue Fähigkeit vermutlich überstrapaziert. Die beiden anderen Punkte der Liste sind bestätigt und bleiben: Schriftgröße entsteht ausschließlich über Skalierung, Farben nur aus der Auswahl. Verbleibende „geht nicht"-Liste: keine Schriftgröße in Punkt, keine freien Farben, kein Textrahmen und keine Hintergrundfläche hinter dem Text. VERSION auf 5. 132 Jest grün, 86 e2e grün. |
Systematische Bestandsaufnahme aller Bedienelemente statt aus dem
Gedaechtnis. Ergebnis: Die Fassade konnte hinzufuegen, aber nichts mit
dem Hinzugefuegten anfangen. In der Oberflaeche klickt man ein Objekt an
und bedient dann die Regler — ueber die Schnittstelle ging das gar nicht.
Neu:
- objects() listet alles auf dem Canvas mit Index, Typ, Rolle, Inhalt,
Position, Groesse, Winkel und ob die Schutzzone eingehalten ist.
- select(index) spricht ein Element an.
- update({...}) aendert Text, Farbe, Ausrichtung, Zeilenabstand, Schatten
und Schrift eines gesetzten Elements — samt initDimensions(), sonst
behaelt Fabric die alten Textmasse und der neue Text laeuft ueber.
- remove(index) loescht; Logo und Hintergrund sind geschuetzt, genau wie
der Loeschknopf sie schuetzt.
- bringToFront(index) ordnet um und laesst das Logo oben.
- qrPayload(spec) baut die vier Inhaltstypen des QR-Assistenten. Bisher
verlangten renderQRCode() und addQRCode() eine fertige Zeichenkette —
ein Modell haette mailto:-Parameter und vCard-Records selbst
zusammensetzen muessen, obwohl die Formatierungsregeln im Werkzeug
stecken (QRFormatHelpers).
e2e/api-coverage.spec.js haelt die Fassade an ihrem Versprechen: Es
laeuft die Bedienelemente des Assistenten ab und prueft fuer jedes eine
Entsprechung, vergleicht jeden <option>-Wert gegen options() und prueft,
dass jeder QR-Inhaltstyp baubar ist. Ohne so einen Test verfaellt das
Versprechen lautlos — ein neuer Knopf waere fuer Aufrufer unerreichbar,
und es fiele erst auf, wenn jemand danach fragt.
Der Beispieltest hat wieder vier Fragmente ohne Kontext gefunden; alle 13
Codebloecke der llms.txt laufen jetzt gegen die echte Seite.
Die fest verdrahtete Versionsnummer in api.spec.js ist raus — die
Uebereinstimmung von Code und Dokument prueft llms-txt.spec.js, eine
zweite Stelle waere nur eine zweite zum Vergessen.
Nebenbefund, nicht angefasst: #scale-direction, #stroke-width und
#opacity haben gebundene Handler, aber die Elemente existieren im HTML
nicht. Der opacity-Wert wird beim Bildhinzufuegen gelesen und ist
undefined.
VERSION auf 6.
Claude-Session: https://claude.ai/code/session_01Qtib9MPRZATQU3j9w7ymDk
Nachtrag: vollständige AbdeckungSystematische Bestandsaufnahme aller Bedienelemente, statt aus dem Gedächtnis zu arbeiten. Ergebnis: Die Fassade konnte hinzufügen, aber nichts mit dem Hinzugefügten anfangen. In der Oberfläche klickt man ein Objekt an und bedient dann die Regler — über die Schnittstelle ging das gar nicht.
Beim QR-Generator war es besonders schief: Die Oberfläche bietet Text, URL, E-Mail und vCard als Formulare an, die Fassade verlangte eine fertige Zeichenkette. Ein Modell hätte Der Test, der das Versprechen hält
Ohne so einen Test verfällt das Versprechen „alles, was die Seite kann" lautlos. Ein neuer Knopf in der Oberfläche wäre für Aufrufer unerreichbar, und es fiele erst auf, wenn jemand danach fragt — genau so ist diese Lücke ja aufgefallen. Der Beispieltest hat wieder zugeschlagen: vier neue Codeblöcke waren Fragmente ohne Kontext. Alle 13 laufen jetzt gegen die echte Seite. AufgeräumtDie fest verdrahtete Versionsnummer in Nebenbefund, nicht angefasst
VERSION auf 6. 132 Jest grün, 104 e2e grün. |
Eine fremde Session kam mit der
llms.txtnicht weiter: mehrere Texte, andere Farben, Größe, links- und rechtsbündig — alles unklar. Zu Recht. Teils war es undokumentiert, teils gab es die Fähigkeit gar nicht.Was nur undokumentiert war
Dass
addText()überhaupt Optionen hat. Die Tabelle sagte| addText(text, opts) | Schlagzeile hinzufügen |— Farbe, Schriftwahl, Ausrichtung, Zeilenabstand und Schatten standen nirgends. Ebensowenig, dassaddText()beliebig oft aufgerufen werden kann.Was tatsächlich gefehlt hat
Mehrere Texte in
render()übertexts, jeder mit eigener Farbe, Größe und Position. Ohne das landet jeder weitere Text zentriert auf dem vorigen.resize(faktor). Die Oberfläche hat einen Größenregler auf dem ausgewählten Objekt (#scale, 0,1 bis 2) — die Fassade legte ihn nur nicht frei. Ein Schriftgrößenfeld gibt es nicht: Text wird auf 80 % der Bildbreite skaliert, und das war bisher die einzige Größe, die ein Aufrufer bekommen konnte.Freie Koordinaten in
place({ x, y })neben den neun Feldern. Die Schutzzone gilt weiter, und Werte außerhalb 0 bis 1 werden abgelehnt statt stillschweigend begrenzt — sonst wäre die Zusage in derllms.txtunwahr.Der Abschnitt „Text im Detail"
Erklärt die Verwechslung, die am meisten Zeit kostet:
alignrichtet die Zeilen innerhalb des Blocks aus. Bei einzeiligem Text wirkungslos.place()bewegt den Block auf dem Bild.Linksbündig am linken Bildrand braucht beides. Das war vermutlich genau die Frage, an der deine Session hing.
Dazu eine ausdrückliche Liste dessen, was nicht geht — keine freie Schriftgröße in Punkt, keine freien Farben, kein Textrahmen, keine Drehung — mit der Anweisung, das zu sagen statt etwas Ähnliches zu liefern.
Ein Test, der die Beispiele ausführt
e2e/llms-examples.spec.jsführt jeden Codeblock derllms.txtgegen die echte Seite aus.Begründung: Ein Beispiel, das nicht läuft, ist schlechter als keines. Das Modell folgt ihm, bekommt einen Fehler, den es nicht deuten kann, und improvisiert — genau der Fehlermodus, gegen den diese Schnittstelle gebaut ist. Beispiele sind der Teil des Dokuments, der am ehesten wörtlich übernommen wird.
Der Test hat sofort etwas gefunden: Das Beispiel zur freien Positionierung war ein Fragment ohne Kontext, kopierbar aber nicht lauffähig. Jetzt vollständig.
Tests
132 Jest grün, 83 e2e grün — davon 27 für die Fassade und 7 für die Beispiele aus der
llms.txt.VERSION auf 4.
https://claude.ai/code/session_01Qtib9MPRZATQU3j9w7ymDk