feat: Cursor-Zeile hebt sich aus der Ebene, plus Puls beim Zeilenwechsel
Die Hervorhebung der Cursor-Zeile (D25) war zu leise. Sie benutzte denselben Kanal, den schon jeder Knoten belegt — jeder Status hat einen Rahmen (SPEC §4); ein weiterer Ring darunter ist ein Unterschied im Grad, nicht in der Art. Dazu kommt jetzt Tiefe: Schlagschatten + scale(1.04). Der einzige Kanal, den im Diagramm noch nichts belegt, also ohne Konflikt mit einer Farbcodierung. Um die Mitte skaliert, damit die Knotenmitte erhalten bleibt (alignStems, Stationspunkte messen genau die — nachgemessen dx=dy=0). Beim Zeilenwechsel meldet sie sich zusätzlich mit einem einmaligen Puls (Hüpfer + auslaufender Ring auf ::after); kein Blinken, prefers-reduced-motion schaltet ihn ab. Behoben dabei: Die Pfad-Inversion (D18) blasste den Ring auf 0,32 aus — die Ausnahme, die .fresh (D28) und .focusmark (D32) längst haben, fehlte für .current als einziger, obwohl der Fall der häufigste ist (Umschalter default an, im Beispiel 7 von 18 Knoten betroffen). diagramToSvg() muss die Erhebung abschalten (Klasse `exporting`): Der Export zieht die Live-Geometrie per getBoundingClientRect() nach, anders als beim box-shadow schlägt eine Vergrößerung dort durch. Nachgemessen: 155,6 statt 161,9 px. Im Druck fällt beides ebenso weg. SPEC §9 und D25 (Nachtrag) nachgezogen; llms.md unberührt (Notation, keine Editor-UI, D43). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
618149a36d
commit
099ee87bc1
+21
-4
@@ -394,6 +394,13 @@ out.addEventListener('focusout', () => setTimeout(drawDepLinks, 0));
|
||||
(und = durchgezogen Tinte, oder = gestrichelt Grau) neu gezogen und treffen
|
||||
so garantiert die Knoten — unabhängig vom Darstellungsmodus. */
|
||||
function diagramToSvg(){
|
||||
/* Der Export misst die **Live-Geometrie**. Den Ring der Cursor-Zeile liest er
|
||||
nie aus (`box-shadow` steht nicht in der Liste), ihre Erhebung
|
||||
(D25-Nachtrag) schlüge aber über `getBoundingClientRect()` durch und
|
||||
exportierte genau einen Knoten 4 % zu groß. Neutralisiert wird sie per
|
||||
Klasse statt durch Abnehmen von `.current`/`.pulse` — so reißt der Export
|
||||
keine laufende Puls-Animation ab und startet sie hinterher nicht neu. */
|
||||
out.classList.add('exporting');
|
||||
const treeRect = out.getBoundingClientRect();
|
||||
const PAD = 24;
|
||||
const W = Math.ceil(treeRect.width) + PAD*2;
|
||||
@@ -570,6 +577,7 @@ function diagramToSvg(){
|
||||
});
|
||||
|
||||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}" font-family="'IBM Plex Sans',system-ui,sans-serif">${parts.join('')}</svg>`;
|
||||
out.classList.remove('exporting');
|
||||
return {svg, W, H};
|
||||
}
|
||||
function svgToPng(svg, W, H, scale){
|
||||
@@ -925,9 +933,9 @@ out.addEventListener('touchcancel', disarmPress);
|
||||
out.addEventListener('contextmenu', e => { if(pressTimer || armedEl) e.preventDefault(); });
|
||||
|
||||
/* Text -> Diagramm: Knoten der Cursor-Zeile hervorheben (`caretLine` steht oben). */
|
||||
function highlightCurrentNode(scroll){
|
||||
function highlightCurrentNode(moved){
|
||||
markCurrentLineNo(); /* die eine Stelle, an der die Cursor-Zeile neu gesetzt wird */
|
||||
if(currentNodeEl) currentNodeEl.classList.remove('current');
|
||||
if(currentNodeEl) currentNodeEl.classList.remove('current', 'pulse');
|
||||
currentNodeEl = caretLine == null
|
||||
? null
|
||||
: out.querySelector('.node[data-line="' + caretLine + '"]');
|
||||
@@ -936,8 +944,17 @@ function highlightCurrentNode(scroll){
|
||||
/* Die Cursor-Zeile ist die zweite Lesart von „ausgewählt" — ihre
|
||||
Abhängigkeits-Kanten hervorheben (D41). */
|
||||
drawDepLinks();
|
||||
/* Nur beim Zeilenwechsel scrollen, sonst ruckelte das Diagramm beim Tippen. */
|
||||
if(scroll) currentNodeEl.scrollIntoView({block:'nearest', inline:'nearest', behavior:'smooth'});
|
||||
/* Beides nur beim **Zeilenwechsel**: Scrollen ruckelte sonst bei jedem
|
||||
Tastendruck, und der Puls (D25-Nachtrag) flackerte beim Tippen. */
|
||||
if(!moved) return;
|
||||
/* Neustart der Animation erzwingen: Steht der Cursor wieder auf demselben
|
||||
Knoten (Zeile mit Knoten -> Zeile ohne -> zurück), wurde `pulse` oben in
|
||||
DERSELBEN Aufgabe entfernt — der Browser sieht dann keinen Klassenwechsel
|
||||
und startet nichts. Das Lesen von `offsetWidth` erzwingt den Zwischenstand. */
|
||||
currentNodeEl.classList.remove('pulse');
|
||||
void currentNodeEl.offsetWidth;
|
||||
currentNodeEl.classList.add('pulse');
|
||||
currentNodeEl.scrollIntoView({block:'nearest', inline:'nearest', behavior:'smooth'});
|
||||
}
|
||||
function caretLineOf(){
|
||||
return src.value.slice(0, src.selectionStart).split('\n').length;
|
||||
|
||||
Reference in New Issue
Block a user