domotion-svg 0.13.0 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/animator.js +28 -3
- package/package.json +1 -1
|
@@ -514,9 +514,15 @@ function renderTypingOverlay(overlay, frameIdx, frameStart, frameEnd, totalDurat
|
|
|
514
514
|
cumChars += line.length;
|
|
515
515
|
parts.push(` <defs><clipPath id="${clipId}"><rect class="${id}-rev${li}" x="${overlay.x}" y="${lineY - fontSize}" width="0" height="${textHeight}" /></clipPath></defs>`);
|
|
516
516
|
parts.push(` <text class="${id}-text" x="${overlay.x}" y="${lineY}" fill="${color}" font-size="${fontSize}" font-family="'SF Mono', Menlo, Monaco, monospace" clip-path="url(#${clipId})">${escapeHtml(line)}</text>`);
|
|
517
|
+
// DM-1204: the reveal clip MUST sweep linearly so its right edge tracks the
|
|
518
|
+
// caret (whose position track is `linear`). Without an explicit timing
|
|
519
|
+
// function the width animation defaults to CSS `ease`, which races ~80%
|
|
520
|
+
// through the sweep at the time-midpoint while the linear caret is only at
|
|
521
|
+
// 50% — that desync read as the caret lagging ~10–20 chars behind the
|
|
522
|
+
// revealed text mid-type, even though the endpoints (parked state) matched.
|
|
517
523
|
cssRules.push(`
|
|
518
524
|
@keyframes ${id}-rev${li} { 0%, ${lineStartPct} { width: 0; } ${lineEndPct} { width: ${lineWidth}px; } ${holdEndPct} { width: ${lineWidth}px; } ${disappearPct}, 100% { width: 0; } }
|
|
519
|
-
.${id}-rev${li} { animation: ${id}-rev${li} ${totalSec.toFixed(2)}s infinite; }`);
|
|
525
|
+
.${id}-rev${li} { animation: ${id}-rev${li} ${totalSec.toFixed(2)}s linear infinite; }`);
|
|
520
526
|
});
|
|
521
527
|
// Whole-overlay visibility — shared by every line's <text>.
|
|
522
528
|
const typeStartPct = pct(typeStartMs, totalDuration);
|
|
@@ -538,10 +544,26 @@ function renderTypingOverlay(overlay, frameIdx, frameStart, frameEnd, totalDurat
|
|
|
538
544
|
const endY = last.li * lineHeight;
|
|
539
545
|
// Position track: hold at line 0 start until typing begins, then sweep each
|
|
540
546
|
// line, then hold at the text end through the blink + disappear.
|
|
547
|
+
//
|
|
548
|
+
// DM-1204 (multi-line): a line ends and the next begins at the same instant
|
|
549
|
+
// (type timing is contiguous — line N+1 starts the ms line N finishes). The
|
|
550
|
+
// end-of-line stop (x = line width, row N) and the next line's left-margin
|
|
551
|
+
// stop (x = 0, row N+1) would therefore round to the SAME keyframe percent;
|
|
552
|
+
// CSS keeps the later declaration, dropping the end-of-line x so the caret
|
|
553
|
+
// stays pinned at x=0 and merely slides down each row. We keep percentages
|
|
554
|
+
// strictly increasing (nudging the carriage-return stop a hair past the
|
|
555
|
+
// line-end stop) so both survive — the jump back to the margin then happens
|
|
556
|
+
// over ~0.01% of the timeline, i.e. visually instant.
|
|
541
557
|
const posStops = [`0%, ${typeStartPct} { transform: translate(0px, 0px); }`];
|
|
558
|
+
let lastPctNum = pctNum(typeStartMs, totalDuration);
|
|
559
|
+
const pushPosStop = (pn, x, y) => {
|
|
560
|
+
const p = Math.max(pn, lastPctNum + 0.01);
|
|
561
|
+
posStops.push(`${p.toFixed(2)}% { transform: translate(${x}px, ${y}px); }`);
|
|
562
|
+
lastPctNum = p;
|
|
563
|
+
};
|
|
542
564
|
for (const lt of lineTimings) {
|
|
543
|
-
|
|
544
|
-
|
|
565
|
+
pushPosStop(pctNum(lt.startMs, totalDuration), 0, lt.li * lineHeight);
|
|
566
|
+
pushPosStop(pctNum(lt.endMs, totalDuration), lt.len * charWidth, lt.li * lineHeight);
|
|
545
567
|
}
|
|
546
568
|
posStops.push(`${holdEndPct}, 100% { transform: translate(${endX}px, ${endY}px); }`);
|
|
547
569
|
// Blink: invisible until typing starts, solid through typing, then toggle
|
|
@@ -612,6 +634,9 @@ function renderBlinkOverlay(overlay, frameIdx, frameStart, frameEnd, totalDurati
|
|
|
612
634
|
function pct(ms, total) {
|
|
613
635
|
return `${((ms / total) * 100).toFixed(2)}%`;
|
|
614
636
|
}
|
|
637
|
+
function pctNum(ms, total) {
|
|
638
|
+
return (ms / total) * 100;
|
|
639
|
+
}
|
|
615
640
|
/**
|
|
616
641
|
* DM-599: build a step-end keyframes block that toggles `display` between
|
|
617
642
|
* `none` and `inline` around a visible window. Used in parallel with the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "domotion-svg",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "DOM-to-animated-SVG renderer. Captures HTML/CSS via Playwright Chromium and converts it to self-contained SVG with CSS animations — pixel-faithful demos that scale crisply and load lazily.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Brian Westphal",
|