sketchmark 1.4.0 → 1.4.1

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/index.js CHANGED
@@ -11399,8 +11399,11 @@ class AnimationController {
11399
11399
  * 4. After guide finishes → fade in rough.js element, remove guide
11400
11400
  */
11401
11401
  _animateAnnotation(roughEl, guideD, silent) {
11402
- if (silent)
11402
+ if (silent) {
11403
+ roughEl.style.opacity = "1";
11404
+ roughEl.style.transition = "none";
11403
11405
  return;
11406
+ }
11404
11407
  // Hide rough.js element — will be revealed after guide draws
11405
11408
  roughEl.style.opacity = "0";
11406
11409
  roughEl.style.transition = "none";
@@ -11690,10 +11693,74 @@ const ANIMATION_CSS = `
11690
11693
  .skm-caption { pointer-events: none; user-select: none; }
11691
11694
  `;
11692
11695
 
11696
+ const exportAnimationState = new WeakMap();
11697
+ function bindExportAnimationState(svg, state) {
11698
+ exportAnimationState.set(svg, state);
11699
+ }
11700
+ function getExportAnimationState(svg) {
11701
+ return exportAnimationState.get(svg);
11702
+ }
11703
+
11693
11704
  // ============================================================
11694
11705
  // sketchmark — Export System
11695
11706
  // SVG, PNG, Canvas, GIF (stub), MP4 (stub)
11696
11707
  // ============================================================
11708
+ const EXPORT_SVG_STYLE_ID = "sketchmark-export-state";
11709
+ const EXPORT_SVG_STATE_CSS = `
11710
+ .ng, .gg, .tg, .ntg, .cg, .eg, .mdg {
11711
+ animation: none !important;
11712
+ transition: none !important;
11713
+ }
11714
+
11715
+ .ng.hidden { opacity: 0 !important; pointer-events: none !important; }
11716
+ .gg.gg-hidden,
11717
+ .tg.gg-hidden,
11718
+ .ntg.gg-hidden,
11719
+ .cg.gg-hidden,
11720
+ .eg.gg-hidden,
11721
+ .mdg.gg-hidden { opacity: 0 !important; }
11722
+
11723
+ .ng.faded,
11724
+ .gg.faded,
11725
+ .tg.faded,
11726
+ .ntg.faded,
11727
+ .cg.faded,
11728
+ .eg.faded,
11729
+ .mdg.faded { opacity: 0.22 !important; }
11730
+
11731
+ .ng.hl path, .ng.hl rect, .ng.hl ellipse, .ng.hl polygon,
11732
+ .tg.hl path, .tg.hl rect,
11733
+ .ntg.hl path, .ntg.hl polygon,
11734
+ .cg.hl path, .cg.hl rect,
11735
+ .mdg.hl text,
11736
+ .eg.hl path, .eg.hl line, .eg.hl polygon { stroke-width: 2.8 !important; }
11737
+ `;
11738
+ function buildExportSnapshot(svg) {
11739
+ const snapshot = svg.cloneNode(true);
11740
+ const animationState = getExportAnimationState(svg);
11741
+ if (animationState?.steps.length) {
11742
+ snapshot.querySelector("#annotation-layer")?.remove();
11743
+ let rc = null;
11744
+ try {
11745
+ rc = rough.svg(snapshot);
11746
+ }
11747
+ catch {
11748
+ rc = null;
11749
+ }
11750
+ const anim = new AnimationController(snapshot, animationState.steps, undefined, rc, animationState.config);
11751
+ anim.goTo(animationState.steps.length - 1);
11752
+ }
11753
+ injectExportStyles(snapshot);
11754
+ return snapshot;
11755
+ }
11756
+ function injectExportStyles(svg) {
11757
+ if (svg.querySelector(`#${EXPORT_SVG_STYLE_ID}`))
11758
+ return;
11759
+ const style = document.createElementNS(SVG_NS$1, "style");
11760
+ style.setAttribute("id", EXPORT_SVG_STYLE_ID);
11761
+ style.textContent = EXPORT_SVG_STATE_CSS;
11762
+ svg.insertBefore(style, svg.firstChild);
11763
+ }
11697
11764
  // ── Trigger browser download ──────────────────────────────
11698
11765
  function download(blob, filename) {
11699
11766
  const url = URL.createObjectURL(blob);
@@ -11707,15 +11774,15 @@ function download(blob, filename) {
11707
11774
  }
11708
11775
  // ── SVG export ────────────────────────────────────────────
11709
11776
  function exportSVG(svg, opts = {}) {
11710
- const str = svgToString(svg);
11777
+ const str = svgToString(buildExportSnapshot(svg));
11711
11778
  const blob = new Blob([str], { type: 'image/svg+xml;charset=utf-8' });
11712
11779
  download(blob, opts.filename ?? 'diagram.svg');
11713
11780
  }
11714
11781
  function getSVGString(svg) {
11715
- return svgToString(svg);
11782
+ return svgToString(buildExportSnapshot(svg));
11716
11783
  }
11717
11784
  function getSVGBlob(svg) {
11718
- return new Blob([svgToString(svg)], { type: 'image/svg+xml;charset=utf-8' });
11785
+ return new Blob([svgToString(buildExportSnapshot(svg))], { type: 'image/svg+xml;charset=utf-8' });
11719
11786
  }
11720
11787
  // ── PNG export (from SVG via Canvas) ─────────────────────
11721
11788
  async function exportPNG(svg, opts = {}) {
@@ -11741,7 +11808,7 @@ async function svgToPNGDataURL(svg, opts = {}) {
11741
11808
  ctx.fillStyle = EXPORT.fallbackBg;
11742
11809
  ctx.fillRect(0, 0, w, h);
11743
11810
  }
11744
- const svgStr = svgToString(svg);
11811
+ const svgStr = svgToString(buildExportSnapshot(svg));
11745
11812
  const blob = new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });
11746
11813
  const url = URL.createObjectURL(blob);
11747
11814
  await new Promise((resolve, reject) => {
@@ -11759,7 +11826,7 @@ async function exportCanvasPNG(canvas, opts = {}) {
11759
11826
  }
11760
11827
  // ── HTML export (self-contained) ──────────────────────────
11761
11828
  function exportHTML(svg, dslSource, opts = {}) {
11762
- const svgStr = svgToString(svg);
11829
+ const svgStr = svgToString(buildExportSnapshot(svg));
11763
11830
  const html = `<!DOCTYPE html>
11764
11831
  <html lang="en">
11765
11832
  <head>
@@ -11940,6 +12007,7 @@ function render(options) {
11940
12007
  }
11941
12008
  const containerEl = el instanceof SVGSVGElement ? undefined : el;
11942
12009
  anim = new AnimationController(svg, ast.steps, containerEl, rc, ast.config);
12010
+ bindExportAnimationState(svg, { steps: ast.steps, config: ast.config });
11943
12011
  }
11944
12012
  if (typeof tts === "boolean") {
11945
12013
  anim.tts = tts;