@motionscript/latex 0.1.0-alpha.0 → 0.1.0-alpha.3
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/CHANGELOG.md +16 -0
- package/README.md +27 -20
- package/dist/browser/index.js +18 -18
- package/dist/browser/index.js.map +4 -4
- package/dist/browser/manifest.json +2 -2
- package/dist/geometry.d.ts +7 -1
- package/dist/geometry.d.ts.map +1 -1
- package/dist/geometry.js +19 -1
- package/dist/geometry.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +2 -2
- package/dist/node.js.map +1 -1
- package/dist/tween.js +1 -1
- package/dist/tween.js.map +1 -1
- package/package.json +4 -3
- package/src/geometry.ts +22 -2
- package/src/node.ts +2 -2
- package/src/tween.ts +1 -1
package/dist/geometry.d.ts
CHANGED
|
@@ -8,7 +8,13 @@ import '@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js';
|
|
|
8
8
|
import '@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js';
|
|
9
9
|
import '@mathjax/src/js/input/tex/bbox/BboxConfiguration.js';
|
|
10
10
|
import '@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js';
|
|
11
|
-
import
|
|
11
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/calligraphic.js';
|
|
12
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/double-struck.js';
|
|
13
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/fraktur.js';
|
|
14
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/monospace.js';
|
|
15
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/sans-serif.js';
|
|
16
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/script.js';
|
|
17
|
+
import { PathCommand } from '@motionscript/sdk';
|
|
12
18
|
/** A single rendered glyph or shape with its character key and path commands. */
|
|
13
19
|
export interface LatexToken {
|
|
14
20
|
/** Character this token represents, or a synthetic key for non-glyph shapes. */
|
package/dist/geometry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"AAQA,OAAO,qDAAqD,CAAC;AAC7D,OAAO,mDAAmD,CAAC;AAC3D,OAAO,iEAAiE,CAAC;AACzE,OAAO,iEAAiE,CAAC;AACzE,OAAO,yDAAyD,CAAC;AACjE,OAAO,uDAAuD,CAAC;AAC/D,OAAO,yDAAyD,CAAC;AACjE,OAAO,2DAA2D,CAAC;AACnE,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+DAA+D,CAAC;
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"AAQA,OAAO,qDAAqD,CAAC;AAC7D,OAAO,mDAAmD,CAAC;AAC3D,OAAO,iEAAiE,CAAC;AACzE,OAAO,iEAAiE,CAAC;AACzE,OAAO,yDAAyD,CAAC;AACjE,OAAO,uDAAuD,CAAC;AAC/D,OAAO,yDAAyD,CAAC;AACjE,OAAO,2DAA2D,CAAC;AACnE,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+DAA+D,CAAC;AAGvE,OAAO,4DAA4D,CAAC;AACpE,OAAO,6DAA6D,CAAC;AACrE,OAAO,uDAAuD,CAAC;AAC/D,OAAO,yDAAyD,CAAC;AACjE,OAAO,0DAA0D,CAAC;AAClE,OAAO,sDAAsD,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkDhD,iFAAiF;AACjF,MAAM,WAAW,UAAU;IACvB,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC5B,kCAAkC;IAClC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,0EAA0E;IAC1E,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAoDD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAiB9E"}
|
package/dist/geometry.js
CHANGED
|
@@ -14,6 +14,13 @@ import '@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js';
|
|
|
14
14
|
import '@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js';
|
|
15
15
|
import '@mathjax/src/js/input/tex/bbox/BboxConfiguration.js';
|
|
16
16
|
import '@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js';
|
|
17
|
+
import { MathJaxNewcmFont } from '@mathjax/mathjax-newcm-font/js/svg.js';
|
|
18
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/calligraphic.js';
|
|
19
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/double-struck.js';
|
|
20
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/fraktur.js';
|
|
21
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/monospace.js';
|
|
22
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/sans-serif.js';
|
|
23
|
+
import '@mathjax/mathjax-newcm-font/js/svg/dynamic/script.js';
|
|
17
24
|
import { createBoundedCache } from './cache.js';
|
|
18
25
|
// --- MathJax Setup (synchronous) ---
|
|
19
26
|
/**
|
|
@@ -41,7 +48,18 @@ const texJax = new TeX({
|
|
|
41
48
|
'bbox', 'mathtools',
|
|
42
49
|
],
|
|
43
50
|
});
|
|
44
|
-
|
|
51
|
+
/**
|
|
52
|
+
* The font files behind `\mathcal`, `\mathbb`, `\mathfrak`, `\mathsf`, `\mathtt`
|
|
53
|
+
* and `\mathscr`, imported above. MathJax fetches these asynchronously the first
|
|
54
|
+
* time a formula needs one, which a synchronous typesetter cannot wait for, so
|
|
55
|
+
* they are bundled and set up on the font before anything is typeset. The font
|
|
56
|
+
* class is passed explicitly so the one they register on is the one in use.
|
|
57
|
+
*/
|
|
58
|
+
const BUNDLED_FONT_FILES = ['calligraphic', 'double-struck', 'fraktur', 'monospace', 'sans-serif', 'script'];
|
|
59
|
+
const svgJax = new SVG({ fontCache: 'local', fontData: MathJaxNewcmFont });
|
|
60
|
+
const fontFiles = MathJaxNewcmFont.dynamicFiles;
|
|
61
|
+
for (const file of BUNDLED_FONT_FILES)
|
|
62
|
+
fontFiles[file].setup(svgJax.font);
|
|
45
63
|
const mjDoc = mathjax.document('', { InputJax: texJax, OutputJax: svgJax });
|
|
46
64
|
/**
|
|
47
65
|
* Formulas already worked out, and formulas already sized.
|
package/dist/geometry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry.js","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { mathjax } from '@mathjax/src/js/mathjax.js';\nimport { TeX } from '@mathjax/src/js/input/tex.js';\nimport { SVG } from '@mathjax/src/js/output/svg.js';\nimport { browserAdaptor } from '@mathjax/src/js/adaptors/browserAdaptor.js';\nimport { liteAdaptor } from '@mathjax/src/js/adaptors/liteAdaptor.js';\nimport { RegisterHTMLHandler } from '@mathjax/src/js/handlers/html.js';\n\nimport '@mathjax/src/js/input/tex/base/BaseConfiguration.js';\nimport '@mathjax/src/js/input/tex/ams/AmsConfiguration.js';\nimport '@mathjax/src/js/input/tex/boldsymbol/BoldsymbolConfiguration.js';\nimport '@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js';\nimport '@mathjax/src/js/input/tex/cancel/CancelConfiguration.js';\nimport '@mathjax/src/js/input/tex/color/ColorConfiguration.js';\nimport '@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js';\nimport '@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js';\nimport '@mathjax/src/js/input/tex/bbox/BboxConfiguration.js';\nimport '@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js';\nimport { PathCommand } from '@motionscript/core';\n\nimport { createBoundedCache } from './cache';\n\n// --- MathJax Setup (synchronous) ---\n\n/**\n * MathJax needs a DOM to build its output in, and there isn't always one.\n *\n * `browserAdaptor()` reads `window` **as it is constructed**, at module scope —\n * so importing this file at all threw in Node, and a project with one LaTeX\n * scene could not be rendered headlessly no matter which scene was asked for.\n * `liteAdaptor` is MathJax's own DOM-free implementation and produces the same\n * SVG; we only ever read paths back out of it, never attach it to a page.\n */\n// The two adaptors are structurally different (a `LiteElement` tree vs. a real\n// one) and MathJax's generics track that, but nothing here touches an element\n// except through the adaptor's own accessors — so the element type is genuinely\n// opaque to us, and pinning it to either concrete one would be a lie.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst adaptor: any = typeof window === 'undefined' && typeof document === 'undefined'\n ? liteAdaptor()\n : browserAdaptor();\nRegisterHTMLHandler(adaptor);\n\nconst texJax = new TeX({\n packages: [\n 'base', 'ams', 'boldsymbol', 'newcommand',\n 'cancel', 'color', 'mhchem', 'physics',\n 'bbox', 'mathtools',\n ],\n});\n\nconst svgJax = new SVG({ fontCache: 'local' });\nconst mjDoc = mathjax.document('', { InputJax: texJax, OutputJax: svgJax });\n\n// --- Public API ---\n\n/** A single rendered glyph or shape with its character key and path commands. */\nexport interface LatexToken {\n /** Character this token represents, or a synthetic key for non-glyph shapes. */\n token: string;\n path: PathCommand[];\n}\n\nexport interface LatexPathResult {\n /** All tokens in render order. */\n tokens: LatexToken[];\n /** Flat array of all path commands (for legacy single-path rendering). */\n commands: PathCommand[];\n width: number;\n height: number;\n /**\n * Bounding box over every token, in token coordinate space:\n * [minX, minY, maxX, maxY]. All tokens share this frame, so passing it as\n * each path's center frame keeps their relative layout (instead of each\n * glyph centering on its own bbox).\n */\n bounds: [number, number, number, number];\n}\n\n/**\n * A formula's glyph geometry, before a type size is applied to it.\n *\n * The dividing line this whole module's caching turns on. Getting here is the\n * expensive part — MathJax lays the formula out, then the SVG it produces is\n * parsed, its glyph dictionary resolved and every `<use>` walked through its\n * transform stack — and **none of it depends on `fontSize`**: `mjDoc.convert`\n * is called at a fixed em/ex, and the size arrives at the very end as one\n * uniform scale (see {@link scaleLatexGeometry}).\n *\n * So this is what gets remembered per formula, and the size is applied to it\n * afresh. A formula animating from 24pt to 120pt is one trip through MathJax\n * and one DOM parse, not one per frame.\n */\ninterface LatexGeometry {\n tokens: RawToken[];\n /** Box over every command, in the SVG's own coordinates. */\n box: { minX: number; minY: number; maxX: number; maxY: number };\n /** The formula's height in `ex`, as MathJax reported it. */\n heightEx: number;\n}\n\n/**\n * Formulas already worked out, and formulas already sized.\n *\n * `buildLatexPath` is a pure function of `(text, fontSize)` and used to have no\n * memory, which made every caller pay full price for a question it had already\n * asked. The callers are not occasional about it either: constructing a `Latex`\n * resolves its formula, and so does every `to({ latex })` the moment it starts,\n * so a scene re-resolves every formula in it whenever it is rebuilt *and*\n * whenever the playhead moves backwards, since a backward seek replays the\n * scene's generator from its first frame. An editor that rebuilds on a keystroke\n * and seeks on a click asks for the same handful of formulas hundreds of times.\n *\n * Two memos, each keyed by what its stage actually depends on, and deliberately\n * different sizes:\n *\n * - {@link geometryCache} is everything up to the type size, keyed by the text\n * alone. This is the expensive one, and it is generously sized because\n * nothing a scene does can churn it: a deck holds as many distinct formulas\n * as it holds, and it holds them for as long as it is open.\n * - {@link pathCache} is the finished result, keyed by text *and* size. Small\n * on purpose: an animated `fontSize` inserts a distinct key every frame, and\n * the right thing for a stream like that is to churn a little memo rather\n * than a big one. What a miss costs here is arithmetic over glyphs already\n * worked out — no MathJax, no parse.\n */\nconst geometryCache = createBoundedCache<LatexGeometry>(128);\nconst pathCache = createBoundedCache<LatexPathResult>(64);\n\nexport function buildLatexPath(text: string, fontSize: number): LatexPathResult {\n // NUL rather than a punctuation separator, so no formula can spell a key\n // belonging to another size.\n const key = `${fontSize}\\0${text}`;\n\n const hit = pathCache.get(key);\n if (hit) return lend(hit);\n\n let geometry = geometryCache.get(text);\n if (!geometry) {\n geometry = buildLatexGeometry(text);\n geometryCache.set(text, geometry);\n }\n\n const result = scaleLatexGeometry(geometry, fontSize);\n pathCache.set(key, result);\n return lend(result);\n}\n\n/** Typeset `text` and reduce the SVG MathJax returns to glyph geometry. */\nfunction buildLatexGeometry(text: string): LatexGeometry {\n const node = mjDoc.convert(text, {\n display: true,\n em: 16,\n ex: 8,\n containerWidth: 80 * 16,\n });\n\n const svgEl = adaptor.firstChild(node);\n const heightAttr = adaptor.getAttribute(svgEl, 'height') ?? '';\n\n return parseLatexSvg(svgEl, parseFloat(heightAttr) || 0);\n}\n\n/**\n * A cached result, handed out safely.\n *\n * `tokens`, `commands` and the path arrays inside them are shared: they are read\n * by everything downstream and written by none of it — `Latex` maps tokens into\n * its own wrappers, and the morph builds new paths rather than editing the ones\n * it is given — so copying them would be copying the whole formula for nothing.\n *\n * `bounds` is copied, because it is the one field a caller *stores*: `Latex`\n * assigns `result.bounds` straight to `this._bounds` and hands it to the\n * renderer as a shared centring frame. That was one node holding its own array\n * before there was a memo, and would be two nodes drawing the same formula\n * holding one array between them after — four numbers is not a price worth\n * paying to find out whether anything downstream ever writes to it.\n */\nfunction lend(result: LatexPathResult): LatexPathResult {\n const [minX, minY, maxX, maxY] = result.bounds;\n return { ...result, bounds: [minX, minY, maxX, maxY] };\n}\n\n// --- High-Speed Matrix Math ---\n\ntype Matrix = [number, number, number, number, number, number]; // [a, b, c, d, tx, ty]\nconst identityMatrix: Matrix = [1, 0, 0, 1, 0, 0];\n\nfunction multiplyMatrix(m1: Matrix, m2: Matrix): Matrix {\n return [\n m1[0] * m2[0] + m1[2] * m2[1],\n m1[1] * m2[0] + m1[3] * m2[1],\n m1[0] * m2[2] + m1[2] * m2[3],\n m1[1] * m2[2] + m1[3] * m2[3],\n m1[0] * m2[4] + m1[2] * m2[5] + m1[4],\n m1[1] * m2[4] + m1[3] * m2[5] + m1[5],\n ];\n}\n\nfunction parseTransform(str: string | null): Matrix {\n if (!str) return identityMatrix;\n let m: Matrix = [...identityMatrix];\n const re = /([a-z]+)\\(([^)]+)\\)/g;\n let match;\n while ((match = re.exec(str)) !== null) {\n const type = match[1];\n const args = match[2].split(/[ ,]+/).map(parseFloat);\n if (type === 'translate') {\n m = multiplyMatrix(m, [1, 0, 0, 1, args[0] || 0, args[1] || 0]);\n } else if (type === 'scale') {\n const sx = args[0] || 1;\n const sy = args[1] !== undefined ? args[1] : sx;\n m = multiplyMatrix(m, [sx, 0, 0, sy, 0, 0]);\n } else if (type === 'matrix') {\n m = multiplyMatrix(m, [args[0], args[1], args[2], args[3], args[4], args[5]]);\n }\n }\n return m;\n}\n\nfunction applyMatrix(x: number, y: number, m: Matrix): [number, number] {\n return [\n x * m[0] + y * m[2] + m[4],\n x * m[1] + y * m[3] + m[5],\n ];\n}\n\n// --- Glyph ID → character decoding ---\n\n/**\n * MathJax SVG glyph IDs look like \"MJX-1-TEX-N-78\" or \"MJX-1-TEX-I-1D465\".\n * The last segment is the Unicode codepoint in hex.\n */\nfunction glyphIdToChar(id: string): string {\n const parts = id.split('-');\n const hex = parts[parts.length - 1];\n const cp = parseInt(hex, 16);\n if (!isNaN(cp)) {\n try { return String.fromCodePoint(cp); } catch { /* fall through */ }\n }\n return id;\n}\n\n// --- Core Fast Traversal Engine ---\n\ntype RawToken = { token: string; cmds: Array<{ cmd: string; args: number[] }> };\n\n/** The tag name of a node's parent, or \"\" at the root. */\nfunction parentKind(node: unknown): string {\n const parent = adaptor.parent(node);\n return parent ? String(adaptor.kind(parent)).toLowerCase() : \"\";\n}\n\n/**\n * The size-independent half: MathJax's own SVG tree in, glyph geometry out.\n *\n * Walked through the **adaptor** rather than a `DOMParser`. MathJax already\n * builds this tree, and the adaptor is its own abstraction over \"a real DOM\" and\n * \"the DOM-free `LiteElement` tree\" — the two this module already picks between\n * at load. Serialising it to a string and parsing it back needed a `DOMParser`,\n * which Node does not have, so every LaTeX node threw `DOMParser is not defined`\n * and could not render headlessly at all: no export, and nothing the visual\n * suite could check.\n *\n * Reading the tree directly is also one representation instead of three (tree →\n * string → tree), so a browser and a headless host cannot disagree about how the\n * markup re-parsed.\n */\nfunction parseLatexSvg(svgEl: unknown, heightEx: number): LatexGeometry {\n // Pre-parse the glyph dictionary. `tags` reaches every <path> in the tree,\n // including the ones inside <defs> that the `use` elements reference.\n const glyphMap = new Map<string, Array<{ cmd: string; args: number[] }>>();\n for (const el of adaptor.tags(svgEl, 'path') as unknown[]) {\n const id = adaptor.getAttribute(el, 'id');\n const d = adaptor.getAttribute(el, 'd');\n if (id && d) {\n glyphMap.set(`#${id}`, expandToAbsolute(tokenisePath(d)));\n }\n }\n\n // Collect raw tokens — each <use> is one token, rects/paths are grouped as synthetic tokens\n const rawTokens: RawToken[] = [];\n let synthIdx = 0;\n\n function pushCmds(token: string, cmds: Array<{ cmd: string; args: number[] }>) {\n rawTokens.push({ token, cmds });\n }\n\n function traverse(node: unknown, currentMatrix: Matrix) {\n let nodeMatrix = currentMatrix;\n\n const transformStr = adaptor.getAttribute(node, \"transform\");\n if (transformStr) {\n nodeMatrix = multiplyMatrix(nodeMatrix, parseTransform(transformStr));\n }\n\n const nodeName = String(adaptor.kind(node)).toLowerCase();\n\n if (nodeName === \"use\") {\n const href = adaptor.getAttribute(node, \"href\") || adaptor.getAttribute(node, \"xlink:href\");\n const x = parseFloat(adaptor.getAttribute(node, \"x\") || \"0\");\n const y = parseFloat(adaptor.getAttribute(node, \"y\") || \"0\");\n\n if (href && glyphMap.has(href)) {\n const glyphCommands = glyphMap.get(href)!;\n const cmds: Array<{ cmd: string; args: number[] }> = [];\n for (const gc of glyphCommands) {\n const shiftedArgs = [...gc.args];\n for (let j = 0; j < shiftedArgs.length; j += 2) {\n const [nx, ny] = applyMatrix(shiftedArgs[j] + x, shiftedArgs[j + 1] + y, nodeMatrix);\n shiftedArgs[j] = nx;\n shiftedArgs[j + 1] = ny;\n }\n cmds.push({ cmd: gc.cmd, args: shiftedArgs });\n }\n // Derive character from glyph ID\n const rawId = href.startsWith('#') ? href.slice(1) : href;\n pushCmds(glyphIdToChar(rawId), cmds);\n }\n } else if (nodeName === \"rect\") {\n const x = parseFloat(adaptor.getAttribute(node, \"x\") || \"0\");\n const y = parseFloat(adaptor.getAttribute(node, \"y\") || \"0\");\n const w = parseFloat(adaptor.getAttribute(node, \"width\") || \"0\");\n const h = parseFloat(adaptor.getAttribute(node, \"height\") || \"0\");\n\n if (w > 0 && h > 0) {\n const pts = [[x, y], [x + w, y], [x + w, y + h], [x, y + h]];\n const tp = pts.map(p => applyMatrix(p[0], p[1], nodeMatrix));\n pushCmds(`__rect_${synthIdx++}`, [\n { cmd: 'M', args: [tp[0][0], tp[0][1]] },\n { cmd: 'L', args: [tp[1][0], tp[1][1]] },\n { cmd: 'L', args: [tp[2][0], tp[2][1]] },\n { cmd: 'L', args: [tp[3][0], tp[3][1]] },\n { cmd: 'Z', args: [] },\n ]);\n }\n } else if (nodeName === \"path\" && parentKind(node) !== \"defs\") {\n const d = adaptor.getAttribute(node, \"d\");\n if (d) {\n const abs = expandToAbsolute(tokenisePath(d));\n const cmds: Array<{ cmd: string; args: number[] }> = [];\n for (const gc of abs) {\n const shiftedArgs = [...gc.args];\n for (let j = 0; j < shiftedArgs.length; j += 2) {\n const [nx, ny] = applyMatrix(shiftedArgs[j], shiftedArgs[j + 1], nodeMatrix);\n shiftedArgs[j] = nx;\n shiftedArgs[j + 1] = ny;\n }\n cmds.push({ cmd: gc.cmd, args: shiftedArgs });\n }\n pushCmds(`__path_${synthIdx++}`, cmds);\n }\n }\n\n for (const child of adaptor.childNodes(node) as unknown[]) {\n // A text node's kind is \"#text\"; only elements carry geometry, and\n // <defs> holds the dictionary rather than anything drawn.\n const kind = String(adaptor.kind(child)).toLowerCase();\n if (kind.startsWith(\"#\") || kind === \"defs\") continue;\n traverse(child, nodeMatrix);\n }\n }\n\n traverse(svgEl, identityMatrix);\n\n // Bounding box across all raw commands, in the SVG's own coordinates.\n const box = svgBBox(rawTokens.flatMap(t => t.cmds));\n return { tokens: rawTokens, box, heightEx };\n}\n\n/**\n * The size-dependent half: glyph geometry in, a laid-out formula out.\n *\n * Everything here is one uniform scale about the geometry's own centre, which\n * is exactly why {@link LatexGeometry} is worth remembering on its own.\n */\nfunction scaleLatexGeometry(geometry: LatexGeometry, fontSize: number): LatexPathResult {\n const { tokens: rawTokens, box, heightEx } = geometry;\n if (rawTokens.length === 0) return { tokens: [], commands: [], width: 0, height: 0, bounds: [0, 0, 0, 0] };\n\n const { minX, minY, maxX, maxY } = box;\n const svgW = maxX - minX;\n const svgH = maxY - minY;\n\n let scale: number;\n if (heightEx > 0 && svgH > 0) {\n const exInCoords = svgH / heightEx;\n scale = fontSize / (2 * exInCoords);\n } else {\n scale = svgH > 0 ? fontSize / svgH : 1;\n }\n\n const ocx = (minX + maxX) / 2;\n const ocy = (minY + maxY) / 2;\n\n const tx = (svgX: number) => (svgX - ocx) * scale;\n const ty = (svgY: number) => (svgY - ocy) * scale;\n\n function rawCmdsToPathCommands(cmds: Array<{ cmd: string; args: number[] }>): PathCommand[] {\n const out: PathCommand[] = [];\n for (const { cmd, args: a } of cmds) {\n switch (cmd) {\n case 'M': out.push({ type: 'M', x: tx(a[0]), y: ty(a[1]) }); break;\n case 'L': out.push({ type: 'L', x: tx(a[0]), y: ty(a[1]) }); break;\n case 'Q': out.push({ type: 'Q', x1: tx(a[0]), y1: ty(a[1]), x: tx(a[2]), y: ty(a[3]) }); break;\n case 'C': out.push({ type: 'C', x1: tx(a[0]), y1: ty(a[1]), x2: tx(a[2]), y2: ty(a[3]), x: tx(a[4]), y: ty(a[5]) }); break;\n case 'Z': out.push({ type: 'Z' }); break;\n }\n }\n return out;\n }\n\n const tokens: LatexToken[] = rawTokens.map(rt => ({\n token: rt.token,\n path: rawCmdsToPathCommands(rt.cmds),\n }));\n\n const commands = tokens.flatMap(t => t.path);\n\n // Shared center frame for all tokens, in token coordinate space. tx/ty map\n // the SVG bbox corners; this is the frame every token's path is laid out in.\n const bounds: [number, number, number, number] = [\n tx(minX), ty(minY), tx(maxX), ty(maxY),\n ];\n\n return { tokens, commands, width: svgW * scale, height: svgH * scale, bounds };\n}\n\n// --- SVG Path Utilities ---\n\ntype RawCmd = { cmd: string; args: number[] };\n\nfunction tokenisePath(d: string): RawCmd[] {\n const re = /([MmLlHhVvCcSsQqTtAaZz])|([+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?)/g;\n const out: RawCmd[] = [];\n let cur: RawCmd | null = null;\n let m: RegExpExecArray | null;\n while ((m = re.exec(d)) !== null) {\n if (m[1]) { cur = { cmd: m[1], args: [] }; out.push(cur); }\n else if (cur) cur.args.push(parseFloat(m[2]));\n }\n return out;\n}\n\nfunction argCount(cmd: string): number {\n switch (cmd.toUpperCase()) {\n case 'M': return 2; case 'L': return 2; case 'H': return 1; case 'V': return 1;\n case 'C': return 6; case 'S': return 4; case 'Q': return 4; case 'T': return 2;\n case 'A': return 7; case 'Z': return 0; default: return 0;\n }\n}\n\ninterface Pt { x: number; y: number }\n\nfunction expandToAbsolute(raw: RawCmd[]): Array<{ cmd: string; args: number[] }> {\n const out: Array<{ cmd: string; args: number[] }> = [];\n let cx = 0, cy = 0;\n let mx = 0, my = 0;\n let prevCmd = '';\n let prevCtrl: Pt = { x: 0, y: 0 };\n\n for (const { cmd, args } of raw) {\n const up = cmd.toUpperCase();\n const rel = cmd === cmd.toLowerCase() && up !== 'Z';\n const n = argCount(up);\n const reps = n === 0 ? 1 : Math.max(1, Math.ceil(args.length / n));\n\n for (let r = 0; r < reps; r++) {\n const a = args.slice(r * n, r * n + n);\n const absX = (i: number) => rel ? a[i] + cx : a[i];\n const absY = (i: number) => rel ? a[i] + cy : a[i];\n\n switch (up) {\n case 'M': {\n const x = absX(0), y = absY(1);\n const emitCmd = r === 0 ? 'M' : 'L';\n out.push({ cmd: emitCmd, args: [x, y] });\n cx = x; cy = y;\n if (r === 0) { mx = x; my = y; }\n prevCmd = emitCmd;\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'Z':\n out.push({ cmd: 'Z', args: [] });\n cx = mx; cy = my;\n prevCmd = 'Z';\n break;\n case 'L': {\n const x = absX(0), y = absY(1);\n out.push({ cmd: 'L', args: [x, y] });\n cx = x; cy = y;\n prevCmd = 'L';\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'H': {\n const x = rel ? a[0] + cx : a[0];\n out.push({ cmd: 'L', args: [x, cy] });\n cx = x;\n prevCmd = 'L';\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'V': {\n const y = rel ? a[0] + cy : a[0];\n out.push({ cmd: 'L', args: [cx, y] });\n cy = y;\n prevCmd = 'L';\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'C': {\n const x1 = absX(0), y1 = absY(1);\n const x2 = absX(2), y2 = absY(3);\n const x = absX(4), y = absY(5);\n out.push({ cmd: 'C', args: [x1, y1, x2, y2, x, y] });\n prevCtrl = { x: x2, y: y2 };\n cx = x; cy = y;\n prevCmd = 'C';\n break;\n }\n case 'S': {\n const x1 = prevCmd === 'C' || prevCmd === 'S' ? 2 * cx - prevCtrl.x : cx;\n const y1 = prevCmd === 'C' || prevCmd === 'S' ? 2 * cy - prevCtrl.y : cy;\n const x2 = absX(0), y2 = absY(1);\n const x = absX(2), y = absY(3);\n out.push({ cmd: 'C', args: [x1, y1, x2, y2, x, y] });\n prevCtrl = { x: x2, y: y2 };\n cx = x; cy = y;\n prevCmd = 'S';\n break;\n }\n case 'Q': {\n const x1 = absX(0), y1 = absY(1);\n const x = absX(2), y = absY(3);\n out.push({ cmd: 'Q', args: [x1, y1, x, y] });\n prevCtrl = { x: x1, y: y1 };\n cx = x; cy = y;\n prevCmd = 'Q';\n break;\n }\n case 'T': {\n const x1 = prevCmd === 'Q' || prevCmd === 'T' ? 2 * cx - prevCtrl.x : cx;\n const y1 = prevCmd === 'Q' || prevCmd === 'T' ? 2 * cy - prevCtrl.y : cy;\n const x = absX(0), y = absY(1);\n out.push({ cmd: 'Q', args: [x1, y1, x, y] });\n prevCtrl = { x: x1, y: y1 };\n cx = x; cy = y;\n prevCmd = 'T';\n break;\n }\n }\n }\n }\n\n if (out.length > 0 && out[out.length - 1].cmd !== 'Z') {\n out.push({ cmd: 'Z', args: [] });\n }\n\n return out;\n}\n\nfunction svgBBox(abs: Array<{ cmd: string; args: number[] }>): { minX: number; minY: number; maxX: number; maxY: number } {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n const touch = (x: number, y: number) => {\n if (x < minX) minX = x; if (x > maxX) maxX = x;\n if (y < minY) minY = y; if (y > maxY) maxY = y;\n };\n for (const { cmd, args } of abs) {\n switch (cmd) {\n case 'M': case 'L': touch(args[0], args[1]); break;\n case 'C': touch(args[0], args[1]); touch(args[2], args[3]); touch(args[4], args[5]); break;\n case 'Q': touch(args[0], args[1]); touch(args[2], args[3]); break;\n }\n }\n return { minX, minY, maxX, maxY };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"geometry.js","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { mathjax } from '@mathjax/src/js/mathjax.js';\nimport { TeX } from '@mathjax/src/js/input/tex.js';\nimport { SVG } from '@mathjax/src/js/output/svg.js';\nimport { browserAdaptor } from '@mathjax/src/js/adaptors/browserAdaptor.js';\nimport { liteAdaptor } from '@mathjax/src/js/adaptors/liteAdaptor.js';\nimport { RegisterHTMLHandler } from '@mathjax/src/js/handlers/html.js';\n\nimport '@mathjax/src/js/input/tex/base/BaseConfiguration.js';\nimport '@mathjax/src/js/input/tex/ams/AmsConfiguration.js';\nimport '@mathjax/src/js/input/tex/boldsymbol/BoldsymbolConfiguration.js';\nimport '@mathjax/src/js/input/tex/newcommand/NewcommandConfiguration.js';\nimport '@mathjax/src/js/input/tex/cancel/CancelConfiguration.js';\nimport '@mathjax/src/js/input/tex/color/ColorConfiguration.js';\nimport '@mathjax/src/js/input/tex/mhchem/MhchemConfiguration.js';\nimport '@mathjax/src/js/input/tex/physics/PhysicsConfiguration.js';\nimport '@mathjax/src/js/input/tex/bbox/BboxConfiguration.js';\nimport '@mathjax/src/js/input/tex/mathtools/MathtoolsConfiguration.js';\nimport type { DynamicFileList } from '@mathjax/src/js/output/common/FontData.js';\nimport { MathJaxNewcmFont } from '@mathjax/mathjax-newcm-font/js/svg.js';\nimport '@mathjax/mathjax-newcm-font/js/svg/dynamic/calligraphic.js';\nimport '@mathjax/mathjax-newcm-font/js/svg/dynamic/double-struck.js';\nimport '@mathjax/mathjax-newcm-font/js/svg/dynamic/fraktur.js';\nimport '@mathjax/mathjax-newcm-font/js/svg/dynamic/monospace.js';\nimport '@mathjax/mathjax-newcm-font/js/svg/dynamic/sans-serif.js';\nimport '@mathjax/mathjax-newcm-font/js/svg/dynamic/script.js';\nimport { PathCommand } from '@motionscript/sdk';\n\nimport { createBoundedCache } from './cache';\n\n// --- MathJax Setup (synchronous) ---\n\n/**\n * MathJax needs a DOM to build its output in, and there isn't always one.\n *\n * `browserAdaptor()` reads `window` **as it is constructed**, at module scope —\n * so importing this file at all threw in Node, and a project with one LaTeX\n * scene could not be rendered headlessly no matter which scene was asked for.\n * `liteAdaptor` is MathJax's own DOM-free implementation and produces the same\n * SVG; we only ever read paths back out of it, never attach it to a page.\n */\n// The two adaptors are structurally different (a `LiteElement` tree vs. a real\n// one) and MathJax's generics track that, but nothing here touches an element\n// except through the adaptor's own accessors — so the element type is genuinely\n// opaque to us, and pinning it to either concrete one would be a lie.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst adaptor: any = typeof window === 'undefined' && typeof document === 'undefined'\n ? liteAdaptor()\n : browserAdaptor();\nRegisterHTMLHandler(adaptor);\n\nconst texJax = new TeX({\n packages: [\n 'base', 'ams', 'boldsymbol', 'newcommand',\n 'cancel', 'color', 'mhchem', 'physics',\n 'bbox', 'mathtools',\n ],\n});\n\n/**\n * The font files behind `\\mathcal`, `\\mathbb`, `\\mathfrak`, `\\mathsf`, `\\mathtt`\n * and `\\mathscr`, imported above. MathJax fetches these asynchronously the first\n * time a formula needs one, which a synchronous typesetter cannot wait for, so\n * they are bundled and set up on the font before anything is typeset. The font\n * class is passed explicitly so the one they register on is the one in use.\n */\nconst BUNDLED_FONT_FILES = ['calligraphic', 'double-struck', 'fraktur', 'monospace', 'sans-serif', 'script'];\n\nconst svgJax = new SVG({ fontCache: 'local', fontData: MathJaxNewcmFont });\nconst fontFiles = (MathJaxNewcmFont as unknown as { dynamicFiles: DynamicFileList }).dynamicFiles;\nfor (const file of BUNDLED_FONT_FILES) fontFiles[file].setup(svgJax.font);\n\nconst mjDoc = mathjax.document('', { InputJax: texJax, OutputJax: svgJax });\n\n// --- Public API ---\n\n/** A single rendered glyph or shape with its character key and path commands. */\nexport interface LatexToken {\n /** Character this token represents, or a synthetic key for non-glyph shapes. */\n token: string;\n path: PathCommand[];\n}\n\nexport interface LatexPathResult {\n /** All tokens in render order. */\n tokens: LatexToken[];\n /** Flat array of all path commands (for legacy single-path rendering). */\n commands: PathCommand[];\n width: number;\n height: number;\n /**\n * Bounding box over every token, in token coordinate space:\n * [minX, minY, maxX, maxY]. All tokens share this frame, so passing it as\n * each path's center frame keeps their relative layout (instead of each\n * glyph centering on its own bbox).\n */\n bounds: [number, number, number, number];\n}\n\n/**\n * A formula's glyph geometry, before a type size is applied to it.\n *\n * The dividing line this whole module's caching turns on. Getting here is the\n * expensive part — MathJax lays the formula out, then the SVG it produces is\n * parsed, its glyph dictionary resolved and every `<use>` walked through its\n * transform stack — and **none of it depends on `fontSize`**: `mjDoc.convert`\n * is called at a fixed em/ex, and the size arrives at the very end as one\n * uniform scale (see {@link scaleLatexGeometry}).\n *\n * So this is what gets remembered per formula, and the size is applied to it\n * afresh. A formula animating from 24pt to 120pt is one trip through MathJax\n * and one DOM parse, not one per frame.\n */\ninterface LatexGeometry {\n tokens: RawToken[];\n /** Box over every command, in the SVG's own coordinates. */\n box: { minX: number; minY: number; maxX: number; maxY: number };\n /** The formula's height in `ex`, as MathJax reported it. */\n heightEx: number;\n}\n\n/**\n * Formulas already worked out, and formulas already sized.\n *\n * `buildLatexPath` is a pure function of `(text, fontSize)` and used to have no\n * memory, which made every caller pay full price for a question it had already\n * asked. The callers are not occasional about it either: constructing a `Latex`\n * resolves its formula, and so does every `to({ latex })` the moment it starts,\n * so a scene re-resolves every formula in it whenever it is rebuilt *and*\n * whenever the playhead moves backwards, since a backward seek replays the\n * scene's generator from its first frame. An editor that rebuilds on a keystroke\n * and seeks on a click asks for the same handful of formulas hundreds of times.\n *\n * Two memos, each keyed by what its stage actually depends on, and deliberately\n * different sizes:\n *\n * - {@link geometryCache} is everything up to the type size, keyed by the text\n * alone. This is the expensive one, and it is generously sized because\n * nothing a scene does can churn it: a deck holds as many distinct formulas\n * as it holds, and it holds them for as long as it is open.\n * - {@link pathCache} is the finished result, keyed by text *and* size. Small\n * on purpose: an animated `fontSize` inserts a distinct key every frame, and\n * the right thing for a stream like that is to churn a little memo rather\n * than a big one. What a miss costs here is arithmetic over glyphs already\n * worked out — no MathJax, no parse.\n */\nconst geometryCache = createBoundedCache<LatexGeometry>(128);\nconst pathCache = createBoundedCache<LatexPathResult>(64);\n\nexport function buildLatexPath(text: string, fontSize: number): LatexPathResult {\n // NUL rather than a punctuation separator, so no formula can spell a key\n // belonging to another size.\n const key = `${fontSize}\\0${text}`;\n\n const hit = pathCache.get(key);\n if (hit) return lend(hit);\n\n let geometry = geometryCache.get(text);\n if (!geometry) {\n geometry = buildLatexGeometry(text);\n geometryCache.set(text, geometry);\n }\n\n const result = scaleLatexGeometry(geometry, fontSize);\n pathCache.set(key, result);\n return lend(result);\n}\n\n/** Typeset `text` and reduce the SVG MathJax returns to glyph geometry. */\nfunction buildLatexGeometry(text: string): LatexGeometry {\n const node = mjDoc.convert(text, {\n display: true,\n em: 16,\n ex: 8,\n containerWidth: 80 * 16,\n });\n\n const svgEl = adaptor.firstChild(node);\n const heightAttr = adaptor.getAttribute(svgEl, 'height') ?? '';\n\n return parseLatexSvg(svgEl, parseFloat(heightAttr) || 0);\n}\n\n/**\n * A cached result, handed out safely.\n *\n * `tokens`, `commands` and the path arrays inside them are shared: they are read\n * by everything downstream and written by none of it — `Latex` maps tokens into\n * its own wrappers, and the morph builds new paths rather than editing the ones\n * it is given — so copying them would be copying the whole formula for nothing.\n *\n * `bounds` is copied, because it is the one field a caller *stores*: `Latex`\n * assigns `result.bounds` straight to `this._bounds` and hands it to the\n * renderer as a shared centring frame. That was one node holding its own array\n * before there was a memo, and would be two nodes drawing the same formula\n * holding one array between them after — four numbers is not a price worth\n * paying to find out whether anything downstream ever writes to it.\n */\nfunction lend(result: LatexPathResult): LatexPathResult {\n const [minX, minY, maxX, maxY] = result.bounds;\n return { ...result, bounds: [minX, minY, maxX, maxY] };\n}\n\n// --- High-Speed Matrix Math ---\n\ntype Matrix = [number, number, number, number, number, number]; // [a, b, c, d, tx, ty]\nconst identityMatrix: Matrix = [1, 0, 0, 1, 0, 0];\n\nfunction multiplyMatrix(m1: Matrix, m2: Matrix): Matrix {\n return [\n m1[0] * m2[0] + m1[2] * m2[1],\n m1[1] * m2[0] + m1[3] * m2[1],\n m1[0] * m2[2] + m1[2] * m2[3],\n m1[1] * m2[2] + m1[3] * m2[3],\n m1[0] * m2[4] + m1[2] * m2[5] + m1[4],\n m1[1] * m2[4] + m1[3] * m2[5] + m1[5],\n ];\n}\n\nfunction parseTransform(str: string | null): Matrix {\n if (!str) return identityMatrix;\n let m: Matrix = [...identityMatrix];\n const re = /([a-z]+)\\(([^)]+)\\)/g;\n let match;\n while ((match = re.exec(str)) !== null) {\n const type = match[1];\n const args = match[2].split(/[ ,]+/).map(parseFloat);\n if (type === 'translate') {\n m = multiplyMatrix(m, [1, 0, 0, 1, args[0] || 0, args[1] || 0]);\n } else if (type === 'scale') {\n const sx = args[0] || 1;\n const sy = args[1] !== undefined ? args[1] : sx;\n m = multiplyMatrix(m, [sx, 0, 0, sy, 0, 0]);\n } else if (type === 'matrix') {\n m = multiplyMatrix(m, [args[0], args[1], args[2], args[3], args[4], args[5]]);\n }\n }\n return m;\n}\n\nfunction applyMatrix(x: number, y: number, m: Matrix): [number, number] {\n return [\n x * m[0] + y * m[2] + m[4],\n x * m[1] + y * m[3] + m[5],\n ];\n}\n\n// --- Glyph ID → character decoding ---\n\n/**\n * MathJax SVG glyph IDs look like \"MJX-1-TEX-N-78\" or \"MJX-1-TEX-I-1D465\".\n * The last segment is the Unicode codepoint in hex.\n */\nfunction glyphIdToChar(id: string): string {\n const parts = id.split('-');\n const hex = parts[parts.length - 1];\n const cp = parseInt(hex, 16);\n if (!isNaN(cp)) {\n try { return String.fromCodePoint(cp); } catch { /* fall through */ }\n }\n return id;\n}\n\n// --- Core Fast Traversal Engine ---\n\ntype RawToken = { token: string; cmds: Array<{ cmd: string; args: number[] }> };\n\n/** The tag name of a node's parent, or \"\" at the root. */\nfunction parentKind(node: unknown): string {\n const parent = adaptor.parent(node);\n return parent ? String(adaptor.kind(parent)).toLowerCase() : \"\";\n}\n\n/**\n * The size-independent half: MathJax's own SVG tree in, glyph geometry out.\n *\n * Walked through the **adaptor** rather than a `DOMParser`. MathJax already\n * builds this tree, and the adaptor is its own abstraction over \"a real DOM\" and\n * \"the DOM-free `LiteElement` tree\" — the two this module already picks between\n * at load. Serialising it to a string and parsing it back needed a `DOMParser`,\n * which Node does not have, so every LaTeX node threw `DOMParser is not defined`\n * and could not render headlessly at all: no export, and nothing the visual\n * suite could check.\n *\n * Reading the tree directly is also one representation instead of three (tree →\n * string → tree), so a browser and a headless host cannot disagree about how the\n * markup re-parsed.\n */\nfunction parseLatexSvg(svgEl: unknown, heightEx: number): LatexGeometry {\n // Pre-parse the glyph dictionary. `tags` reaches every <path> in the tree,\n // including the ones inside <defs> that the `use` elements reference.\n const glyphMap = new Map<string, Array<{ cmd: string; args: number[] }>>();\n for (const el of adaptor.tags(svgEl, 'path') as unknown[]) {\n const id = adaptor.getAttribute(el, 'id');\n const d = adaptor.getAttribute(el, 'd');\n if (id && d) {\n glyphMap.set(`#${id}`, expandToAbsolute(tokenisePath(d)));\n }\n }\n\n // Collect raw tokens — each <use> is one token, rects/paths are grouped as synthetic tokens\n const rawTokens: RawToken[] = [];\n let synthIdx = 0;\n\n function pushCmds(token: string, cmds: Array<{ cmd: string; args: number[] }>) {\n rawTokens.push({ token, cmds });\n }\n\n function traverse(node: unknown, currentMatrix: Matrix) {\n let nodeMatrix = currentMatrix;\n\n const transformStr = adaptor.getAttribute(node, \"transform\");\n if (transformStr) {\n nodeMatrix = multiplyMatrix(nodeMatrix, parseTransform(transformStr));\n }\n\n const nodeName = String(adaptor.kind(node)).toLowerCase();\n\n if (nodeName === \"use\") {\n const href = adaptor.getAttribute(node, \"href\") || adaptor.getAttribute(node, \"xlink:href\");\n const x = parseFloat(adaptor.getAttribute(node, \"x\") || \"0\");\n const y = parseFloat(adaptor.getAttribute(node, \"y\") || \"0\");\n\n if (href && glyphMap.has(href)) {\n const glyphCommands = glyphMap.get(href)!;\n const cmds: Array<{ cmd: string; args: number[] }> = [];\n for (const gc of glyphCommands) {\n const shiftedArgs = [...gc.args];\n for (let j = 0; j < shiftedArgs.length; j += 2) {\n const [nx, ny] = applyMatrix(shiftedArgs[j] + x, shiftedArgs[j + 1] + y, nodeMatrix);\n shiftedArgs[j] = nx;\n shiftedArgs[j + 1] = ny;\n }\n cmds.push({ cmd: gc.cmd, args: shiftedArgs });\n }\n // Derive character from glyph ID\n const rawId = href.startsWith('#') ? href.slice(1) : href;\n pushCmds(glyphIdToChar(rawId), cmds);\n }\n } else if (nodeName === \"rect\") {\n const x = parseFloat(adaptor.getAttribute(node, \"x\") || \"0\");\n const y = parseFloat(adaptor.getAttribute(node, \"y\") || \"0\");\n const w = parseFloat(adaptor.getAttribute(node, \"width\") || \"0\");\n const h = parseFloat(adaptor.getAttribute(node, \"height\") || \"0\");\n\n if (w > 0 && h > 0) {\n const pts = [[x, y], [x + w, y], [x + w, y + h], [x, y + h]];\n const tp = pts.map(p => applyMatrix(p[0], p[1], nodeMatrix));\n pushCmds(`__rect_${synthIdx++}`, [\n { cmd: 'M', args: [tp[0][0], tp[0][1]] },\n { cmd: 'L', args: [tp[1][0], tp[1][1]] },\n { cmd: 'L', args: [tp[2][0], tp[2][1]] },\n { cmd: 'L', args: [tp[3][0], tp[3][1]] },\n { cmd: 'Z', args: [] },\n ]);\n }\n } else if (nodeName === \"path\" && parentKind(node) !== \"defs\") {\n const d = adaptor.getAttribute(node, \"d\");\n if (d) {\n const abs = expandToAbsolute(tokenisePath(d));\n const cmds: Array<{ cmd: string; args: number[] }> = [];\n for (const gc of abs) {\n const shiftedArgs = [...gc.args];\n for (let j = 0; j < shiftedArgs.length; j += 2) {\n const [nx, ny] = applyMatrix(shiftedArgs[j], shiftedArgs[j + 1], nodeMatrix);\n shiftedArgs[j] = nx;\n shiftedArgs[j + 1] = ny;\n }\n cmds.push({ cmd: gc.cmd, args: shiftedArgs });\n }\n pushCmds(`__path_${synthIdx++}`, cmds);\n }\n }\n\n for (const child of adaptor.childNodes(node) as unknown[]) {\n // A text node's kind is \"#text\"; only elements carry geometry, and\n // <defs> holds the dictionary rather than anything drawn.\n const kind = String(adaptor.kind(child)).toLowerCase();\n if (kind.startsWith(\"#\") || kind === \"defs\") continue;\n traverse(child, nodeMatrix);\n }\n }\n\n traverse(svgEl, identityMatrix);\n\n // Bounding box across all raw commands, in the SVG's own coordinates.\n const box = svgBBox(rawTokens.flatMap(t => t.cmds));\n return { tokens: rawTokens, box, heightEx };\n}\n\n/**\n * The size-dependent half: glyph geometry in, a laid-out formula out.\n *\n * Everything here is one uniform scale about the geometry's own centre, which\n * is exactly why {@link LatexGeometry} is worth remembering on its own.\n */\nfunction scaleLatexGeometry(geometry: LatexGeometry, fontSize: number): LatexPathResult {\n const { tokens: rawTokens, box, heightEx } = geometry;\n if (rawTokens.length === 0) return { tokens: [], commands: [], width: 0, height: 0, bounds: [0, 0, 0, 0] };\n\n const { minX, minY, maxX, maxY } = box;\n const svgW = maxX - minX;\n const svgH = maxY - minY;\n\n let scale: number;\n if (heightEx > 0 && svgH > 0) {\n const exInCoords = svgH / heightEx;\n scale = fontSize / (2 * exInCoords);\n } else {\n scale = svgH > 0 ? fontSize / svgH : 1;\n }\n\n const ocx = (minX + maxX) / 2;\n const ocy = (minY + maxY) / 2;\n\n const tx = (svgX: number) => (svgX - ocx) * scale;\n const ty = (svgY: number) => (svgY - ocy) * scale;\n\n function rawCmdsToPathCommands(cmds: Array<{ cmd: string; args: number[] }>): PathCommand[] {\n const out: PathCommand[] = [];\n for (const { cmd, args: a } of cmds) {\n switch (cmd) {\n case 'M': out.push({ type: 'M', x: tx(a[0]), y: ty(a[1]) }); break;\n case 'L': out.push({ type: 'L', x: tx(a[0]), y: ty(a[1]) }); break;\n case 'Q': out.push({ type: 'Q', x1: tx(a[0]), y1: ty(a[1]), x: tx(a[2]), y: ty(a[3]) }); break;\n case 'C': out.push({ type: 'C', x1: tx(a[0]), y1: ty(a[1]), x2: tx(a[2]), y2: ty(a[3]), x: tx(a[4]), y: ty(a[5]) }); break;\n case 'Z': out.push({ type: 'Z' }); break;\n }\n }\n return out;\n }\n\n const tokens: LatexToken[] = rawTokens.map(rt => ({\n token: rt.token,\n path: rawCmdsToPathCommands(rt.cmds),\n }));\n\n const commands = tokens.flatMap(t => t.path);\n\n // Shared center frame for all tokens, in token coordinate space. tx/ty map\n // the SVG bbox corners; this is the frame every token's path is laid out in.\n const bounds: [number, number, number, number] = [\n tx(minX), ty(minY), tx(maxX), ty(maxY),\n ];\n\n return { tokens, commands, width: svgW * scale, height: svgH * scale, bounds };\n}\n\n// --- SVG Path Utilities ---\n\ntype RawCmd = { cmd: string; args: number[] };\n\nfunction tokenisePath(d: string): RawCmd[] {\n const re = /([MmLlHhVvCcSsQqTtAaZz])|([+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?)/g;\n const out: RawCmd[] = [];\n let cur: RawCmd | null = null;\n let m: RegExpExecArray | null;\n while ((m = re.exec(d)) !== null) {\n if (m[1]) { cur = { cmd: m[1], args: [] }; out.push(cur); }\n else if (cur) cur.args.push(parseFloat(m[2]));\n }\n return out;\n}\n\nfunction argCount(cmd: string): number {\n switch (cmd.toUpperCase()) {\n case 'M': return 2; case 'L': return 2; case 'H': return 1; case 'V': return 1;\n case 'C': return 6; case 'S': return 4; case 'Q': return 4; case 'T': return 2;\n case 'A': return 7; case 'Z': return 0; default: return 0;\n }\n}\n\ninterface Pt { x: number; y: number }\n\nfunction expandToAbsolute(raw: RawCmd[]): Array<{ cmd: string; args: number[] }> {\n const out: Array<{ cmd: string; args: number[] }> = [];\n let cx = 0, cy = 0;\n let mx = 0, my = 0;\n let prevCmd = '';\n let prevCtrl: Pt = { x: 0, y: 0 };\n\n for (const { cmd, args } of raw) {\n const up = cmd.toUpperCase();\n const rel = cmd === cmd.toLowerCase() && up !== 'Z';\n const n = argCount(up);\n const reps = n === 0 ? 1 : Math.max(1, Math.ceil(args.length / n));\n\n for (let r = 0; r < reps; r++) {\n const a = args.slice(r * n, r * n + n);\n const absX = (i: number) => rel ? a[i] + cx : a[i];\n const absY = (i: number) => rel ? a[i] + cy : a[i];\n\n switch (up) {\n case 'M': {\n const x = absX(0), y = absY(1);\n const emitCmd = r === 0 ? 'M' : 'L';\n out.push({ cmd: emitCmd, args: [x, y] });\n cx = x; cy = y;\n if (r === 0) { mx = x; my = y; }\n prevCmd = emitCmd;\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'Z':\n out.push({ cmd: 'Z', args: [] });\n cx = mx; cy = my;\n prevCmd = 'Z';\n break;\n case 'L': {\n const x = absX(0), y = absY(1);\n out.push({ cmd: 'L', args: [x, y] });\n cx = x; cy = y;\n prevCmd = 'L';\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'H': {\n const x = rel ? a[0] + cx : a[0];\n out.push({ cmd: 'L', args: [x, cy] });\n cx = x;\n prevCmd = 'L';\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'V': {\n const y = rel ? a[0] + cy : a[0];\n out.push({ cmd: 'L', args: [cx, y] });\n cy = y;\n prevCmd = 'L';\n prevCtrl = { x: cx, y: cy };\n break;\n }\n case 'C': {\n const x1 = absX(0), y1 = absY(1);\n const x2 = absX(2), y2 = absY(3);\n const x = absX(4), y = absY(5);\n out.push({ cmd: 'C', args: [x1, y1, x2, y2, x, y] });\n prevCtrl = { x: x2, y: y2 };\n cx = x; cy = y;\n prevCmd = 'C';\n break;\n }\n case 'S': {\n const x1 = prevCmd === 'C' || prevCmd === 'S' ? 2 * cx - prevCtrl.x : cx;\n const y1 = prevCmd === 'C' || prevCmd === 'S' ? 2 * cy - prevCtrl.y : cy;\n const x2 = absX(0), y2 = absY(1);\n const x = absX(2), y = absY(3);\n out.push({ cmd: 'C', args: [x1, y1, x2, y2, x, y] });\n prevCtrl = { x: x2, y: y2 };\n cx = x; cy = y;\n prevCmd = 'S';\n break;\n }\n case 'Q': {\n const x1 = absX(0), y1 = absY(1);\n const x = absX(2), y = absY(3);\n out.push({ cmd: 'Q', args: [x1, y1, x, y] });\n prevCtrl = { x: x1, y: y1 };\n cx = x; cy = y;\n prevCmd = 'Q';\n break;\n }\n case 'T': {\n const x1 = prevCmd === 'Q' || prevCmd === 'T' ? 2 * cx - prevCtrl.x : cx;\n const y1 = prevCmd === 'Q' || prevCmd === 'T' ? 2 * cy - prevCtrl.y : cy;\n const x = absX(0), y = absY(1);\n out.push({ cmd: 'Q', args: [x1, y1, x, y] });\n prevCtrl = { x: x1, y: y1 };\n cx = x; cy = y;\n prevCmd = 'T';\n break;\n }\n }\n }\n }\n\n if (out.length > 0 && out[out.length - 1].cmd !== 'Z') {\n out.push({ cmd: 'Z', args: [] });\n }\n\n return out;\n}\n\nfunction svgBBox(abs: Array<{ cmd: string; args: number[] }>): { minX: number; minY: number; maxX: number; maxY: number } {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n const touch = (x: number, y: number) => {\n if (x < minX) minX = x; if (x > maxX) maxX = x;\n if (y < minY) minY = y; if (y > maxY) maxY = y;\n };\n for (const { cmd, args } of abs) {\n switch (cmd) {\n case 'M': case 'L': touch(args[0], args[1]); break;\n case 'C': touch(args[0], args[1]); touch(args[2], args[3]); touch(args[4], args[5]); break;\n case 'Q': touch(args[0], args[1]); touch(args[2], args[3]); break;\n }\n }\n return { minX, minY, maxX, maxY };\n}\n"]}
|
package/dist/node.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RenderContext2D, EasingFunction, NodeConfig, ShapeNode, ShapeProps, InsetsProps, Size2D, SizeConstraints, InsetsResolved, type Command, type CommandArgs } from "@motionscript/
|
|
1
|
+
import { RenderContext2D, EasingFunction, NodeConfig, ShapeNode, ShapeProps, InsetsProps, Size2D, SizeConstraints, InsetsResolved, type Command, type CommandArgs } from "@motionscript/sdk";
|
|
2
2
|
import { type LatexMorphStrategy } from "./engine.js";
|
|
3
3
|
export interface LatexProps extends ShapeProps {
|
|
4
4
|
latex: string;
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAc,cAAc,EAA6B,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAgB,cAAc,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAc,cAAc,EAA6B,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAgB,cAAc,EAAwE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,mBAAmB,CAAC;AAC3U,OAAO,EAAyD,KAAK,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAE3H,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC5B,iFAAiF;IACjF,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC9B;AAED,qBA0Ba,KAAM,SAAQ,SAAS,CAAC,UAAU,CAAC;IAC5C,SAA4C,KAAK,EAAE,MAAM,CAAC;IAC1D,SAA4C,QAAQ,EAAE,MAAM,CAAC;IAC7D,SAAmC,OAAO,EAAE,cAAc,CAAC;IAE3D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAE3C,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,gBAAgB,CAAa;IAErC;;;;OAIG;IACH,OAAO,CAAC,OAAO,CAAkD;IAEjE,gFAAgF;IAChF,OAAO,CAAC,OAAO,CAAuB;IAEtC,uEAAuE;IACvE,OAAO,CAAC,UAAU,CAAkB;IAEpC,uFAAuF;IACvF,OAAO,CAAC,cAAc,CAAuB;gBAEjC,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,eAAe;IASlE;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,aAAa;IAqBZ,OAAO,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB/D;;;;;;;OAOG;IACM,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAIlI;;;OAGG;IAEH,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAIzF;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,WAAW,CAAC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IA0EpG;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAOhD;;;;;;;;;;;;;;;;;;;;OAoBG;cACgB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAM5D;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;CAyBpB"}
|
package/dist/node.js
CHANGED
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { Graphics2D, command, node, lerpNumber, ShapeNode, toPathString, property,
|
|
7
|
+
import { Graphics2D, command, node, lerpNumber, ShapeNode, toPathString, property, insetsProperty, driveCommand } from "@motionscript/sdk";
|
|
8
8
|
import { buildLatexPath, defaultLatexMorph } from "./engine.js";
|
|
9
9
|
let Latex = class Latex extends ShapeNode {
|
|
10
10
|
/**
|
|
@@ -288,7 +288,7 @@ __decorate([
|
|
|
288
288
|
property({ default: 16 })
|
|
289
289
|
], Latex.prototype, "fontSize", void 0);
|
|
290
290
|
__decorate([
|
|
291
|
-
|
|
291
|
+
insetsProperty()
|
|
292
292
|
], Latex.prototype, "padding", void 0);
|
|
293
293
|
__decorate([
|
|
294
294
|
command({ args: [{ key: "latex", kind: "text", multiline: true }] })
|
package/dist/node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["import { RenderContext2D, Graphics2D, EasingFunction, command, node, lerpNumber, NodeConfig, ShapeNode, ShapeProps, InsetsProps, Size2D, SizeConstraints, toPathString, InsetsResolved, property, insetsOps, FillResolved, ShadowResolved, driveCommand, type Command, type CommandArgs, type TweenStepper } from \"@motionscript/core\";\nimport { buildLatexPath, defaultLatexMorph, type AnimatedToken, type LatexMorphStrategy, type LatexToken } from \"./engine\";\n\nexport interface LatexProps extends ShapeProps {\n latex: string;\n fontSize: number;\n padding: InsetsProps;\n}\n\n/**\n * Construction-time-only options: pluggable engine behavior, set once when\n * the node is created. Deliberately *not* part of {@link LatexProps} — every\n * `@property` field accepts either a value or a zero-arg reactive binding\n * (`value | (() => value)`, see `PropInputs`), and the node's own reactive\n * write path (`_writeProp`) treats any function value as the latter. A\n * strategy *is* a function, so it can't be told apart from a binding that\n * computes one — it has to stay outside the reactive prop system entirely.\n */\nexport interface LatexStrategies {\n /** How the node morphs between two formulas. Defaults to `defaultLatexMorph`. */\n morph?: LatexMorphStrategy;\n}\n\n@node({\n key: \"latex\",\n parentKey: \"shape\",\n forkable: true,\n layout: {\n children: \"freeform\",\n defaultWidthMode: \"hug\",\n defaultHeightMode: \"hug\",\n acceptsChildren: true,\n },\n seed: {\n fill: [\n {\n type: \"solid\",\n color: [\n 0.412,\n 0.565,\n 0.867,\n 1,\n ],\n opacity: 1,\n enabled: true,\n },\n ],\n },\n})\nexport class Latex extends ShapeNode<LatexProps> {\n @property({ default: \"\" }) declare readonly latex: string;\n @property({ default: 16 }) declare readonly fontSize: number;\n @property({ default: 0, mapper: insetsOps.resolve, tween: insetsOps.lerp }) declare readonly padding: InsetsResolved;\n\n /**\n * How this node morphs between two formulas. Construction-time-only (see\n * {@link LatexStrategies}) — resolved once here rather than left as\n * `?? defaultLatexMorph` at every call site.\n */\n private readonly morph: LatexMorphStrategy;\n\n private _intrinsicWidth: number = 0;\n private _intrinsicHeight: number = 0;\n\n /**\n * Shared center frame for all current tokens, [minX, minY, maxX, maxY] in\n * token space. Passed to every per-token path so glyphs keep their relative\n * layout instead of each centering on its own bbox.\n */\n private _bounds: [number, number, number, number] = [0, 0, 0, 0];\n\n /** Current tokens to render. Each has its own opacity for tween transitions. */\n private _tokens: AnimatedToken[] = [];\n\n /** Suppresses retokenization while a custom to() is driving frames. */\n private _animating: boolean = false;\n\n /** The `fontSize|latex` the live tokens were built from. See {@link _ensureTokens}. */\n private _tokenizedFrom: string | null = null;\n\n constructor(props: NodeConfig<Latex, LatexProps> & LatexStrategies) {\n super(props);\n this.morph = props.morph ?? defaultLatexMorph;\n this.applyProp(\"width\", props.width ?? \"hug\");\n this.applyProp(\"height\", props.height ?? \"hug\");\n\n this._ensureTokens();\n }\n\n /**\n * Rebuild the token list when the formula or size has moved since it last\n * was built.\n *\n * Pulled from every reader rather than pushed from a prop write, because\n * `latex` can be a binding — and a binding has no write to hang a\n * subscription on. The key is what the current tokens were built from;\n * `_animating` hands ownership to the morph command for its open interval.\n */\n private _ensureTokens(): void {\n if (this._animating) return;\n const key = `${this.fontSize}|${this.latex}`;\n if (key === this._tokenizedFrom) return;\n this._tokenizedFrom = key;\n this._updateTokens();\n }\n\n private _updateTokens() {\n if (this.latex) {\n const result = buildLatexPath(this.latex, this.fontSize);\n this._intrinsicWidth = result.width;\n this._intrinsicHeight = result.height;\n this._bounds = result.bounds;\n this._tokens = result.tokens.map(t => ({\n token: t.token,\n path: t.path,\n opacity: 1,\n x: 0,\n y: 0,\n }));\n } else {\n this._tokens = [];\n this._intrinsicWidth = 0;\n this._intrinsicHeight = 0;\n this._bounds = [0, 0, 0, 0];\n }\n }\n\n override measure(constraints: SizeConstraints): Partial<Size2D> {\n this._ensureTokens();\n const pad = this.padding;\n const wm = this.width;\n const hm = this.height;\n\n const resolvedW = typeof wm === \"number\"\n ? wm\n : wm === \"hug\"\n ? this._intrinsicWidth + pad.left + pad.right\n : constraints.maxWidth ?? 0;\n\n const resolvedH = typeof hm === \"number\"\n ? hm\n : hm === \"hug\"\n ? this._intrinsicHeight + pad.top + pad.bottom\n : constraints.maxHeight ?? 0;\n\n return { width: resolvedW, height: resolvedH };\n }\n\n /**\n * A LaTeX morph — one {@link Command}, like every other `to()`.\n *\n * Sequence two of them with `sequence(...)` rather than chaining: the chain\n * builder this used to return existed only so `latexRef().to(a, 1).to(b, 1)`\n * would read as two steps, and it could not compose with anything that was\n * not another Latex morph.\n */\n override to<D extends Partial<LatexProps> = Partial<LatexProps>>(args: CommandArgs<D> & { duration: number }): Command<LatexProps> {\n return this._buildMorph(args.data ?? {}, args.duration, args.easing);\n }\n\n /**\n * Morph this formula into another — a document-facing name for {@link to},\n * which already routes through {@link _buildMorph}.\n */\n @command({ args: [{ key: \"latex\", kind: \"text\", multiline: true }] })\n morphTo(args: CommandArgs<{ latex: string }> & { duration: number }): Command<LatexProps> {\n return this.to({ data: { latex: args.data?.latex } as Partial<LatexProps>, duration: args.duration, easing: args.easing });\n }\n\n /**\n * Build a single LaTeX morph as a {@link Command}: every ordinary\n * `ShapeProps` field (via the inherited `_prepareStep`), plus the\n * intrinsic size, shared center frame and per-glyph token list — state a\n * plain `set()` can't reach — driven together by one eased `t`, matching\n * the concurrent `parallel` the generator version ran.\n *\n * The \"from\" snapshot (`fromTokens`, `fromLatex`, …) is captured\n * **lazily, on the command's first evaluation**, not when this is called.\n * That is what lets two morphs be sequenced: `commandSequence` settles each\n * prior step before evaluating the next, so a second morph's \"from\" reads\n * the first one's end state rather than whatever the node held before either\n * of them ran.\n *\n * `_animating` suppresses {@link _ensureTokens} for the open interval, and\n * both ends commit: `t === 1`\n * lands on the target formula, `t === 0` restores the source one — the same\n * \"membership for the open interval, commit at either end\" shape\n * `packages/components/code`'s `runTransition` uses, so seeking into either\n * side of the morph (not just running it forward) shows the right thing.\n *\n * `@internal` — the entry point for authors is {@link to}.\n */\n _buildMorph(to: Partial<LatexProps>, duration: number, easing?: EasingFunction): Command<LatexProps> {\n let setupDone = false;\n let fromAnimTokens: AnimatedToken[] = [];\n let fromLatex = \"\";\n let fromFontSize = 0;\n let fromWidth = 0;\n let fromHeight = 0;\n let fromBounds: [number, number, number, number] = [0, 0, 0, 0];\n let toFontSize = 0;\n let toLatex = \"\";\n let toResult: ReturnType<typeof buildLatexPath>;\n let propStep: TweenStepper;\n let latexFrame: (t: number) => AnimatedToken[];\n\n const setup = (): void => {\n setupDone = true;\n this._ensureTokens();\n const fromTokens: LatexToken[] = this._tokens.map(t => ({ token: t.token, path: t.path }));\n fromAnimTokens = this._tokens.map(t => ({ ...t }));\n fromLatex = this.latex;\n fromFontSize = this.fontSize;\n fromWidth = this._intrinsicWidth;\n fromHeight = this._intrinsicHeight;\n fromBounds = this._bounds;\n\n toFontSize = to.fontSize !== undefined ? to.fontSize : this.fontSize;\n toLatex = to.latex !== undefined ? to.latex : this.latex;\n toResult = buildLatexPath(toLatex, toFontSize);\n\n propStep = this._prepareStep(to, duration);\n latexFrame = this.morph(fromTokens, toResult.tokens);\n };\n\n return driveCommand(duration, (t) => {\n if (!setupDone) setup();\n const toBounds = toResult.bounds;\n\n this._animating = true;\n propStep.seek(t * duration);\n this.set({ fontSize: lerpNumber(fromFontSize, toFontSize, t) });\n // Track the measured size so a hugging box grows/shrinks smoothly\n // across the morph rather than jumping when the end commits.\n this._intrinsicWidth = lerpNumber(fromWidth, toResult.width, t);\n this._intrinsicHeight = lerpNumber(fromHeight, toResult.height, t);\n // Interpolate the shared center frame in lockstep so glyphs stay\n // centered within the resizing box.\n this._bounds = [\n lerpNumber(fromBounds[0], toBounds[0], t),\n lerpNumber(fromBounds[1], toBounds[1], t),\n lerpNumber(fromBounds[2], toBounds[2], t),\n lerpNumber(fromBounds[3], toBounds[3], t),\n ];\n this._tokens = latexFrame(t);\n\n if (t >= 1) {\n this.set({ latex: toLatex, fontSize: toFontSize });\n this._tokens = toResult.tokens.map(tok => ({ token: tok.token, path: tok.path, opacity: 1, x: 0, y: 0 }));\n this._intrinsicWidth = toResult.width;\n this._intrinsicHeight = toResult.height;\n this._bounds = toResult.bounds;\n this._animating = false;\n this._tokenizedFrom = `${toFontSize}|${toLatex}`;\n } else if (t <= 0) {\n this.set({ latex: fromLatex, fontSize: fromFontSize });\n this._tokens = fromAnimTokens;\n this._intrinsicWidth = fromWidth;\n this._intrinsicHeight = fromHeight;\n this._bounds = fromBounds;\n this._animating = false;\n this._tokenizedFrom = `${fromFontSize}|${fromLatex}`;\n }\n }, easing) as Command<LatexProps>;\n }\n\n /**\n * The shadow op comes **first**, as it does on every other painted node.\n *\n * The renderer does not draw a shadow when it sees one: `.shadow()` stores\n * it pending and the *next* fill or stroke op casts it (`_shadow` →\n * `storePendingShadows`, `_fill`/`_stroke` → `takePendingShadows`). Appended\n * last, it was stored by every token and then thrown away by the reset at\n * the end of the draw — a shadow set on a LaTeX node simply never appeared,\n * with no error to say why. Same failure {@link PaintedNode.renderStroke}\n * documents for a fill-less stroked shape, and the same one-op fix.\n *\n * Order also carries the fill-less case for free: an empty fill returns\n * before it takes the pending shadow, so the stroke below casts it from the\n * glyph outlines instead — which is what `castsShadowFromStroke` arranges on\n * a plain shape.\n */\n protected renderSelf(ctx: RenderContext2D): void {\n this.eachToken(ctx, (graphics, opacity) => graphics\n .shadow(scaleShadowOpacity(this.shadow as ShadowResolved[], opacity))\n .fill(scaleFillopacity(this.fill as FillResolved[], opacity))\n .stroke(this.stroke));\n }\n\n /**\n * The overlay, painted *through* the glyphs.\n *\n * `ShapeNode`'s inherited overlay pass fills whatever {@link\n * ShapeNode.shapeGraphics} describes, and this node describes nothing there:\n * a formula has no single fillable silhouette — its silhouette *is* the list\n * of token paths, which is why `renderSelf` is overridden rather than a\n * `shapeGraphics` supplied. So the generic pass drew nothing and an overlay\n * set on a LaTeX node simply never appeared, with no error to say why.\n *\n * Painted the same way the fill is: one `Graphics2D` per token, all sharing the\n * centre frame, each scaled by its token's animated opacity — so a morph\n * carries the overlay along with the glyph it is laid over instead of leaving\n * a wash hanging over glyphs that have faded out.\n *\n * The stroke is *not* re-drawn here. `renderSelf` already strokes each token\n * (there is no silhouette for the deferred {@link ShapeNode.renderStroke} to\n * outline), so it is painted under the overlay rather than over it — the one\n * place this node's draw order differs from a plain shape's, and the price of\n * a stroke that follows glyphs rather than a box.\n */\n protected override renderOverlay(ctx: RenderContext2D): void {\n const overlay = this.overlay as FillResolved[];\n if (overlay.length === 0) return;\n this.eachToken(ctx, (graphics, opacity) => graphics.fill(scaleFillopacity(overlay, opacity)));\n }\n\n /**\n * Draws every visible token's path once, handing each one to `paint` to have\n * its paint ops appended.\n *\n * A fresh `Graphics2D` per token per pass, because `.fill()`/`.stroke()` push\n * onto one op list and return `this` — a silhouette shared between the fill\n * pass and the overlay pass would accumulate both.\n */\n private eachToken(ctx: RenderContext2D, paint: (graphics: Graphics2D, opacity: number) => Graphics2D): void {\n // The one funnel every paint pass goes through, so the tokens a frame\n // draws cannot be older than the formula it holds.\n this._ensureTokens();\n for (const token of this._tokens) {\n if (token.opacity <= 0) continue;\n\n // Translate the path by token's interpolated position offset\n const pathStr = token.x !== 0 || token.y !== 0\n ? toPathString(offsetPath(token.path, token.x, token.y))\n : toPathString(token.path);\n\n ctx.draw(paint(new Graphics2D()\n .path({\n data: pathStr,\n start: this.start,\n end: this.end,\n // All tokens share one center frame so they keep their relative\n // layout — without this each glyph centers on its own bbox and\n // they all stack on the origin.\n centerBounds: this._bounds,\n }), token.opacity));\n }\n }\n\n}\n\nfunction scaleFillopacity(fills: FillResolved[], opacity: number): FillResolved[] {\n if (opacity >= 1) return fills;\n return fills.map(f => ({ ...f, opacity: (f.opacity ?? 1) * opacity }));\n}\n\n/**\n * A morphing token fades, and its shadow has to fade with it — the paints are\n * scaled the same way the fill's are, so a half-faded glyph casts a half-strength\n * shadow rather than sitting over a shadow at full weight.\n */\nfunction scaleShadowOpacity(shadows: ShadowResolved[], opacity: number): ShadowResolved[] {\n if (opacity >= 1) return shadows;\n return shadows.map(s => ({ ...s, fill: scaleFillopacity(s.fill, opacity) }));\n}\n\nfunction offsetPath(\n path: LatexToken[\"path\"],\n dx: number,\n dy: number,\n): LatexToken[\"path\"] {\n return path.map(cmd => {\n const c = cmd as any;\n const shifted: any = { ...c };\n if (\"x\" in c) shifted.x = c.x + dx;\n if (\"y\" in c) shifted.y = c.y + dy;\n if (\"x1\" in c) { shifted.x1 = c.x1 + dx; shifted.y1 = c.y1 + dy; }\n if (\"x2\" in c) { shifted.x2 = c.x2 + dx; shifted.y2 = c.y2 + dy; }\n return shifted;\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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","sourcesContent":["import { RenderContext2D, Graphics2D, EasingFunction, command, node, lerpNumber, NodeConfig, ShapeNode, ShapeProps, InsetsProps, Size2D, SizeConstraints, toPathString, InsetsResolved, property, insetsProperty, FillResolved, ShadowResolved, driveCommand, type Command, type CommandArgs, type TweenStepper } from \"@motionscript/sdk\";\nimport { buildLatexPath, defaultLatexMorph, type AnimatedToken, type LatexMorphStrategy, type LatexToken } from \"./engine\";\n\nexport interface LatexProps extends ShapeProps {\n latex: string;\n fontSize: number;\n padding: InsetsProps;\n}\n\n/**\n * Construction-time-only options: pluggable engine behavior, set once when\n * the node is created. Deliberately *not* part of {@link LatexProps} — every\n * `@property` field accepts either a value or a zero-arg reactive binding\n * (`value | (() => value)`, see `PropInputs`), and the node's own reactive\n * write path (`_writeProp`) treats any function value as the latter. A\n * strategy *is* a function, so it can't be told apart from a binding that\n * computes one — it has to stay outside the reactive prop system entirely.\n */\nexport interface LatexStrategies {\n /** How the node morphs between two formulas. Defaults to `defaultLatexMorph`. */\n morph?: LatexMorphStrategy;\n}\n\n@node({\n key: \"latex\",\n parentKey: \"shape\",\n forkable: true,\n layout: {\n children: \"freeform\",\n defaultWidthMode: \"hug\",\n defaultHeightMode: \"hug\",\n acceptsChildren: true,\n },\n seed: {\n fill: [\n {\n type: \"solid\",\n color: [\n 0.412,\n 0.565,\n 0.867,\n 1,\n ],\n opacity: 1,\n enabled: true,\n },\n ],\n },\n})\nexport class Latex extends ShapeNode<LatexProps> {\n @property({ default: \"\" }) declare readonly latex: string;\n @property({ default: 16 }) declare readonly fontSize: number;\n @insetsProperty() declare readonly padding: InsetsResolved;\n\n /**\n * How this node morphs between two formulas. Construction-time-only (see\n * {@link LatexStrategies}) — resolved once here rather than left as\n * `?? defaultLatexMorph` at every call site.\n */\n private readonly morph: LatexMorphStrategy;\n\n private _intrinsicWidth: number = 0;\n private _intrinsicHeight: number = 0;\n\n /**\n * Shared center frame for all current tokens, [minX, minY, maxX, maxY] in\n * token space. Passed to every per-token path so glyphs keep their relative\n * layout instead of each centering on its own bbox.\n */\n private _bounds: [number, number, number, number] = [0, 0, 0, 0];\n\n /** Current tokens to render. Each has its own opacity for tween transitions. */\n private _tokens: AnimatedToken[] = [];\n\n /** Suppresses retokenization while a custom to() is driving frames. */\n private _animating: boolean = false;\n\n /** The `fontSize|latex` the live tokens were built from. See {@link _ensureTokens}. */\n private _tokenizedFrom: string | null = null;\n\n constructor(props: NodeConfig<Latex, LatexProps> & LatexStrategies) {\n super(props);\n this.morph = props.morph ?? defaultLatexMorph;\n this.applyProp(\"width\", props.width ?? \"hug\");\n this.applyProp(\"height\", props.height ?? \"hug\");\n\n this._ensureTokens();\n }\n\n /**\n * Rebuild the token list when the formula or size has moved since it last\n * was built.\n *\n * Pulled from every reader rather than pushed from a prop write, because\n * `latex` can be a binding — and a binding has no write to hang a\n * subscription on. The key is what the current tokens were built from;\n * `_animating` hands ownership to the morph command for its open interval.\n */\n private _ensureTokens(): void {\n if (this._animating) return;\n const key = `${this.fontSize}|${this.latex}`;\n if (key === this._tokenizedFrom) return;\n this._tokenizedFrom = key;\n this._updateTokens();\n }\n\n private _updateTokens() {\n if (this.latex) {\n const result = buildLatexPath(this.latex, this.fontSize);\n this._intrinsicWidth = result.width;\n this._intrinsicHeight = result.height;\n this._bounds = result.bounds;\n this._tokens = result.tokens.map(t => ({\n token: t.token,\n path: t.path,\n opacity: 1,\n x: 0,\n y: 0,\n }));\n } else {\n this._tokens = [];\n this._intrinsicWidth = 0;\n this._intrinsicHeight = 0;\n this._bounds = [0, 0, 0, 0];\n }\n }\n\n override measure(constraints: SizeConstraints): Partial<Size2D> {\n this._ensureTokens();\n const pad = this.padding;\n const wm = this.width;\n const hm = this.height;\n\n const resolvedW = typeof wm === \"number\"\n ? wm\n : wm === \"hug\"\n ? this._intrinsicWidth + pad.left + pad.right\n : constraints.maxWidth ?? 0;\n\n const resolvedH = typeof hm === \"number\"\n ? hm\n : hm === \"hug\"\n ? this._intrinsicHeight + pad.top + pad.bottom\n : constraints.maxHeight ?? 0;\n\n return { width: resolvedW, height: resolvedH };\n }\n\n /**\n * A LaTeX morph — one {@link Command}, like every other `to()`.\n *\n * Sequence two of them with `sequence(...)` rather than chaining: the chain\n * builder this used to return existed only so `latexRef().to(a, 1).to(b, 1)`\n * would read as two steps, and it could not compose with anything that was\n * not another Latex morph.\n */\n override to<D extends Partial<LatexProps> = Partial<LatexProps>>(args: CommandArgs<D> & { duration: number }): Command<LatexProps> {\n return this._buildMorph(args.data ?? {}, args.duration, args.easing);\n }\n\n /**\n * Morph this formula into another — a document-facing name for {@link to},\n * which already routes through {@link _buildMorph}.\n */\n @command({ args: [{ key: \"latex\", kind: \"text\", multiline: true }] })\n morphTo(args: CommandArgs<{ latex: string }> & { duration: number }): Command<LatexProps> {\n return this.to({ data: { latex: args.data?.latex } as Partial<LatexProps>, duration: args.duration, easing: args.easing });\n }\n\n /**\n * Build a single LaTeX morph as a {@link Command}: every ordinary\n * `ShapeProps` field (via the inherited `_prepareStep`), plus the\n * intrinsic size, shared center frame and per-glyph token list — state a\n * plain `set()` can't reach — driven together by one eased `t`, matching\n * the concurrent `parallel` the generator version ran.\n *\n * The \"from\" snapshot (`fromTokens`, `fromLatex`, …) is captured\n * **lazily, on the command's first evaluation**, not when this is called.\n * That is what lets two morphs be sequenced: `commandSequence` settles each\n * prior step before evaluating the next, so a second morph's \"from\" reads\n * the first one's end state rather than whatever the node held before either\n * of them ran.\n *\n * `_animating` suppresses {@link _ensureTokens} for the open interval, and\n * both ends commit: `t === 1`\n * lands on the target formula, `t === 0` restores the source one — the same\n * \"membership for the open interval, commit at either end\" shape\n * `packages/components/code`'s `runTransition` uses, so seeking into either\n * side of the morph (not just running it forward) shows the right thing.\n *\n * `@internal` — the entry point for authors is {@link to}.\n */\n _buildMorph(to: Partial<LatexProps>, duration: number, easing?: EasingFunction): Command<LatexProps> {\n let setupDone = false;\n let fromAnimTokens: AnimatedToken[] = [];\n let fromLatex = \"\";\n let fromFontSize = 0;\n let fromWidth = 0;\n let fromHeight = 0;\n let fromBounds: [number, number, number, number] = [0, 0, 0, 0];\n let toFontSize = 0;\n let toLatex = \"\";\n let toResult: ReturnType<typeof buildLatexPath>;\n let propStep: TweenStepper;\n let latexFrame: (t: number) => AnimatedToken[];\n\n const setup = (): void => {\n setupDone = true;\n this._ensureTokens();\n const fromTokens: LatexToken[] = this._tokens.map(t => ({ token: t.token, path: t.path }));\n fromAnimTokens = this._tokens.map(t => ({ ...t }));\n fromLatex = this.latex;\n fromFontSize = this.fontSize;\n fromWidth = this._intrinsicWidth;\n fromHeight = this._intrinsicHeight;\n fromBounds = this._bounds;\n\n toFontSize = to.fontSize !== undefined ? to.fontSize : this.fontSize;\n toLatex = to.latex !== undefined ? to.latex : this.latex;\n toResult = buildLatexPath(toLatex, toFontSize);\n\n propStep = this._prepareStep(to, duration);\n latexFrame = this.morph(fromTokens, toResult.tokens);\n };\n\n return driveCommand(duration, (t) => {\n if (!setupDone) setup();\n const toBounds = toResult.bounds;\n\n this._animating = true;\n propStep.seek(t * duration);\n this.set({ fontSize: lerpNumber(fromFontSize, toFontSize, t) });\n // Track the measured size so a hugging box grows/shrinks smoothly\n // across the morph rather than jumping when the end commits.\n this._intrinsicWidth = lerpNumber(fromWidth, toResult.width, t);\n this._intrinsicHeight = lerpNumber(fromHeight, toResult.height, t);\n // Interpolate the shared center frame in lockstep so glyphs stay\n // centered within the resizing box.\n this._bounds = [\n lerpNumber(fromBounds[0], toBounds[0], t),\n lerpNumber(fromBounds[1], toBounds[1], t),\n lerpNumber(fromBounds[2], toBounds[2], t),\n lerpNumber(fromBounds[3], toBounds[3], t),\n ];\n this._tokens = latexFrame(t);\n\n if (t >= 1) {\n this.set({ latex: toLatex, fontSize: toFontSize });\n this._tokens = toResult.tokens.map(tok => ({ token: tok.token, path: tok.path, opacity: 1, x: 0, y: 0 }));\n this._intrinsicWidth = toResult.width;\n this._intrinsicHeight = toResult.height;\n this._bounds = toResult.bounds;\n this._animating = false;\n this._tokenizedFrom = `${toFontSize}|${toLatex}`;\n } else if (t <= 0) {\n this.set({ latex: fromLatex, fontSize: fromFontSize });\n this._tokens = fromAnimTokens;\n this._intrinsicWidth = fromWidth;\n this._intrinsicHeight = fromHeight;\n this._bounds = fromBounds;\n this._animating = false;\n this._tokenizedFrom = `${fromFontSize}|${fromLatex}`;\n }\n }, easing) as Command<LatexProps>;\n }\n\n /**\n * The shadow op comes **first**, as it does on every other painted node.\n *\n * The renderer does not draw a shadow when it sees one: `.shadow()` stores\n * it pending and the *next* fill or stroke op casts it (`_shadow` →\n * `storePendingShadows`, `_fill`/`_stroke` → `takePendingShadows`). Appended\n * last, it was stored by every token and then thrown away by the reset at\n * the end of the draw — a shadow set on a LaTeX node simply never appeared,\n * with no error to say why. Same failure {@link PaintedNode.renderStroke}\n * documents for a fill-less stroked shape, and the same one-op fix.\n *\n * Order also carries the fill-less case for free: an empty fill returns\n * before it takes the pending shadow, so the stroke below casts it from the\n * glyph outlines instead — which is what `castsShadowFromStroke` arranges on\n * a plain shape.\n */\n protected renderSelf(ctx: RenderContext2D): void {\n this.eachToken(ctx, (graphics, opacity) => graphics\n .shadow(scaleShadowOpacity(this.shadow as ShadowResolved[], opacity))\n .fill(scaleFillopacity(this.fill as FillResolved[], opacity))\n .stroke(this.stroke));\n }\n\n /**\n * The overlay, painted *through* the glyphs.\n *\n * `ShapeNode`'s inherited overlay pass fills whatever {@link\n * ShapeNode.shapeGraphics} describes, and this node describes nothing there:\n * a formula has no single fillable silhouette — its silhouette *is* the list\n * of token paths, which is why `renderSelf` is overridden rather than a\n * `shapeGraphics` supplied. So the generic pass drew nothing and an overlay\n * set on a LaTeX node simply never appeared, with no error to say why.\n *\n * Painted the same way the fill is: one `Graphics2D` per token, all sharing the\n * centre frame, each scaled by its token's animated opacity — so a morph\n * carries the overlay along with the glyph it is laid over instead of leaving\n * a wash hanging over glyphs that have faded out.\n *\n * The stroke is *not* re-drawn here. `renderSelf` already strokes each token\n * (there is no silhouette for the deferred {@link ShapeNode.renderStroke} to\n * outline), so it is painted under the overlay rather than over it — the one\n * place this node's draw order differs from a plain shape's, and the price of\n * a stroke that follows glyphs rather than a box.\n */\n protected override renderOverlay(ctx: RenderContext2D): void {\n const overlay = this.overlay as FillResolved[];\n if (overlay.length === 0) return;\n this.eachToken(ctx, (graphics, opacity) => graphics.fill(scaleFillopacity(overlay, opacity)));\n }\n\n /**\n * Draws every visible token's path once, handing each one to `paint` to have\n * its paint ops appended.\n *\n * A fresh `Graphics2D` per token per pass, because `.fill()`/`.stroke()` push\n * onto one op list and return `this` — a silhouette shared between the fill\n * pass and the overlay pass would accumulate both.\n */\n private eachToken(ctx: RenderContext2D, paint: (graphics: Graphics2D, opacity: number) => Graphics2D): void {\n // The one funnel every paint pass goes through, so the tokens a frame\n // draws cannot be older than the formula it holds.\n this._ensureTokens();\n for (const token of this._tokens) {\n if (token.opacity <= 0) continue;\n\n // Translate the path by token's interpolated position offset\n const pathStr = token.x !== 0 || token.y !== 0\n ? toPathString(offsetPath(token.path, token.x, token.y))\n : toPathString(token.path);\n\n ctx.draw(paint(new Graphics2D()\n .path({\n data: pathStr,\n start: this.start,\n end: this.end,\n // All tokens share one center frame so they keep their relative\n // layout — without this each glyph centers on its own bbox and\n // they all stack on the origin.\n centerBounds: this._bounds,\n }), token.opacity));\n }\n }\n\n}\n\nfunction scaleFillopacity(fills: FillResolved[], opacity: number): FillResolved[] {\n if (opacity >= 1) return fills;\n return fills.map(f => ({ ...f, opacity: (f.opacity ?? 1) * opacity }));\n}\n\n/**\n * A morphing token fades, and its shadow has to fade with it — the paints are\n * scaled the same way the fill's are, so a half-faded glyph casts a half-strength\n * shadow rather than sitting over a shadow at full weight.\n */\nfunction scaleShadowOpacity(shadows: ShadowResolved[], opacity: number): ShadowResolved[] {\n if (opacity >= 1) return shadows;\n return shadows.map(s => ({ ...s, fill: scaleFillopacity(s.fill, opacity) }));\n}\n\nfunction offsetPath(\n path: LatexToken[\"path\"],\n dx: number,\n dy: number,\n): LatexToken[\"path\"] {\n return path.map(cmd => {\n const c = cmd as any;\n const shifted: any = { ...c };\n if (\"x\" in c) shifted.x = c.x + dx;\n if (\"y\" in c) shifted.y = c.y + dy;\n if (\"x1\" in c) { shifted.x1 = c.x1 + dx; shifted.y1 = c.y1 + dy; }\n if (\"x2\" in c) { shifted.x2 = c.x2 + dx; shifted.y2 = c.y2 + dy; }\n return shifted;\n });\n}\n"]}
|
package/dist/tween.js
CHANGED
package/dist/tween.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tween.js","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"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","sourcesContent":["import { lerpNumber, type PathCommand } from \"@motionscript/core\";\nimport type { LatexToken } from \"./geometry\";\n\nexport interface AnimatedToken {\n token: string;\n path: LatexToken[\"path\"];\n /** 0 = invisible, 1 = fully visible */\n opacity: number;\n /** Interpolated position offset applied during morph (x, y in formula space). */\n x: number;\n y: number;\n}\n\n/**\n * How a `Latex` node interpolates between two formulas: given the tokens it\n * currently holds and the tokens the target formula resolves to, return a\n * pure `t → AnimatedToken[]` frame function. `prepareLatexTween` below is the\n * default implementation (exported as `defaultLatexMorph`) — pass a `morph`\n * of this shape to `<Latex>` to replace it with your own.\n */\nexport type LatexMorphStrategy = (from: LatexToken[], to: LatexToken[]) => (t: number) => AnimatedToken[];\n\n/** The coordinate pairs a `PathCommand` can carry, as (x, y) field names. */\nconst POINT_FIELDS = [[\"x\", \"y\"], [\"x1\", \"y1\"], [\"x2\", \"y2\"]] as const;\n\n/**\n * Compute the centroid of a token's path for position-based interpolation.\n */\nfunction centroid(path: LatexToken[\"path\"]): { x: number; y: number } {\n let sx = 0, sy = 0, n = 0;\n for (const cmd of path) {\n if (\"x\" in cmd && \"y\" in cmd) {\n sx += (cmd as any).x;\n sy += (cmd as any).y;\n n++;\n }\n }\n return n > 0 ? { x: sx / n, y: sy / n } : { x: 0, y: 0 };\n}\n\n/**\n * A glyph's on-screen extent, as the diagonal of its control-point bbox.\n *\n * Only ever used as a *ratio* between the two ends of a match, so the fact that\n * control points overshoot the true outline doesn't matter: both ends overshoot\n * by the same proportion, because they are the same outline.\n */\nfunction extent(path: LatexToken[\"path\"]): number {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const cmd of path) {\n const c = cmd as any;\n for (const [kx, ky] of POINT_FIELDS) {\n if (kx in c) {\n if (c[kx] < minX) minX = c[kx];\n if (c[kx] > maxX) maxX = c[kx];\n if (c[ky] < minY) minY = c[ky];\n if (c[ky] > maxY) maxY = c[ky];\n }\n }\n }\n if (minX > maxX) return 0;\n return Math.hypot(maxX - minX, maxY - minY);\n}\n\n/**\n * Whether two paths can be interpolated point by point: same command count,\n * same command types in the same order.\n *\n * For a matched pair this is the overwhelmingly common case, and not by luck.\n * Tokens are matched on the character their MathJax glyph id decodes to, and\n * that id *is* the key into the `<defs>` dictionary — so the same character in\n * two formulas is the same outline, emitted twice under two different\n * transforms. Same commands, different numbers.\n */\nfunction isPointwiseCompatible(from: PathCommand[], to: PathCommand[]): boolean {\n if (from.length !== to.length) return false;\n for (let i = 0; i < from.length; i++) {\n if (from[i].type !== to[i].type) return false;\n }\n return true;\n}\n\n/**\n * Lerp two structurally identical paths point by point.\n *\n * When the two ends are the same outline under two affine transforms — which is\n * what a matched glyph is — this is exact at both ends *and* correct in\n * between: `(1-t)·A·q + t·B·q = ((1-t)A + tB)·q`, and a blend of two\n * uniform-scale-plus-translate transforms is another one. The intermediate is a\n * properly formed glyph at an intermediate size, not a smeared one.\n */\nfunction lerpPath(from: PathCommand[], to: PathCommand[], t: number): PathCommand[] {\n const out: PathCommand[] = new Array(from.length);\n for (let i = 0; i < from.length; i++) {\n const f = from[i] as any;\n const g = to[i] as any;\n const c: any = { ...g };\n for (const [kx, ky] of POINT_FIELDS) {\n if (kx in g && kx in f) {\n c[kx] = lerpNumber(f[kx], g[kx], t);\n c[ky] = lerpNumber(f[ky], g[ky], t);\n }\n }\n out[i] = c as PathCommand;\n }\n return out;\n}\n\n/**\n * Scale a path uniformly about (cx, cy), then translate by (dx, dy).\n *\n * The fallback for a matched pair whose paths *aren't* structurally identical —\n * a stretchy delimiter assembled from a different number of pieces at the two\n * sizes, say. Point-by-point lerping is impossible there, so the target outline\n * is shrunk to the source's size instead and grown back over the morph: the\n * size still changes continuously, which is the whole point, at the cost of\n * showing the target's shape from the start.\n */\nfunction scaleAbout(\n path: PathCommand[],\n cx: number,\n cy: number,\n s: number,\n dx: number,\n dy: number,\n): PathCommand[] {\n return path.map(cmd => {\n const c: any = { ...(cmd as any) };\n for (const [kx, ky] of POINT_FIELDS) {\n if (kx in c) {\n c[kx] = cx + (c[kx] - cx) * s + dx;\n c[ky] = cy + (c[ky] - cy) * s + dy;\n }\n }\n return c as PathCommand;\n });\n}\n\n/**\n * Greedily match tokens from `from` to `to` by character key.\n * Returns three lists: matched pairs, deleted tokens (only in from), added tokens (only in to).\n */\nfunction matchTokens(\n from: LatexToken[],\n to: LatexToken[],\n): {\n matched: Array<{ from: LatexToken; to: LatexToken }>;\n deleted: LatexToken[];\n added: LatexToken[];\n} {\n const remaining = [...to];\n const matched: Array<{ from: LatexToken; to: LatexToken }> = [];\n const deleted: LatexToken[] = [];\n\n for (const ft of from) {\n // Skip synthetic shapes (rects/paths) — they don't have a natural token key\n if (ft.token.startsWith(\"__\")) {\n deleted.push(ft);\n continue;\n }\n const idx = remaining.findIndex(t => t.token === ft.token && !t.token.startsWith(\"__\"));\n if (idx !== -1) {\n matched.push({ from: ft, to: remaining[idx] });\n remaining.splice(idx, 1);\n } else {\n deleted.push(ft);\n }\n }\n\n // Remaining to-tokens that weren't matched\n const added = remaining;\n\n return { matched, deleted, added };\n}\n\n/**\n * Precompute a formula-change morph and return a pure `t → AnimatedToken[]`\n * frame function:\n * - Deleted tokens fade out over the first half of `t`.\n * - Matched tokens are interpolated — place *and* size — across the full range\n * of `t`.\n * - Added tokens fade in over the second half of `t`.\n *\n * A matched glyph is rarely the same size at both ends: the `2` of `b^2` is set\n * at script size and the `2` of `2a` at full size, and a `\\frac`'s arguments\n * come back a step smaller than the same symbols on a baseline. So the\n * interpolation has to carry the glyph's *geometry*, not just where it sits.\n * Sliding the target outline from one centroid to the other — which is all this\n * used to do — put the whole size change between the last static frame and the\n * morph's first one: a snap to the new size, then a smooth glide to the new\n * place. Point-by-point lerping (see {@link lerpPath}) is that same\n * interpolation generalised from a glyph's average point to all of them, and it\n * costs nothing extra — the path was already being rebuilt every frame to apply\n * the slide.\n *\n * `t` is normalized `[0, 1]` and already eased — the caller (a `Command`'s\n * `at`) applies easing once, up front, the same eased value driving every\n * concurrent aspect of the morph (props, intrinsic size, tokens) in lockstep.\n */\nexport function prepareLatexTween(\n from: LatexToken[],\n to: LatexToken[],\n): (t: number) => AnimatedToken[] {\n const { matched, deleted, added } = matchTokens(from, to);\n\n // Per-match interpolation data. Structure compatibility, and the centroids\n // and extents behind the fallback, are properties of the pair rather than\n // of `t`, so they are settled once here instead of at every frame.\n const matchedData = matched.map(({ from: f, to: t }) => {\n const toExtent = extent(t.path);\n return {\n pointwise: isPointwiseCompatible(f.path, t.path),\n fromPath: f.path,\n toPath: t.path,\n token: t.token,\n fromCenter: centroid(f.path),\n toCenter: centroid(t.path),\n /** Only the fallback needs it, and only as a ratio. */\n fromScale: toExtent > 0 ? extent(f.path) / toExtent : 1,\n };\n });\n\n return (t: number): AnimatedToken[] => {\n const tokens: AnimatedToken[] = [];\n\n // Matched tokens: interpolate place and size across the full duration.\n for (const m of matchedData) {\n if (m.pointwise) {\n tokens.push({\n token: m.token,\n path: lerpPath(m.fromPath, m.toPath, t),\n opacity: 1,\n // Baked into the path above: the lerp carries every point,\n // which includes where the glyph sits.\n x: 0,\n y: 0,\n });\n continue;\n }\n\n const s = lerpNumber(m.fromScale, 1, t);\n const cx = lerpNumber(m.fromCenter.x, m.toCenter.x, t);\n const cy = lerpNumber(m.fromCenter.y, m.toCenter.y, t);\n tokens.push({\n token: m.token,\n path: scaleAbout(\n m.toPath,\n m.toCenter.x,\n m.toCenter.y,\n s,\n cx - m.toCenter.x,\n cy - m.toCenter.y,\n ),\n opacity: 1,\n x: 0,\n y: 0,\n });\n }\n\n // Deleted tokens: fade out over the first half, gone by t=0.5\n for (const d of deleted) {\n const fadeT = Math.min(t * 2, 1);\n tokens.push({\n token: d.token,\n path: d.path,\n opacity: lerpNumber(1, 0, fadeT),\n x: 0,\n y: 0,\n });\n }\n\n // Added tokens: fade in over the second half, starting at t=0.5\n for (const a of added) {\n const fadeT = Math.max(t * 2 - 1, 0);\n tokens.push({\n token: a.token,\n path: a.path,\n opacity: lerpNumber(0, 1, fadeT),\n x: 0,\n y: 0,\n });\n }\n\n return tokens;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tween.js","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"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","sourcesContent":["import { lerpNumber, type PathCommand } from \"@motionscript/sdk\";\nimport type { LatexToken } from \"./geometry\";\n\nexport interface AnimatedToken {\n token: string;\n path: LatexToken[\"path\"];\n /** 0 = invisible, 1 = fully visible */\n opacity: number;\n /** Interpolated position offset applied during morph (x, y in formula space). */\n x: number;\n y: number;\n}\n\n/**\n * How a `Latex` node interpolates between two formulas: given the tokens it\n * currently holds and the tokens the target formula resolves to, return a\n * pure `t → AnimatedToken[]` frame function. `prepareLatexTween` below is the\n * default implementation (exported as `defaultLatexMorph`) — pass a `morph`\n * of this shape to `<Latex>` to replace it with your own.\n */\nexport type LatexMorphStrategy = (from: LatexToken[], to: LatexToken[]) => (t: number) => AnimatedToken[];\n\n/** The coordinate pairs a `PathCommand` can carry, as (x, y) field names. */\nconst POINT_FIELDS = [[\"x\", \"y\"], [\"x1\", \"y1\"], [\"x2\", \"y2\"]] as const;\n\n/**\n * Compute the centroid of a token's path for position-based interpolation.\n */\nfunction centroid(path: LatexToken[\"path\"]): { x: number; y: number } {\n let sx = 0, sy = 0, n = 0;\n for (const cmd of path) {\n if (\"x\" in cmd && \"y\" in cmd) {\n sx += (cmd as any).x;\n sy += (cmd as any).y;\n n++;\n }\n }\n return n > 0 ? { x: sx / n, y: sy / n } : { x: 0, y: 0 };\n}\n\n/**\n * A glyph's on-screen extent, as the diagonal of its control-point bbox.\n *\n * Only ever used as a *ratio* between the two ends of a match, so the fact that\n * control points overshoot the true outline doesn't matter: both ends overshoot\n * by the same proportion, because they are the same outline.\n */\nfunction extent(path: LatexToken[\"path\"]): number {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const cmd of path) {\n const c = cmd as any;\n for (const [kx, ky] of POINT_FIELDS) {\n if (kx in c) {\n if (c[kx] < minX) minX = c[kx];\n if (c[kx] > maxX) maxX = c[kx];\n if (c[ky] < minY) minY = c[ky];\n if (c[ky] > maxY) maxY = c[ky];\n }\n }\n }\n if (minX > maxX) return 0;\n return Math.hypot(maxX - minX, maxY - minY);\n}\n\n/**\n * Whether two paths can be interpolated point by point: same command count,\n * same command types in the same order.\n *\n * For a matched pair this is the overwhelmingly common case, and not by luck.\n * Tokens are matched on the character their MathJax glyph id decodes to, and\n * that id *is* the key into the `<defs>` dictionary — so the same character in\n * two formulas is the same outline, emitted twice under two different\n * transforms. Same commands, different numbers.\n */\nfunction isPointwiseCompatible(from: PathCommand[], to: PathCommand[]): boolean {\n if (from.length !== to.length) return false;\n for (let i = 0; i < from.length; i++) {\n if (from[i].type !== to[i].type) return false;\n }\n return true;\n}\n\n/**\n * Lerp two structurally identical paths point by point.\n *\n * When the two ends are the same outline under two affine transforms — which is\n * what a matched glyph is — this is exact at both ends *and* correct in\n * between: `(1-t)·A·q + t·B·q = ((1-t)A + tB)·q`, and a blend of two\n * uniform-scale-plus-translate transforms is another one. The intermediate is a\n * properly formed glyph at an intermediate size, not a smeared one.\n */\nfunction lerpPath(from: PathCommand[], to: PathCommand[], t: number): PathCommand[] {\n const out: PathCommand[] = new Array(from.length);\n for (let i = 0; i < from.length; i++) {\n const f = from[i] as any;\n const g = to[i] as any;\n const c: any = { ...g };\n for (const [kx, ky] of POINT_FIELDS) {\n if (kx in g && kx in f) {\n c[kx] = lerpNumber(f[kx], g[kx], t);\n c[ky] = lerpNumber(f[ky], g[ky], t);\n }\n }\n out[i] = c as PathCommand;\n }\n return out;\n}\n\n/**\n * Scale a path uniformly about (cx, cy), then translate by (dx, dy).\n *\n * The fallback for a matched pair whose paths *aren't* structurally identical —\n * a stretchy delimiter assembled from a different number of pieces at the two\n * sizes, say. Point-by-point lerping is impossible there, so the target outline\n * is shrunk to the source's size instead and grown back over the morph: the\n * size still changes continuously, which is the whole point, at the cost of\n * showing the target's shape from the start.\n */\nfunction scaleAbout(\n path: PathCommand[],\n cx: number,\n cy: number,\n s: number,\n dx: number,\n dy: number,\n): PathCommand[] {\n return path.map(cmd => {\n const c: any = { ...(cmd as any) };\n for (const [kx, ky] of POINT_FIELDS) {\n if (kx in c) {\n c[kx] = cx + (c[kx] - cx) * s + dx;\n c[ky] = cy + (c[ky] - cy) * s + dy;\n }\n }\n return c as PathCommand;\n });\n}\n\n/**\n * Greedily match tokens from `from` to `to` by character key.\n * Returns three lists: matched pairs, deleted tokens (only in from), added tokens (only in to).\n */\nfunction matchTokens(\n from: LatexToken[],\n to: LatexToken[],\n): {\n matched: Array<{ from: LatexToken; to: LatexToken }>;\n deleted: LatexToken[];\n added: LatexToken[];\n} {\n const remaining = [...to];\n const matched: Array<{ from: LatexToken; to: LatexToken }> = [];\n const deleted: LatexToken[] = [];\n\n for (const ft of from) {\n // Skip synthetic shapes (rects/paths) — they don't have a natural token key\n if (ft.token.startsWith(\"__\")) {\n deleted.push(ft);\n continue;\n }\n const idx = remaining.findIndex(t => t.token === ft.token && !t.token.startsWith(\"__\"));\n if (idx !== -1) {\n matched.push({ from: ft, to: remaining[idx] });\n remaining.splice(idx, 1);\n } else {\n deleted.push(ft);\n }\n }\n\n // Remaining to-tokens that weren't matched\n const added = remaining;\n\n return { matched, deleted, added };\n}\n\n/**\n * Precompute a formula-change morph and return a pure `t → AnimatedToken[]`\n * frame function:\n * - Deleted tokens fade out over the first half of `t`.\n * - Matched tokens are interpolated — place *and* size — across the full range\n * of `t`.\n * - Added tokens fade in over the second half of `t`.\n *\n * A matched glyph is rarely the same size at both ends: the `2` of `b^2` is set\n * at script size and the `2` of `2a` at full size, and a `\\frac`'s arguments\n * come back a step smaller than the same symbols on a baseline. So the\n * interpolation has to carry the glyph's *geometry*, not just where it sits.\n * Sliding the target outline from one centroid to the other — which is all this\n * used to do — put the whole size change between the last static frame and the\n * morph's first one: a snap to the new size, then a smooth glide to the new\n * place. Point-by-point lerping (see {@link lerpPath}) is that same\n * interpolation generalised from a glyph's average point to all of them, and it\n * costs nothing extra — the path was already being rebuilt every frame to apply\n * the slide.\n *\n * `t` is normalized `[0, 1]` and already eased — the caller (a `Command`'s\n * `at`) applies easing once, up front, the same eased value driving every\n * concurrent aspect of the morph (props, intrinsic size, tokens) in lockstep.\n */\nexport function prepareLatexTween(\n from: LatexToken[],\n to: LatexToken[],\n): (t: number) => AnimatedToken[] {\n const { matched, deleted, added } = matchTokens(from, to);\n\n // Per-match interpolation data. Structure compatibility, and the centroids\n // and extents behind the fallback, are properties of the pair rather than\n // of `t`, so they are settled once here instead of at every frame.\n const matchedData = matched.map(({ from: f, to: t }) => {\n const toExtent = extent(t.path);\n return {\n pointwise: isPointwiseCompatible(f.path, t.path),\n fromPath: f.path,\n toPath: t.path,\n token: t.token,\n fromCenter: centroid(f.path),\n toCenter: centroid(t.path),\n /** Only the fallback needs it, and only as a ratio. */\n fromScale: toExtent > 0 ? extent(f.path) / toExtent : 1,\n };\n });\n\n return (t: number): AnimatedToken[] => {\n const tokens: AnimatedToken[] = [];\n\n // Matched tokens: interpolate place and size across the full duration.\n for (const m of matchedData) {\n if (m.pointwise) {\n tokens.push({\n token: m.token,\n path: lerpPath(m.fromPath, m.toPath, t),\n opacity: 1,\n // Baked into the path above: the lerp carries every point,\n // which includes where the glyph sits.\n x: 0,\n y: 0,\n });\n continue;\n }\n\n const s = lerpNumber(m.fromScale, 1, t);\n const cx = lerpNumber(m.fromCenter.x, m.toCenter.x, t);\n const cy = lerpNumber(m.fromCenter.y, m.toCenter.y, t);\n tokens.push({\n token: m.token,\n path: scaleAbout(\n m.toPath,\n m.toCenter.x,\n m.toCenter.y,\n s,\n cx - m.toCenter.x,\n cy - m.toCenter.y,\n ),\n opacity: 1,\n x: 0,\n y: 0,\n });\n }\n\n // Deleted tokens: fade out over the first half, gone by t=0.5\n for (const d of deleted) {\n const fadeT = Math.min(t * 2, 1);\n tokens.push({\n token: d.token,\n path: d.path,\n opacity: lerpNumber(1, 0, fadeT),\n x: 0,\n y: 0,\n });\n }\n\n // Added tokens: fade in over the second half, starting at t=0.5\n for (const a of added) {\n const fadeT = Math.max(t * 2 - 1, 0);\n tokens.push({\n token: a.token,\n path: a.path,\n opacity: lerpNumber(0, 1, fadeT),\n x: 0,\n y: 0,\n });\n }\n\n return tokens;\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motionscript/latex",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Animated LaTeX math for Motion Script, rendering formulas to glyph paths via MathJax and morphing them token by token.",
|
|
6
6
|
"repository": {
|
|
@@ -44,9 +44,10 @@
|
|
|
44
44
|
},
|
|
45
45
|
"license": "Apache-2.0",
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@motionscript/
|
|
47
|
+
"@motionscript/sdk": "^0.1.0-alpha.3"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
+
"@mathjax/mathjax-newcm-font": "^4.1.1",
|
|
50
51
|
"@mathjax/src": "^4.1.1"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"typescript": "^6.0.3",
|
|
59
60
|
"typescript-eslint": "^8.48.0",
|
|
60
61
|
"vitest": "^4.1.5",
|
|
61
|
-
"@motionscript/
|
|
62
|
+
"@motionscript/sdk": "0.1.0-alpha.3"
|
|
62
63
|
},
|
|
63
64
|
"scripts": {
|
|
64
65
|
"build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json --resolve-full-paths && node ../../../scripts/build-browser.mjs",
|