domotion-svg 0.21.1 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/FEATURES.md +3 -0
  2. package/README.md +7 -1
  3. package/assets/fonts/fixture/DomotionFixtureMono-Regular.ttf +0 -0
  4. package/assets/fonts/fixture/DomotionFixtureSerif-Regular.ttf +0 -0
  5. package/assets/fonts/fixture/LICENSE-ibm-plex-serif.txt +93 -0
  6. package/assets/fonts/fixture/LICENSE-jetbrains-mono.txt +93 -0
  7. package/assets/fonts/fixture/README.md +39 -0
  8. package/dist/animation/animator.d.ts +49 -57
  9. package/dist/animation/animator.js +511 -143
  10. package/dist/animation/caret-metrics.d.ts +99 -5
  11. package/dist/animation/caret-metrics.js +82 -3
  12. package/dist/animation/caret-track.d.ts +181 -0
  13. package/dist/animation/caret-track.js +459 -0
  14. package/dist/animation/compressed-run.d.ts +318 -0
  15. package/dist/animation/compressed-run.js +1408 -0
  16. package/dist/animation/cursor-overlay.d.ts +10 -5
  17. package/dist/animation/cursor-overlay.js +12 -19
  18. package/dist/animation/easing.js +0 -0
  19. package/dist/animation/embed-timeline.d.ts +6 -1
  20. package/dist/animation/embed-timeline.js +45 -37
  21. package/dist/animation/glyph-align.d.ts +69 -0
  22. package/dist/animation/glyph-align.js +128 -0
  23. package/dist/animation/index.d.ts +5 -0
  24. package/dist/animation/index.js +19 -0
  25. package/dist/animation/magic-move.js +16 -4
  26. package/dist/animation/overlay-schema.d.ts +16 -0
  27. package/dist/animation/overlay-schema.js +60 -0
  28. package/dist/animation/resolve-overlays.d.ts +23 -0
  29. package/dist/animation/resolve-overlays.js +191 -9
  30. package/dist/animation/text-address.d.ts +213 -0
  31. package/dist/animation/text-address.js +727 -0
  32. package/dist/animation/transition-schema.d.ts +454 -0
  33. package/dist/animation/transition-schema.js +150 -0
  34. package/dist/capture/emoji.d.ts +10 -0
  35. package/dist/capture/emoji.js +203 -17
  36. package/dist/capture/generic-font-probe.d.ts +31 -0
  37. package/dist/capture/generic-font-probe.js +186 -0
  38. package/dist/capture/index.d.ts +33 -0
  39. package/dist/capture/index.js +89 -10
  40. package/dist/capture/script/emoji-detect.d.ts +2 -2
  41. package/dist/capture/script/emoji-detect.js +197 -4
  42. package/dist/capture/script/font-family-default.d.ts +3 -0
  43. package/dist/capture/script/font-family-default.js +133 -0
  44. package/dist/capture/script/index.d.ts +1 -0
  45. package/dist/capture/script/index.js +55 -5
  46. package/dist/capture/script/utils.d.ts +1 -0
  47. package/dist/capture/script/utils.js +2 -0
  48. package/dist/capture/script/walker/counter-style-resolver.js +16 -3
  49. package/dist/capture/script/walker/input-value.js +19 -1
  50. package/dist/capture/script/walker/pseudo-content.d.ts +3 -9
  51. package/dist/capture/script/walker/pseudo-content.js +6 -2
  52. package/dist/capture/script/walker/text-segments.d.ts +5 -17
  53. package/dist/capture/script/walker/text-segments.js +116 -138
  54. package/dist/capture/script.generated.js +1 -1
  55. package/dist/capture/types.d.ts +131 -6
  56. package/dist/cli/animate.d.ts +939 -51
  57. package/dist/cli/animate.js +1422 -54
  58. package/dist/cli/capture.js +6 -2
  59. package/dist/cli/index.js +9 -1
  60. package/dist/cli/mutation-detect.js +6 -3
  61. package/dist/cli/storyboard.d.ts +174 -23
  62. package/dist/cli/storyboard.js +5 -10
  63. package/dist/cli/svg-to-image-core.js +3 -1
  64. package/dist/cli/svg-to-video-core.d.ts +13 -1
  65. package/dist/cli/svg-to-video-core.js +34 -3
  66. package/dist/cli/type-resample.js +30 -19
  67. package/dist/index.d.ts +1 -1
  68. package/dist/index.js +1 -1
  69. package/dist/post-processing/hoist-image-payloads.d.ts +72 -0
  70. package/dist/post-processing/hoist-image-payloads.js +247 -0
  71. package/dist/post-processing/index.d.ts +2 -0
  72. package/dist/post-processing/index.js +7 -2
  73. package/dist/post-processing/woff2-fonts.d.ts +6 -0
  74. package/dist/post-processing/woff2-fonts.js +41 -0
  75. package/dist/render/cluster-fallback.d.ts +77 -0
  76. package/dist/render/cluster-fallback.js +903 -0
  77. package/dist/render/element-tree-to-svg.d.ts +20 -1
  78. package/dist/render/element-tree-to-svg.js +579 -430
  79. package/dist/render/embedded-font-builder.d.ts +161 -0
  80. package/dist/render/embedded-font-builder.js +355 -63
  81. package/dist/render/embolden-outline.d.ts +109 -0
  82. package/dist/render/embolden-outline.js +372 -0
  83. package/dist/render/font-features.d.ts +40 -0
  84. package/dist/render/font-features.js +61 -0
  85. package/dist/render/font-resolution.d.ts +1457 -96
  86. package/dist/render/font-resolution.js +6907 -441
  87. package/dist/render/format.js +30 -0
  88. package/dist/render/generic-script-families.d.ts +51 -0
  89. package/dist/render/generic-script-families.js +338 -0
  90. package/dist/render/glyph-helper.d.ts +614 -11
  91. package/dist/render/glyph-helper.js +1115 -49
  92. package/dist/render/harfbuzz-default-ignorable-ranges.generated.d.ts +1 -0
  93. package/dist/render/harfbuzz-default-ignorable-ranges.generated.js +32 -0
  94. package/dist/render/harfbuzz-shaper.d.ts +321 -4
  95. package/dist/render/harfbuzz-shaper.js +718 -25
  96. package/dist/render/hb-subset.d.ts +63 -0
  97. package/dist/render/hb-subset.js +550 -0
  98. package/dist/render/helper-acquire.js +8 -5
  99. package/dist/render/host-platform.d.ts +57 -0
  100. package/dist/render/host-platform.js +68 -0
  101. package/dist/render/index.js +10 -0
  102. package/dist/render/paint-order.d.ts +70 -0
  103. package/dist/render/paint-order.js +174 -0
  104. package/dist/render/script-extensions.generated.d.ts +7 -0
  105. package/dist/render/script-extensions.generated.js +151 -0
  106. package/dist/render/script-iso15924.generated.d.ts +1 -0
  107. package/dist/render/script-iso15924.generated.js +197 -0
  108. package/dist/render/script-segmentation.d.ts +90 -0
  109. package/dist/render/script-segmentation.js +486 -0
  110. package/dist/render/stacking.d.ts +114 -0
  111. package/dist/render/stacking.js +252 -2
  112. package/dist/render/standardized-variation-sequences.generated.d.ts +1 -0
  113. package/dist/render/standardized-variation-sequences.generated.js +91 -0
  114. package/dist/render/synth-test-fonts.d.ts +47 -0
  115. package/dist/render/synth-test-fonts.js +382 -0
  116. package/dist/render/synthesis-decision.d.ts +150 -0
  117. package/dist/render/synthesis-decision.js +250 -0
  118. package/dist/render/text-parity-diagnostics.d.ts +13 -0
  119. package/dist/render/text-parity-diagnostics.js +18 -0
  120. package/dist/render/text-to-path.d.ts +298 -83
  121. package/dist/render/text-to-path.js +1529 -545
  122. package/dist/render/text.d.ts +143 -1
  123. package/dist/render/text.js +757 -247
  124. package/dist/render/unicode-classification.d.ts +69 -0
  125. package/dist/render/unicode-classification.js +839 -74
  126. package/dist/render/unicode-font-routing.darwin.generated.d.ts +4 -0
  127. package/dist/render/unicode-font-routing.darwin.generated.js +142 -142
  128. package/dist/render/use-left-matra-ranges.generated.d.ts +1 -0
  129. package/dist/render/use-left-matra-ranges.generated.js +29 -0
  130. package/dist/render/vertical-text.js +16 -3
  131. package/dist/render/win-font-fallback.d.ts +296 -0
  132. package/dist/render/win-font-fallback.js +949 -0
  133. package/dist/render/win32-family-suffix.d.ts +40 -0
  134. package/dist/render/win32-family-suffix.js +75 -0
  135. package/dist/review/compare-pngs.d.ts +142 -9
  136. package/dist/review/compare-pngs.js +146 -39
  137. package/dist/review/glyph-compare.d.ts +282 -0
  138. package/dist/review/glyph-compare.js +858 -0
  139. package/dist/review/side-digest.d.ts +166 -0
  140. package/dist/review/side-digest.js +209 -0
  141. package/dist/scroll/composer.js +19 -3
  142. package/dist/scroll/executor.d.ts +11 -0
  143. package/dist/scroll/executor.js +7 -4
  144. package/dist/scrubber/client.bundle.generated.js +1 -1
  145. package/dist/scrubber/client.js +28 -2
  146. package/dist/templates/builtin/chart.d.ts +1 -1
  147. package/dist/templates/builtin/kinetic-text.d.ts +1 -1
  148. package/dist/templates/builtin/subscribe.js +4 -2
  149. package/dist/tree-ops/annotate-animated-properties.d.ts +32 -0
  150. package/dist/tree-ops/annotate-animated-properties.js +41 -0
  151. package/dist/tree-ops/decoration-propagation.d.ts +60 -0
  152. package/dist/tree-ops/decoration-propagation.js +134 -0
  153. package/dist/tree-ops/index.d.ts +2 -0
  154. package/dist/tree-ops/index.js +4 -0
  155. package/dist/tree-ops/viewbox-culling.d.ts +26 -7
  156. package/dist/tree-ops/viewbox-culling.js +335 -61
  157. package/llms.txt +1 -1
  158. package/package.json +34 -17
  159. package/schemas/animate-config.schema.json +3363 -787
  160. package/schemas/storyboard-config.schema.json +987 -31
  161. package/vendor/harfbuzzjs/LICENSE +19 -0
  162. package/vendor/harfbuzzjs/README.md +120 -0
  163. package/vendor/harfbuzzjs/build/Makefile +88 -0
  164. package/vendor/harfbuzzjs/build/config-override.h +89 -0
  165. package/vendor/harfbuzzjs/build/harfbuzz.symbols +114 -0
  166. package/vendor/harfbuzzjs/dist/harfbuzz-subset.wasm +0 -0
  167. package/vendor/harfbuzzjs/dist/harfbuzz.d.ts +4 -0
  168. package/vendor/harfbuzzjs/dist/harfbuzz.js +2 -0
  169. package/vendor/harfbuzzjs/dist/harfbuzz.wasm +0 -0
  170. package/vendor/harfbuzzjs/dist/index.d.mts +902 -0
  171. package/vendor/harfbuzzjs/dist/index.mjs +1638 -0
  172. package/dist/capture/initial-letter-probe.d.ts +0 -37
  173. package/dist/capture/initial-letter-probe.js +0 -134
package/FEATURES.md CHANGED
@@ -11,9 +11,11 @@ Each feature has a visual regression test that compares HTML-to-PNG with SVG-to-
11
11
  - [x] **text-right**: Right-aligned text
12
12
  - [x] **text-mono**: Monospace font rendering
13
13
  - [x] **text-multiline**: Multiple lines of text in a container
14
+ - [x] **lineheight-residual**: Baseline pixel-grid snap on fractional line-height baselines (18px × 1.6 → 28.796875px line boxes; Skia rounds glyph y to integer device pixels)
14
15
  - [x] **text-small**: Small/label text (11-12px)
15
16
  - [x] **text-inline-mixed**: Mixed inline content (prose with inline code spans)
16
17
  - [x] **text-pre-multiline**: Preformatted multiline text (`<pre>` with `white-space: pre`)
18
+ - [x] **text-font-stretch-underline**: CSS `font-stretch` end to end — condensed/expanded cut selection for declared families (Blink's trait-based style matcher), the `wdth` variation axis on the macOS `system-ui` face and variable webfonts, and decoration metrics resolved on the same width-matched face as the glyphs
17
19
 
18
20
  ### Backgrounds & Colors
19
21
  - [x] **bg-solid**: Solid background colors
@@ -35,6 +37,7 @@ Each feature has a visual regression test that compares HTML-to-PNG with SVG-to-
35
37
  - [ ] **layout-grid**: CSS Grid layout
36
38
  - [ ] **layout-absolute**: Absolute positioning
37
39
  - [x] **layout-padding**: Padding affecting content position
40
+ - [x] **float-paint-order-context-wide** (doc 01 § Stacking): a stacking context paints in CSS 2.1 Appendix E phases — every in-flow block's background + border (step 3), then every non-positioned float (step 4), then all inline content (step 5). So a float paints above a later block sibling's background and below the text of every paragraph in the context, and an `inline-block` / flex item keeps its own floats (it paints atomically).
38
41
 
39
42
  ### Components
40
43
  - [x] **comp-button**: Button with background, border, padding, text
package/README.md CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  **Domotion turns real HTML/CSS into one self-contained, animated SVG** — an accurate reproduction of the rendered page, with optional animation and simulated interaction built in. Text is emitted as real glyph paths, so it looks identical across browsers; the output scales crisply at any size and embeds anywhere with a plain `<img>`, no external assets.
16
16
 
17
- Beyond raw capture it ships a **template library** that turns a few flags into a polished animated SVG, **terminal-session capture** (a recording → an animated terminal), **scroll capture** (a long page replayed as one self-contained scrolling SVG), multi-frame **animation** with transitions, overlays, and simulated interaction, **scene storyboarding** (sequence distinct scenes end-to-end), **brand kits** and **social-format presets** (reel / square / portrait / landscape), **device-chrome** framing, **nested compositing** (animated layers inside animated layers), one-command **SVG → MP4/WebM**, and a fidelity **review** tool.
17
+ Beyond raw capture it ships a **template library** that turns a few flags into a polished animated SVG, **terminal-session capture** (a recording → an animated terminal), **scroll capture** (a long page replayed as one self-contained scrolling SVG), multi-frame **animation** with parameterized and custom transitions, overlays, and simulated interaction, **scene storyboarding** (sequence distinct scenes end-to-end), **brand kits** and **social-format presets** (reel / square / portrait / landscape), **device-chrome** framing, **nested compositing** (animated layers inside animated layers), one-command **SVG → MP4/WebM**, and a fidelity **review** tool.
18
18
 
19
19
  <p align="center">
20
20
  <img src="examples/output/hero-product-demo.svg" alt="An analytics dashboard assembling itself inside a browser window — KPI cards rise in, a bar chart grows with its peak highlighted, a search query types itself, and a nav item is clicked — all in one self-contained animated SVG" width="760">
@@ -89,6 +89,12 @@ domotion animate ./demo.json
89
89
 
90
90
  The config describes each frame (input, duration, transition) plus a declarative surface for interaction demos: continuous-session frames that carry client-side state across steps (omit `input` / set `"continue": true`), DOM-mutation and interaction actions, richer readiness waits (`waitForText` / `waitForGone` / `waitForCount`), typing / tap / svg / blink / shine / interact overlays that can anchor to an element's box (typing supports per-keystroke reveal, `kern`, caret shapes, and a high-fidelity `typeResample` mode), real interaction-state capture (`forceState` / `hoverReveal` / `hoverDetect` / `jsReveal`), an on-screen `cursor` (explicit or `"auto"`), `vars` + `${}` interpolation, and a small `evaluate` escape hatch. See `domotion --help` for the full grammar and the [Quick start](https://brianwestphal.github.io/domotion/start/quickstart/) for a walkthrough.
91
91
 
92
+ Transitions are not limited to fixed presets. Parameterized `push`, `reveal`,
93
+ `zoom`, and `shine` forms control direction/angle, distance, origin, radius, and
94
+ highlight styling. A strict `custom` recipe can safely combine incoming/outgoing
95
+ opacity, translate, scale, reveal clip, and shine channels—plus explicit reduced-
96
+ motion and loop behavior—without accepting raw CSS or script.
97
+
92
98
  ### Templates — animated SVGs from a few flags
93
99
 
94
100
  The fastest way to a polished result without writing any HTML. Each built-in is a parameterized generator; pass a few flags and get a self-contained animated SVG. `domotion template list` shows them, `domotion template <name> --help` shows a template's parameters.
@@ -0,0 +1,93 @@
1
+ Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+
5
+ This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,93 @@
1
+ Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ https://openfontlicense.org
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # Deterministic fixture faces
2
+
3
+ Subsetted fonts the frame-sequence compressor's e2e fixtures render with, so
4
+ those fixtures paint the same glyph outlines on macOS, Linux, and Windows.
5
+
6
+ They exist because the compressor e2e tests assert pixel parity between a
7
+ compressed run and the uncompressed flipbook of the same state, bounded by the
8
+ no-motion caps in `src/review/compare-pngs.ts`. Both images come from our own
9
+ renderer, so the caps only absorb the sub-pixel phase difference the
10
+ compressor's transform groups introduce — but the size of that drift depends on
11
+ which outlines get rasterized. While the fixtures asked for host-dependent
12
+ families (`Menlo`, `system-ui`, `Georgia`) the clean drift ceiling moved with
13
+ the host (88 px largest strict region on macOS vs 829 px in the Linux
14
+ container), overlapping a known compressor break at 3712 px, so no single cap
15
+ could both pass a correct build and fail a broken one. Pinning the fixtures to
16
+ these files collapses the ceiling to one number everywhere.
17
+
18
+ Consumed through `tests/fixture-fonts.ts` — never referenced by path from a
19
+ test. See that module for the two-halves usage contract (page `@font-face` for
20
+ Chrome's layout, `registerWebfont` for Domotion's outlines).
21
+
22
+ ## Provenance
23
+
24
+ | File | Upstream | License |
25
+ |---|---|---|
26
+ | `DomotionFixtureMono-Regular.ttf` | [JetBrains Mono](https://github.com/JetBrains/JetBrainsMono) Regular | SIL OFL 1.1 — `LICENSE-jetbrains-mono.txt` |
27
+ | `DomotionFixtureSerif-Regular.ttf` | [IBM Plex Serif](https://github.com/IBM/plex) Regular | SIL OFL 1.1 — `LICENSE-ibm-plex-serif.txt` |
28
+
29
+ Both are unmodified apart from being subsetted to the characters the fixtures
30
+ paint. The OFL permits redistribution of modified copies under a reserved-name
31
+ rule, which is why the outputs carry neutral `DomotionFixture*` names rather
32
+ than the upstream family names.
33
+
34
+ ## Regenerating
35
+
36
+ `tools/build-fixture-fonts.mjs` rebuilds both from the upstream originals (it
37
+ prints the download URLs). The subset is deterministic — same inputs and the
38
+ same harfbuzzjs version produce byte-identical output, so a re-run must leave
39
+ `git status` clean unless an input or the charset actually changed.
@@ -7,6 +7,8 @@
7
7
  import { type CursorAtResolver, type CursorOverlay, type SelectorResolver } from "./cursor-overlay.js";
8
8
  import type { MagicMove } from "./magic-move.js";
9
9
  import type { AnimationOverlay, TypingOverlay, TapOverlay, SvgOverlay, BlinkOverlay, ShineOverlay, InteractOverlay, IntraFrameAnimation } from "./overlay-schema.js";
10
+ import { type ResolvedTextTrack } from "./caret-track.js";
11
+ import { type Transition } from "./transition-schema.js";
10
12
  export interface AnimationFrame {
11
13
  /** SVG content for this frame (from dom-to-svg) */
12
14
  svgContent: string;
@@ -14,9 +16,10 @@ export interface AnimationFrame {
14
16
  * Per-element viewBox-cull keyframes CSS (DM-603). The caller runs
15
17
  * `cullElementsOutsideViewBox()` on the captured tree before `elementTreeToSvg()` — that
16
18
  * mutates `displayNone` / `cullClass` on each element (which the renderer
17
- * surfaces) and returns the keyframes blocks that map each `cull-N` class
18
- * to its visible window. The animator splices this CSS into the scene-wide
19
- * `<style>` block.
19
+ * surfaces) and returns the keyframes blocks that map each window-derived
20
+ * `cull-<start>-<end>` class to its visible window. The animator splices
21
+ * this CSS into the scene-wide `<style>` block, deduping blocks whose class
22
+ * (= window) repeats across frames.
20
23
  *
21
24
  * When omitted, no culling happens — callers passing pre-rendered
22
25
  * `svgContent` strings without the cull CSS get unchanged behavior.
@@ -33,60 +36,8 @@ export interface AnimationFrame {
33
36
  * `offsetEmbeddedAnimatedSvgTimeline`). Omit for ordinary captured frames.
34
37
  */
35
38
  embeddedAnimationPeriodMs?: number;
36
- /** Transition to next frame */
37
- transition?: {
38
- /**
39
- * `crossfade` (default) overlaps fade-out and fade-in. `push-left` slides
40
- * the outgoing frame off and the incoming frame in from the right.
41
- * `scroll` keeps both visible during the transition. `cut` is instant —
42
- * no fade, no slide. For `cut`, `duration` is ignored. `magic-move` blends
43
- * shared elements between the two frames — matched elements slide from
44
- * their old position to their new one while added/removed elements
45
- * cross-fade (DM-898; see `docs/53-magic-move-transition.md`). It requires
46
- * the per-frame `magicMove` bridge layer (built caller-side from the
47
- * element trees); when that's absent it degrades to `crossfade`.
48
- *
49
- * DM-1524 adds the cross-engine-safe transition/effect expansion (docs/88):
50
- * directional pushes `push-right` / `push-up` / `push-down` (the vertical/
51
- * horizontal siblings of `push-left`; `push-up` is the alias of `scroll`'s
52
- * motion), the `wipe` (linear left→right `clip-path` reveal) and `iris`
53
- * (expanding-circle `clip-path` reveal) reveals, `zoom-in` / `zoom-out`
54
- * (scale dolly under a crossfade), and `shine` (a crossfade with a swept
55
- * gradient highlight over the handoff — the shared `buildShineSweep` helper).
56
- *
57
- * DM-1547 adds the radial / clock wipes (docs/88): `wipe-radial` (an
58
- * expanding-circle reveal — the same geometry family as `iris`, kept as a
59
- * named alias so the "radial wipe" vocabulary is complete, mirroring how
60
- * `push-up` aliases `scroll`) and `wipe-clock` (an angular "clock hand" sweep
61
- * that reveals the incoming frame around the center via an animated
62
- * `clip-path: polygon()` with a fixed vertex count — NO animated conic mask,
63
- * NO animated filter, so it composites identically on Blink / WebKit / Gecko).
64
- *
65
- * All express motion in `transform` / `clip-path` / `opacity` / gradients
66
- * only — never an animated CSS `filter` (Chromium-only in `<img>`, docs/84).
67
- */
68
- type: "crossfade" | "push-left" | "scroll" | "cut" | "magic-move" | "push-right" | "push-up" | "push-down" | "wipe" | "iris" | "zoom-in" | "zoom-out" | "shine" | "wipe-radial" | "wipe-clock";
69
- duration: number;
70
- /**
71
- * DM-1550: optional named easing (or a raw CSS easing string) for the
72
- * `wipe` / `iris` clip-path reveal and the `zoom-in` / `zoom-out` scale
73
- * dolly this transition drives into the NEXT frame. Resolved through the
74
- * motion-preset vocabulary (`resolveEasingPreset`) so the sampled
75
- * `spring-soft` / `spring-bouncy` `linear(...)` curves — and their visible
76
- * overshoot — apply to the reveal / dolly. Ignored by the other transition
77
- * types (their motion is fixed). Default: `linear`.
78
- */
79
- easing?: string;
80
- /**
81
- * DM-1585: `wipe-clock` only — where the clock hand STARTS, in degrees
82
- * clockwise from 12 o'clock (default 0), and whether it sweeps
83
- * counterclockwise (default clockwise). Lets a clock wipe open from, say, 3
84
- * o'clock (`wipeStartAngle: 90`) or unwind anticlockwise
85
- * (`wipeCounterclockwise: true`). Ignored by every other transition type.
86
- */
87
- wipeStartAngle?: number;
88
- wipeCounterclockwise?: boolean;
89
- };
39
+ /** Transition to the next frame. The type is derived from the canonical zod schema. */
40
+ transition?: Transition;
90
41
  /**
91
42
  * Magic-move bridge layer for this frame's transition to the next, built by
92
43
  * the caller via `buildMagicMove(prevTree, nextTree, …)`. Present only when
@@ -150,6 +101,15 @@ export interface AnimationConfig {
150
101
  * when omitted, the overlay paints the single arrow.
151
102
  */
152
103
  resolveCursorAt?: CursorAtResolver;
104
+ /**
105
+ * Caret + selection tracks (docs/101): declarative caret / selection
106
+ * rendering anchored to captured text, resolved caller-side against the
107
+ * frame's captured tree via `resolveTextTrack` (the magic-move precedent —
108
+ * built from the element trees, consumed here as resolved geometry). Layered
109
+ * above every frame group and below the cursor overlay. Times inside each
110
+ * track are ms on the animation's global timeline.
111
+ */
112
+ textTracks?: ResolvedTextTrack[];
153
113
  /**
154
114
  * Canvas background color painted behind every frame (a full-viewport
155
115
  * `<rect>`). Mirrors the single-frame path's `transparentRootBgRect`
@@ -183,4 +143,36 @@ export interface AnimationConfig {
183
143
  * frames whose ids are already unique are emitted byte-for-byte unchanged.
184
144
  */
185
145
  export declare function dedupeFrameIds(frames: AnimationFrame[]): AnimationFrame[];
146
+ /** A rectangular half-plane reveal sampled to a fixed vertex count so angled
147
+ * wipe polygons remain CSS-interpolable on every supported engine. */
148
+ export declare function linearWipeClip(f: number, width: number, height: number, angleDeg: number): string;
149
+ /**
150
+ * DM-1767 (docs/104): resolve an overlay's WINDOW END, in ms from frame start.
151
+ *
152
+ * Historically every overlay's window ended with its frame. `endAt` makes that
153
+ * explicit and lets an overlay end EARLY — clamped to the frame's duration, so
154
+ * it can still never leak past the cut into the next frame. Returns the frame's
155
+ * own duration when the overlay declares nothing, which is why every existing
156
+ * config emits byte-identical CSS.
157
+ *
158
+ * Exported for unit tests.
159
+ */
160
+ export declare function overlayWindowEndMs(overlay: AnimationOverlay, frameDurationMs: number): number;
161
+ /**
162
+ * Collapse repeated numeric offsets inside whole-layer CSS `@keyframes` blocks.
163
+ * Later declarations win per property, matching CSS source-order cascading,
164
+ * but each offset is emitted once so boundary behavior is engine-independent.
165
+ * Blocks without repeated offsets remain byte-identical.
166
+ */
167
+ export declare function consolidateKeyframeOffsets(svg: string): string;
186
168
  export declare function generateAnimatedSvg(config: AnimationConfig): string;
169
+ /**
170
+ * DM-1767: each overlay kind's default `delay` — the ms after frame start at
171
+ * which it begins when the author sets none. Published because SHIFTING an
172
+ * overlay onto a different origin (a per-state overlay inside a compressed run
173
+ * moving from "its own state's start" to "the collapsed run's start" —
174
+ * docs/104) must add the offset to the EFFECTIVE delay; adding it to a bare
175
+ * `delay ?? 0` would silently drop the kind's own lead-in and the overlay would
176
+ * fire early relative to how it behaved as its own frame.
177
+ */
178
+ export declare const OVERLAY_DEFAULT_DELAY_MS: Record<AnimationOverlay["kind"], number>;