@motion-script/web 0.1.0

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 (262) hide show
  1. package/README.md +47 -0
  2. package/dist/audio/player.d.ts +43 -0
  3. package/dist/audio/player.d.ts.map +1 -0
  4. package/dist/audio/player.js +165 -0
  5. package/dist/audio/player.js.map +1 -0
  6. package/dist/effects/bloom.d.ts +19 -0
  7. package/dist/effects/bloom.d.ts.map +1 -0
  8. package/dist/effects/bloom.js +64 -0
  9. package/dist/effects/bloom.js.map +1 -0
  10. package/dist/effects/blur.d.ts +8 -0
  11. package/dist/effects/blur.d.ts.map +1 -0
  12. package/dist/effects/blur.js +12 -0
  13. package/dist/effects/blur.js.map +1 -0
  14. package/dist/effects/bulge-pinch.d.ts +20 -0
  15. package/dist/effects/bulge-pinch.d.ts.map +1 -0
  16. package/dist/effects/bulge-pinch.js +86 -0
  17. package/dist/effects/bulge-pinch.js.map +1 -0
  18. package/dist/effects/chromatic-aberration.d.ts +19 -0
  19. package/dist/effects/chromatic-aberration.d.ts.map +1 -0
  20. package/dist/effects/chromatic-aberration.js +59 -0
  21. package/dist/effects/chromatic-aberration.js.map +1 -0
  22. package/dist/effects/effect.d.ts +32 -0
  23. package/dist/effects/effect.d.ts.map +1 -0
  24. package/dist/effects/effect.js +22 -0
  25. package/dist/effects/effect.js.map +1 -0
  26. package/dist/effects/grayscale.d.ts +12 -0
  27. package/dist/effects/grayscale.d.ts.map +1 -0
  28. package/dist/effects/grayscale.js +31 -0
  29. package/dist/effects/grayscale.js.map +1 -0
  30. package/dist/effects/index.d.ts +13 -0
  31. package/dist/effects/index.d.ts.map +1 -0
  32. package/dist/effects/index.js +13 -0
  33. package/dist/effects/index.js.map +1 -0
  34. package/dist/effects/pixelate.d.ts +23 -0
  35. package/dist/effects/pixelate.d.ts.map +1 -0
  36. package/dist/effects/pixelate.js +37 -0
  37. package/dist/effects/pixelate.js.map +1 -0
  38. package/dist/effects/registry.d.ts +17 -0
  39. package/dist/effects/registry.d.ts.map +1 -0
  40. package/dist/effects/registry.js +56 -0
  41. package/dist/effects/registry.js.map +1 -0
  42. package/dist/effects/sksl-cache.d.ts +6 -0
  43. package/dist/effects/sksl-cache.d.ts.map +1 -0
  44. package/dist/effects/sksl-cache.js +21 -0
  45. package/dist/effects/sksl-cache.js.map +1 -0
  46. package/dist/effects/sksl-layer.d.ts +30 -0
  47. package/dist/effects/sksl-layer.d.ts.map +1 -0
  48. package/dist/effects/sksl-layer.js +82 -0
  49. package/dist/effects/sksl-layer.js.map +1 -0
  50. package/dist/effects/texture.d.ts +31 -0
  51. package/dist/effects/texture.d.ts.map +1 -0
  52. package/dist/effects/texture.js +66 -0
  53. package/dist/effects/texture.js.map +1 -0
  54. package/dist/effects/vintage.d.ts +20 -0
  55. package/dist/effects/vintage.d.ts.map +1 -0
  56. package/dist/effects/vintage.js +47 -0
  57. package/dist/effects/vintage.js.map +1 -0
  58. package/dist/effects/zoom.d.ts +20 -0
  59. package/dist/effects/zoom.d.ts.map +1 -0
  60. package/dist/effects/zoom.js +65 -0
  61. package/dist/effects/zoom.js.map +1 -0
  62. package/dist/exporter.d.ts +24 -0
  63. package/dist/exporter.d.ts.map +1 -0
  64. package/dist/exporter.js +177 -0
  65. package/dist/exporter.js.map +1 -0
  66. package/dist/fills/conic-gradient.d.ts +12 -0
  67. package/dist/fills/conic-gradient.d.ts.map +1 -0
  68. package/dist/fills/conic-gradient.js +44 -0
  69. package/dist/fills/conic-gradient.js.map +1 -0
  70. package/dist/fills/filters/alpha.d.ts +9 -0
  71. package/dist/fills/filters/alpha.d.ts.map +1 -0
  72. package/dist/fills/filters/alpha.js +21 -0
  73. package/dist/fills/filters/alpha.js.map +1 -0
  74. package/dist/fills/filters/blur.d.ts +9 -0
  75. package/dist/fills/filters/blur.d.ts.map +1 -0
  76. package/dist/fills/filters/blur.js +12 -0
  77. package/dist/fills/filters/blur.js.map +1 -0
  78. package/dist/fills/filters/color-adjustment.d.ts +14 -0
  79. package/dist/fills/filters/color-adjustment.d.ts.map +1 -0
  80. package/dist/fills/filters/color-adjustment.js +147 -0
  81. package/dist/fills/filters/color-adjustment.js.map +1 -0
  82. package/dist/fills/filters/color-matrix.d.ts +9 -0
  83. package/dist/fills/filters/color-matrix.d.ts.map +1 -0
  84. package/dist/fills/filters/color-matrix.js +14 -0
  85. package/dist/fills/filters/color-matrix.js.map +1 -0
  86. package/dist/fills/filters/curves.d.ts +9 -0
  87. package/dist/fills/filters/curves.d.ts.map +1 -0
  88. package/dist/fills/filters/curves.js +89 -0
  89. package/dist/fills/filters/curves.js.map +1 -0
  90. package/dist/fills/filters/exposure.d.ts +9 -0
  91. package/dist/fills/filters/exposure.d.ts.map +1 -0
  92. package/dist/fills/filters/exposure.js +22 -0
  93. package/dist/fills/filters/exposure.js.map +1 -0
  94. package/dist/fills/filters/filter.d.ts +17 -0
  95. package/dist/fills/filters/filter.d.ts.map +1 -0
  96. package/dist/fills/filters/filter.js +16 -0
  97. package/dist/fills/filters/filter.js.map +1 -0
  98. package/dist/fills/filters/grayscale.d.ts +9 -0
  99. package/dist/fills/filters/grayscale.d.ts.map +1 -0
  100. package/dist/fills/filters/grayscale.js +25 -0
  101. package/dist/fills/filters/grayscale.js.map +1 -0
  102. package/dist/fills/filters/registry.d.ts +16 -0
  103. package/dist/fills/filters/registry.d.ts.map +1 -0
  104. package/dist/fills/filters/registry.js +50 -0
  105. package/dist/fills/filters/registry.js.map +1 -0
  106. package/dist/fills/gradient-cache.d.ts +29 -0
  107. package/dist/fills/gradient-cache.d.ts.map +1 -0
  108. package/dist/fills/gradient-cache.js +57 -0
  109. package/dist/fills/gradient-cache.js.map +1 -0
  110. package/dist/fills/handler.d.ts +49 -0
  111. package/dist/fills/handler.d.ts.map +1 -0
  112. package/dist/fills/handler.js +172 -0
  113. package/dist/fills/handler.js.map +1 -0
  114. package/dist/fills/image.d.ts +34 -0
  115. package/dist/fills/image.d.ts.map +1 -0
  116. package/dist/fills/image.js +91 -0
  117. package/dist/fills/image.js.map +1 -0
  118. package/dist/fills/linear-gradient.d.ts +12 -0
  119. package/dist/fills/linear-gradient.d.ts.map +1 -0
  120. package/dist/fills/linear-gradient.js +48 -0
  121. package/dist/fills/linear-gradient.js.map +1 -0
  122. package/dist/fills/noise.d.ts +11 -0
  123. package/dist/fills/noise.d.ts.map +1 -0
  124. package/dist/fills/noise.js +82 -0
  125. package/dist/fills/noise.js.map +1 -0
  126. package/dist/fills/radial-gradient.d.ts +9 -0
  127. package/dist/fills/radial-gradient.d.ts.map +1 -0
  128. package/dist/fills/radial-gradient.js +43 -0
  129. package/dist/fills/radial-gradient.js.map +1 -0
  130. package/dist/fills/registry.d.ts +10 -0
  131. package/dist/fills/registry.d.ts.map +1 -0
  132. package/dist/fills/registry.js +34 -0
  133. package/dist/fills/registry.js.map +1 -0
  134. package/dist/fills/renderer.d.ts +24 -0
  135. package/dist/fills/renderer.d.ts.map +1 -0
  136. package/dist/fills/renderer.js +5 -0
  137. package/dist/fills/renderer.js.map +1 -0
  138. package/dist/fills/solid.d.ts +7 -0
  139. package/dist/fills/solid.d.ts.map +1 -0
  140. package/dist/fills/solid.js +13 -0
  141. package/dist/fills/solid.js.map +1 -0
  142. package/dist/fills/stripe.d.ts +7 -0
  143. package/dist/fills/stripe.d.ts.map +1 -0
  144. package/dist/fills/stripe.js +85 -0
  145. package/dist/fills/stripe.js.map +1 -0
  146. package/dist/fills/video.d.ts +6 -0
  147. package/dist/fills/video.d.ts.map +1 -0
  148. package/dist/fills/video.js +14 -0
  149. package/dist/fills/video.js.map +1 -0
  150. package/dist/font-style.d.ts +23 -0
  151. package/dist/font-style.d.ts.map +1 -0
  152. package/dist/font-style.js +34 -0
  153. package/dist/font-style.js.map +1 -0
  154. package/dist/getter.d.ts +9 -0
  155. package/dist/getter.d.ts.map +1 -0
  156. package/dist/getter.js +26 -0
  157. package/dist/getter.js.map +1 -0
  158. package/dist/index.d.ts +9 -0
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +11 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/master-clock.d.ts +42 -0
  163. package/dist/master-clock.d.ts.map +1 -0
  164. package/dist/master-clock.js +134 -0
  165. package/dist/master-clock.js.map +1 -0
  166. package/dist/measure-scope.d.ts +14 -0
  167. package/dist/measure-scope.d.ts.map +1 -0
  168. package/dist/measure-scope.js +29 -0
  169. package/dist/measure-scope.js.map +1 -0
  170. package/dist/render-context.d.ts +107 -0
  171. package/dist/render-context.d.ts.map +1 -0
  172. package/dist/render-context.js +940 -0
  173. package/dist/render-context.js.map +1 -0
  174. package/dist/shapes/alpha-contour.d.ts +27 -0
  175. package/dist/shapes/alpha-contour.d.ts.map +1 -0
  176. package/dist/shapes/alpha-contour.js +330 -0
  177. package/dist/shapes/alpha-contour.js.map +1 -0
  178. package/dist/shapes/base.d.ts +46 -0
  179. package/dist/shapes/base.d.ts.map +1 -0
  180. package/dist/shapes/base.js +95 -0
  181. package/dist/shapes/base.js.map +1 -0
  182. package/dist/shapes/boolean.d.ts +28 -0
  183. package/dist/shapes/boolean.d.ts.map +1 -0
  184. package/dist/shapes/boolean.js +90 -0
  185. package/dist/shapes/boolean.js.map +1 -0
  186. package/dist/shapes/ellipse.d.ts +32 -0
  187. package/dist/shapes/ellipse.d.ts.map +1 -0
  188. package/dist/shapes/ellipse.js +50 -0
  189. package/dist/shapes/ellipse.js.map +1 -0
  190. package/dist/shapes/image.d.ts +66 -0
  191. package/dist/shapes/image.d.ts.map +1 -0
  192. package/dist/shapes/image.js +214 -0
  193. package/dist/shapes/image.js.map +1 -0
  194. package/dist/shapes/index.d.ts +67 -0
  195. package/dist/shapes/index.d.ts.map +1 -0
  196. package/dist/shapes/index.js +297 -0
  197. package/dist/shapes/index.js.map +1 -0
  198. package/dist/shapes/line.d.ts +25 -0
  199. package/dist/shapes/line.d.ts.map +1 -0
  200. package/dist/shapes/line.js +87 -0
  201. package/dist/shapes/line.js.map +1 -0
  202. package/dist/shapes/mask.d.ts +28 -0
  203. package/dist/shapes/mask.d.ts.map +1 -0
  204. package/dist/shapes/mask.js +106 -0
  205. package/dist/shapes/mask.js.map +1 -0
  206. package/dist/shapes/paragraph-layout.d.ts +64 -0
  207. package/dist/shapes/paragraph-layout.d.ts.map +1 -0
  208. package/dist/shapes/paragraph-layout.js +156 -0
  209. package/dist/shapes/paragraph-layout.js.map +1 -0
  210. package/dist/shapes/path.d.ts +29 -0
  211. package/dist/shapes/path.d.ts.map +1 -0
  212. package/dist/shapes/path.js +71 -0
  213. package/dist/shapes/path.js.map +1 -0
  214. package/dist/shapes/polygon.d.ts +33 -0
  215. package/dist/shapes/polygon.d.ts.map +1 -0
  216. package/dist/shapes/polygon.js +86 -0
  217. package/dist/shapes/polygon.js.map +1 -0
  218. package/dist/shapes/polygram.d.ts +34 -0
  219. package/dist/shapes/polygram.d.ts.map +1 -0
  220. package/dist/shapes/polygram.js +90 -0
  221. package/dist/shapes/polygram.js.map +1 -0
  222. package/dist/shapes/rect.d.ts +41 -0
  223. package/dist/shapes/rect.d.ts.map +1 -0
  224. package/dist/shapes/rect.js +111 -0
  225. package/dist/shapes/rect.js.map +1 -0
  226. package/dist/shapes/richtext.d.ts +28 -0
  227. package/dist/shapes/richtext.d.ts.map +1 -0
  228. package/dist/shapes/richtext.js +32 -0
  229. package/dist/shapes/richtext.js.map +1 -0
  230. package/dist/shapes/shape-handler.d.ts +79 -0
  231. package/dist/shapes/shape-handler.d.ts.map +1 -0
  232. package/dist/shapes/shape-handler.js +304 -0
  233. package/dist/shapes/shape-handler.js.map +1 -0
  234. package/dist/shapes/text.d.ts +13 -0
  235. package/dist/shapes/text.d.ts.map +1 -0
  236. package/dist/shapes/text.js +67 -0
  237. package/dist/shapes/text.js.map +1 -0
  238. package/dist/shapes/trim.d.ts +10 -0
  239. package/dist/shapes/trim.d.ts.map +1 -0
  240. package/dist/shapes/trim.js +49 -0
  241. package/dist/shapes/trim.js.map +1 -0
  242. package/dist/storage-adapter.d.ts +56 -0
  243. package/dist/storage-adapter.d.ts.map +1 -0
  244. package/dist/storage-adapter.js +188 -0
  245. package/dist/storage-adapter.js.map +1 -0
  246. package/dist/stroke/index.d.ts +34 -0
  247. package/dist/stroke/index.d.ts.map +1 -0
  248. package/dist/stroke/index.js +360 -0
  249. package/dist/stroke/index.js.map +1 -0
  250. package/dist/stroke/stroke-handler.d.ts +45 -0
  251. package/dist/stroke/stroke-handler.d.ts.map +1 -0
  252. package/dist/stroke/stroke-handler.js +371 -0
  253. package/dist/stroke/stroke-handler.js.map +1 -0
  254. package/dist/video/extract.d.ts +54 -0
  255. package/dist/video/extract.d.ts.map +1 -0
  256. package/dist/video/extract.js +192 -0
  257. package/dist/video/extract.js.map +1 -0
  258. package/dist/video/extract.worker.d.ts +50 -0
  259. package/dist/video/extract.worker.d.ts.map +1 -0
  260. package/dist/video/extract.worker.js +224 -0
  261. package/dist/video/extract.worker.js.map +1 -0
  262. package/package.json +57 -0
@@ -0,0 +1,24 @@
1
+ import type { CanvasKit, Image as CKImage, Paint } from "@motion-script/canvaskit";
2
+ import type { FillResolved } from "@motion-script/core";
3
+ import type { WebStorageAdapter } from "../storage-adapter";
4
+ import type { ShapeBounds } from "./handler";
5
+ export interface FillRendererContext {
6
+ canvasKit: CanvasKit;
7
+ paint: Paint;
8
+ assets: WebStorageAdapter;
9
+ getShapeBounds: () => ShapeBounds | null;
10
+ offscreenCanvas: HTMLCanvasElement | null;
11
+ offscreenCtx: CanvasRenderingContext2D | null;
12
+ /**
13
+ * CKImages the renderer materialized for this fill. The handler deletes
14
+ * them after the fill's shapes are drawn so GPU memory is bounded to one
15
+ * frame's worth of textures rather than the whole cached clip.
16
+ */
17
+ transientImages: CKImage[];
18
+ }
19
+ export declare abstract class FillRenderer<T extends FillResolved = FillResolved> {
20
+ abstract applyPaint(fill: T, ctx: FillRendererContext): boolean;
21
+ /** Release any persistent CanvasKit objects held by this renderer. */
22
+ dispose(): void;
23
+ }
24
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../src/fills/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,cAAc,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IACzC,eAAe,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1C,YAAY,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC9C;;;;OAIG;IACH,eAAe,EAAE,OAAO,EAAE,CAAC;CAC9B;AAED,8BAAsB,YAAY,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY;IACpE,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO;IAE/D,sEAAsE;IACtE,OAAO,IAAI,IAAI;CAClB"}
@@ -0,0 +1,5 @@
1
+ export class FillRenderer {
2
+ /** Release any persistent CanvasKit objects held by this renderer. */
3
+ dispose() { }
4
+ }
5
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/fills/renderer.ts"],"names":[],"mappings":"AAoBA,MAAM,OAAgB,YAAY;IAG9B,sEAAsE;IACtE,OAAO,KAAW,CAAC;CACtB"}
@@ -0,0 +1,7 @@
1
+ import type { SolidFillResolved } from "@motion-script/core";
2
+ import { FillRenderer, type FillRendererContext } from "./renderer";
3
+ /** Flat-color fill — sets paint color components directly, no shader. */
4
+ export declare class SolidFillRenderer extends FillRenderer<SolidFillResolved> {
5
+ applyPaint(fill: SolidFillResolved, ctx: FillRendererContext): boolean;
6
+ }
7
+ //# sourceMappingURL=solid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solid.d.ts","sourceRoot":"","sources":["../../src/fills/solid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEpE,yEAAyE;AACzE,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IAClE,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO;CAazE"}
@@ -0,0 +1,13 @@
1
+ import { FillRenderer } from "./renderer";
2
+ /** Flat-color fill — sets paint color components directly, no shader. */
3
+ export class SolidFillRenderer extends FillRenderer {
4
+ applyPaint(fill, ctx) {
5
+ // setColorComponents takes scalars directly (defaults to sRGB), avoiding
6
+ // the per-call Float32Array that Color4f()+setColor() allocates on the
7
+ // wasm heap every frame for every shape.
8
+ ctx.paint.setColorComponents(fill.color[0], fill.color[1], fill.color[2], fill.color[3] * (fill.opacity ?? 1));
9
+ ctx.paint.setShader(null);
10
+ return true;
11
+ }
12
+ }
13
+ //# sourceMappingURL=solid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solid.js","sourceRoot":"","sources":["../../src/fills/solid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA4B,MAAM,YAAY,CAAC;AAEpE,yEAAyE;AACzE,MAAM,OAAO,iBAAkB,SAAQ,YAA+B;IAClE,UAAU,CAAC,IAAuB,EAAE,GAAwB;QACxD,yEAAyE;QACzE,uEAAuE;QACvE,yCAAyC;QACzC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CACxB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EACb,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EACb,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EACb,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CACtC,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}
@@ -0,0 +1,7 @@
1
+ import type { StripeFillResolved } from "@motion-script/core";
2
+ import { FillRenderer, type FillRendererContext } from "./renderer";
3
+ /** Renders a repeating diagonal-stripe pattern from a cached single-tile image. */
4
+ export declare class StripeFillRenderer extends FillRenderer<StripeFillResolved> {
5
+ applyPaint(fill: StripeFillResolved, ctx: FillRendererContext): boolean;
6
+ }
7
+ //# sourceMappingURL=stripe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../src/fills/stripe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AA6EpE,mFAAmF;AACnF,qBAAa,kBAAmB,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IACpE,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO;CAiC1E"}
@@ -0,0 +1,85 @@
1
+ import { FillRenderer } from "./renderer";
2
+ const stripeCache = new Map();
3
+ function buildCacheKey(fill) {
4
+ const gap = fill.gap ?? 8;
5
+ const sw = fill.strokeWidth ?? 1;
6
+ const [r, g, b, a] = fill.color ?? [0, 0, 0, 1];
7
+ return `${gap}|${sw}|${r},${g},${b},${a}`;
8
+ }
9
+ /**
10
+ * Renders a stripe tile onto the offscreen 2D canvas — no rotation applied.
11
+ * The tile is `gap × gap` pixels with a single vertical line of `strokeWidth`
12
+ * at x = strokeWidth/2 (same clip-prevention offset as the SVG component).
13
+ * Rotation is handled by the CanvasKit shader matrix in applyPaint.
14
+ */
15
+ function renderStripeTile(fill, offscreen, offscreenCtx, ck) {
16
+ const gap = fill.gap ?? 8;
17
+ const sw = fill.strokeWidth ?? 1;
18
+ const [cr, cg, cb, ca] = fill.color ?? [0, 0, 0, 1];
19
+ const cssColor = `rgba(${Math.round(cr * 255)},${Math.round(cg * 255)},${Math.round(cb * 255)},${ca})`;
20
+ offscreen.width = gap;
21
+ offscreen.height = gap;
22
+ offscreenCtx.clearRect(0, 0, gap, gap);
23
+ offscreenCtx.strokeStyle = cssColor;
24
+ offscreenCtx.lineWidth = sw;
25
+ // Vertical line at x = sw/2 — same as SVG x1={offset}
26
+ const offset = sw / 2;
27
+ offscreenCtx.beginPath();
28
+ offscreenCtx.moveTo(offset, 0);
29
+ offscreenCtx.lineTo(offset, gap);
30
+ offscreenCtx.stroke();
31
+ const imageData = offscreenCtx.getImageData(0, 0, gap, gap);
32
+ return ck.MakeImage({
33
+ width: gap,
34
+ height: gap,
35
+ alphaType: ck.AlphaType.Unpremul,
36
+ colorType: ck.ColorType.RGBA_8888,
37
+ colorSpace: ck.ColorSpace.SRGB,
38
+ }, imageData.data, 4 * gap);
39
+ }
40
+ /**
41
+ * Builds a 3×3 affine matrix (row-major, as CanvasKit expects) that:
42
+ * 1. Rotates by `angleDeg` around the shape's top-left corner
43
+ * 2. Translates so the pattern starts at the shape origin
44
+ *
45
+ * This is equivalent to SVG patternTransform="rotate(angle)" — the tile
46
+ * itself is axis-aligned; CanvasKit rotates the repeating space.
47
+ */
48
+ function makeRotatedMatrix(angleDeg, tx, ty) {
49
+ const rad = (angleDeg * Math.PI) / 180;
50
+ const cos = Math.cos(rad);
51
+ const sin = Math.sin(rad);
52
+ // Rotate around (tx, ty): translate to origin, rotate, translate back
53
+ return [
54
+ cos, -sin, tx - cos * tx + sin * ty,
55
+ sin, cos, ty - sin * tx - cos * ty,
56
+ 0, 0, 1,
57
+ ];
58
+ }
59
+ /** Renders a repeating diagonal-stripe pattern from a cached single-tile image. */
60
+ export class StripeFillRenderer extends FillRenderer {
61
+ applyPaint(fill, ctx) {
62
+ if (!ctx.offscreenCanvas) {
63
+ ctx.offscreenCanvas = document.createElement("canvas");
64
+ ctx.offscreenCtx = ctx.offscreenCanvas.getContext("2d");
65
+ }
66
+ if (!ctx.offscreenCtx)
67
+ return false;
68
+ const key = buildCacheKey(fill);
69
+ let img = stripeCache.get(key);
70
+ if (!img) {
71
+ img = renderStripeTile(fill, ctx.offscreenCanvas, ctx.offscreenCtx, ctx.canvasKit);
72
+ if (!img)
73
+ return false;
74
+ stripeCache.set(key, img);
75
+ }
76
+ const bounds = ctx.getShapeBounds();
77
+ const tx = bounds?.left ?? 0;
78
+ const ty = bounds?.top ?? 0;
79
+ const angle = fill.angle ?? -45;
80
+ const matrix = makeRotatedMatrix(angle, tx, ty);
81
+ ctx.paint.setShader(img.makeShaderOptions(ctx.canvasKit.TileMode.Repeat, ctx.canvasKit.TileMode.Repeat, ctx.canvasKit.FilterMode.Linear, ctx.canvasKit.MipmapMode.None, matrix));
82
+ return true;
83
+ }
84
+ }
85
+ //# sourceMappingURL=stripe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../src/fills/stripe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { VideoFillResolved } from "@motion-script/core";
2
+ import { FillRenderer, type FillRendererContext } from "./renderer";
3
+ export declare class VideoFillRenderer extends FillRenderer<VideoFillResolved> {
4
+ applyPaint(fill: VideoFillResolved, ctx: FillRendererContext): boolean;
5
+ }
6
+ //# sourceMappingURL=video.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../src/fills/video.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGpE,qBAAa,iBAAkB,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IAClE,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO;CAQzE"}
@@ -0,0 +1,14 @@
1
+ import { FillRenderer } from "./renderer";
2
+ import { makeImageShader, applyMediaFilters } from "./image";
3
+ export class VideoFillRenderer extends FillRenderer {
4
+ applyPaint(fill, ctx) {
5
+ const frame = ctx.assets.getVideoFrame(fill.src, fill.timestamp * 1_000_000);
6
+ if (!frame)
7
+ return false;
8
+ // Adapter-owned CKImage — see ImageFillRenderer for rationale.
9
+ ctx.paint.setShader(makeImageShader(frame, fill, ctx.canvasKit, ctx.getShapeBounds()));
10
+ applyMediaFilters(fill, ctx);
11
+ return true;
12
+ }
13
+ }
14
+ //# sourceMappingURL=video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/fills/video.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA4B,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE7D,MAAM,OAAO,iBAAkB,SAAQ,YAA+B;IAClE,UAAU,CAAC,IAAuB,EAAE,GAAwB;QACxD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,GAAI,EAAE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;QAC9E,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,+DAA+D;QAC/D,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;QACvF,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}
@@ -0,0 +1,23 @@
1
+ import type { CanvasKit, FontStyle, Typeface, TypefaceFontProvider } from "@motion-script/canvaskit";
2
+ /**
3
+ * Build a CanvasKit {@link FontStyle} from a numeric CSS font weight (100–900)
4
+ * and an optional italic flag. Skia's font matcher reads the `weight`/`slant`
5
+ * fields off this style and picks the closest registered typeface for the
6
+ * family — this is what makes any `fontWeight` resolve to the nearest available
7
+ * weight file rather than requiring an exact `family@weight` registration.
8
+ */
9
+ export declare function toFontStyle(canvasKit: CanvasKit, fontWeight: number, italic?: boolean): FontStyle;
10
+ /**
11
+ * Resolve the closest registered typeface for a family at the requested weight
12
+ * and slant. Fonts are registered under their bare family name (see
13
+ * {@link WebStorageAdapter.loadFont}), so the provider holds every weight of a
14
+ * family and Skia selects the nearest *static* file match.
15
+ *
16
+ * Note: this matcher does NOT instantiate a variable font's `wght` axis — it
17
+ * returns the default instance regardless of requested weight. Paragraph text
18
+ * gets continuous variable weight through the layout path instead (which passes
19
+ * `fontVariations` and draws with the run's positioned typeface); see
20
+ * {@link layoutParagraph}. This helper remains for static-family matching.
21
+ */
22
+ export declare function resolveTypeface(canvasKit: CanvasKit, fontMgr: TypefaceFontProvider, fontFamily: string, fontWeight: number, italic?: boolean): Typeface | null;
23
+ //# sourceMappingURL=font-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-style.d.ts","sourceRoot":"","sources":["../src/font-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErG;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,SAAS,CAU/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC3B,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,oBAAoB,EAC7B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,UAAQ,GACf,QAAQ,GAAG,IAAI,CAEjB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Build a CanvasKit {@link FontStyle} from a numeric CSS font weight (100–900)
3
+ * and an optional italic flag. Skia's font matcher reads the `weight`/`slant`
4
+ * fields off this style and picks the closest registered typeface for the
5
+ * family — this is what makes any `fontWeight` resolve to the nearest available
6
+ * weight file rather than requiring an exact `family@weight` registration.
7
+ */
8
+ export function toFontStyle(canvasKit, fontWeight, italic = false) {
9
+ // FontWeight enum entities carry their numeric CSS weight as `.value`, so a
10
+ // raw numeric weight can be passed straight through. We still clamp to the
11
+ // valid CSS range so an out-of-range tween value can't confuse the matcher.
12
+ const weight = { value: Math.max(1, Math.min(1000, Math.round(fontWeight))) };
13
+ return {
14
+ weight,
15
+ slant: italic ? canvasKit.FontSlant.Italic : canvasKit.FontSlant.Upright,
16
+ width: canvasKit.FontWidth.Normal,
17
+ };
18
+ }
19
+ /**
20
+ * Resolve the closest registered typeface for a family at the requested weight
21
+ * and slant. Fonts are registered under their bare family name (see
22
+ * {@link WebStorageAdapter.loadFont}), so the provider holds every weight of a
23
+ * family and Skia selects the nearest *static* file match.
24
+ *
25
+ * Note: this matcher does NOT instantiate a variable font's `wght` axis — it
26
+ * returns the default instance regardless of requested weight. Paragraph text
27
+ * gets continuous variable weight through the layout path instead (which passes
28
+ * `fontVariations` and draws with the run's positioned typeface); see
29
+ * {@link layoutParagraph}. This helper remains for static-family matching.
30
+ */
31
+ export function resolveTypeface(canvasKit, fontMgr, fontFamily, fontWeight, italic = false) {
32
+ return fontMgr.matchFamilyStyle(fontFamily, toFontStyle(canvasKit, fontWeight, italic));
33
+ }
34
+ //# sourceMappingURL=font-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-style.js","sourceRoot":"","sources":["../src/font-style.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,SAAoB,EAAE,UAAkB,EAAE,MAAM,GAAG,KAAK;IAChF,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAyB,CAAC;IACrG,OAAO;QACH,MAAM;QACN,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO;QACxE,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM;KACpC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAC3B,SAAoB,EACpB,OAA6B,EAC7B,UAAkB,EAClB,UAAkB,EAClB,MAAM,GAAG,KAAK;IAEd,OAAO,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,WAAW,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5F,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type CanvasKit } from "@motion-script/canvaskit";
2
+ /**
3
+ * Loads and caches the CanvasKit wasm module (memoized — concurrent callers
4
+ * share the same init promise, and once resolved every call returns the same
5
+ * instance). `wasmUrl` defaults to a CDN so consumers don't have to host the
6
+ * binary themselves; pass a local URL to use the bundled/copied wasm instead.
7
+ */
8
+ export declare function getCanvasKit(wasmUrl?: string): Promise<CanvasKit>;
9
+ //# sourceMappingURL=getter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getter.d.ts","sourceRoot":"","sources":["../src/getter.ts"],"names":[],"mappings":"AACA,OAAsB,EAAE,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAQzE;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,MAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAWpF"}
package/dist/getter.js ADDED
@@ -0,0 +1,26 @@
1
+ // @motion-script/core/src/engine.ts
2
+ import CanvasKitInit from "@motion-script/canvaskit";
3
+ let canvasKit = null;
4
+ let initPromise = null;
5
+ // Default to unpkg so beginners don't have to configure anything
6
+ const DEFAULT_CDN = "https://unpkg.com/canvaskit-wasm@latest/bin/canvaskit.wasm";
7
+ /**
8
+ * Loads and caches the CanvasKit wasm module (memoized — concurrent callers
9
+ * share the same init promise, and once resolved every call returns the same
10
+ * instance). `wasmUrl` defaults to a CDN so consumers don't have to host the
11
+ * binary themselves; pass a local URL to use the bundled/copied wasm instead.
12
+ */
13
+ export async function getCanvasKit(wasmUrl = DEFAULT_CDN) {
14
+ if (canvasKit)
15
+ return canvasKit;
16
+ if (initPromise)
17
+ return initPromise;
18
+ initPromise = CanvasKitInit({
19
+ locateFile: () => wasmUrl,
20
+ }).then((ck) => {
21
+ canvasKit = ck;
22
+ return ck;
23
+ });
24
+ return initPromise;
25
+ }
26
+ //# sourceMappingURL=getter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getter.js","sourceRoot":"","sources":["../src/getter.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,aAAiC,MAAM,0BAA0B,CAAC;AAEzE,IAAI,SAAS,GAAqB,IAAI,CAAC;AACvC,IAAI,WAAW,GAA8B,IAAI,CAAC;AAElD,iEAAiE;AACjE,MAAM,WAAW,GAAG,4DAA4D,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB,WAAW;IAC5D,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,WAAW,GAAG,aAAa,CAAC;QACxB,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO;KAC5B,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE;QACX,SAAS,GAAG,EAAE,CAAC;QACf,OAAO,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO,WAAW,CAAC;AACvB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export { WebRenderContext } from "./render-context";
2
+ export { WebStorageAdapter } from "./storage-adapter";
3
+ export { getCanvasKit } from "./getter";
4
+ export { CanvasKitEffect, CanvasKitEffectRegistry } from "./effects";
5
+ export { exportScenesAsVideo, type ExportParams, type ExportProgressCallback } from "./exporter";
6
+ export { WebAudioDevice as WebAudioPlayer } from "./audio/player";
7
+ export { WebMeasureScope } from "./measure-scope";
8
+ export { WebMasterClock } from "./master-clock";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,KAAK,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,cAAc,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ // @motion-script/web — CanvasKit/Skia-based renderer for @motion-script/core,
2
+ // running in the browser (canvas mount, video export, audio playback/clock).
3
+ export { WebRenderContext } from "./render-context";
4
+ export { WebStorageAdapter } from "./storage-adapter";
5
+ export { getCanvasKit } from "./getter";
6
+ export { CanvasKitEffect, CanvasKitEffectRegistry } from "./effects";
7
+ export { exportScenesAsVideo } from "./exporter";
8
+ export { WebAudioDevice as WebAudioPlayer } from "./audio/player";
9
+ export { WebMeasureScope } from "./measure-scope";
10
+ export { WebMasterClock } from "./master-clock";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAE7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAkD,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,cAAc,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { MasterClock } from "@motion-script/core";
2
+ /**
3
+ * MasterClock backed by a Web Audio AudioContext. Scene time advances in
4
+ * lock-step with `audioContext.currentTime`, so any AudioBufferSourceNodes
5
+ * scheduled on the same context play perfectly in sync.
6
+ *
7
+ * When paused we suspend the context (audio stops, currentTime freezes);
8
+ * when playing we resume and a rAF loop publishes ticks at the target fps.
9
+ *
10
+ * A single silent buffer covering the full timeline is started on play(),
11
+ * which keeps the context active and gives the browser a stable audio
12
+ * graph to schedule against even on scenes that contain no audio nodes.
13
+ */
14
+ export declare class WebMasterClock extends MasterClock {
15
+ private context;
16
+ private ownsContext;
17
+ private fps;
18
+ private playStartCtxTime;
19
+ private seekOffset;
20
+ private speed;
21
+ private reverse;
22
+ private rafId;
23
+ private silentSource;
24
+ constructor(opts: {
25
+ context?: AudioContext;
26
+ fps: number;
27
+ });
28
+ getContext(): AudioContext;
29
+ seek(t: number): void;
30
+ /** Resumes the (possibly suspended) context, anchors elapsed-time tracking to the current `context.currentTime`, and starts the silent ticker + rAF tick loop. */
31
+ play(speed?: number, reverse?: boolean): Promise<void>;
32
+ /** Stops the tick loop and silent ticker, then suspends the context — freezing `currentTime` so elapsed-time math stays correct across the pause. */
33
+ pause(): void;
34
+ /** (Re)starts the silent buffer source covering the remaining timeline — keeps the AudioContext active and gives a stable graph for other AudioBufferSourceNodes to schedule against, per the class-level note. */
35
+ private startSilentTicker;
36
+ private stopSilentTicker;
37
+ /** Drives ticks off `requestAnimationFrame`, deriving scene time from elapsed `context.currentTime` (so it stays sample-accurate) and only firing `tick()` when a full frame interval has elapsed. */
38
+ private startLoop;
39
+ private stopLoop;
40
+ dispose(): void;
41
+ }
42
+ //# sourceMappingURL=master-clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-clock.d.ts","sourceRoot":"","sources":["../src/master-clock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAC3C,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,GAAG,CAAS;IAEpB,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAkB;IAEjC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,YAAY,CAAsC;gBAE9C,IAAI,EAAE;QAAE,OAAO,CAAC,EAAE,YAAY,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAOzD,UAAU,IAAI,YAAY;IAI1B,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAOrB,kKAAkK;IAC5J,IAAI,CAAC,KAAK,GAAE,MAAU,EAAE,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAetE,qJAAqJ;IACrJ,KAAK,IAAI,IAAI;IAUb,mNAAmN;IACnN,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,gBAAgB;IAaxB,sMAAsM;IACtM,OAAO,CAAC,SAAS;IAkCjB,OAAO,CAAC,QAAQ;IAOhB,OAAO,IAAI,IAAI;CAQlB"}
@@ -0,0 +1,134 @@
1
+ import { MasterClock } from "@motion-script/core";
2
+ /**
3
+ * MasterClock backed by a Web Audio AudioContext. Scene time advances in
4
+ * lock-step with `audioContext.currentTime`, so any AudioBufferSourceNodes
5
+ * scheduled on the same context play perfectly in sync.
6
+ *
7
+ * When paused we suspend the context (audio stops, currentTime freezes);
8
+ * when playing we resume and a rAF loop publishes ticks at the target fps.
9
+ *
10
+ * A single silent buffer covering the full timeline is started on play(),
11
+ * which keeps the context active and gives the browser a stable audio
12
+ * graph to schedule against even on scenes that contain no audio nodes.
13
+ */
14
+ export class WebMasterClock extends MasterClock {
15
+ context;
16
+ ownsContext;
17
+ fps;
18
+ playStartCtxTime = 0;
19
+ seekOffset = 0;
20
+ speed = 1;
21
+ reverse = false;
22
+ rafId = null;
23
+ silentSource = null;
24
+ constructor(opts) {
25
+ super();
26
+ this.context = opts.context ?? new AudioContext();
27
+ this.ownsContext = !opts.context;
28
+ this.fps = opts.fps;
29
+ }
30
+ getContext() {
31
+ return this.context;
32
+ }
33
+ seek(t) {
34
+ const clamped = Math.max(0, Math.min(t, this.duration));
35
+ this.seekOffset = clamped;
36
+ this.playStartCtxTime = this.context.currentTime;
37
+ this.setCurrentTime(clamped);
38
+ }
39
+ /** Resumes the (possibly suspended) context, anchors elapsed-time tracking to the current `context.currentTime`, and starts the silent ticker + rAF tick loop. */
40
+ async play(speed = 1, reverse = false) {
41
+ this.speed = speed;
42
+ this.reverse = reverse;
43
+ this.seekOffset = this.currentTime;
44
+ if (this.context.state === "suspended") {
45
+ await this.context.resume();
46
+ }
47
+ this.playStartCtxTime = this.context.currentTime;
48
+ this.startSilentTicker();
49
+ super.play(speed, reverse);
50
+ this.startLoop();
51
+ }
52
+ /** Stops the tick loop and silent ticker, then suspends the context — freezing `currentTime` so elapsed-time math stays correct across the pause. */
53
+ pause() {
54
+ this.seekOffset = this.currentTime;
55
+ this.stopLoop();
56
+ this.stopSilentTicker();
57
+ if (this.context.state === "running") {
58
+ this.context.suspend();
59
+ }
60
+ super.pause();
61
+ }
62
+ /** (Re)starts the silent buffer source covering the remaining timeline — keeps the AudioContext active and gives a stable graph for other AudioBufferSourceNodes to schedule against, per the class-level note. */
63
+ startSilentTicker() {
64
+ this.stopSilentTicker();
65
+ const remaining = Math.max(0.001, this.duration - this.seekOffset);
66
+ const sampleRate = this.context.sampleRate;
67
+ const buffer = this.context.createBuffer(1, Math.ceil(remaining * sampleRate), sampleRate);
68
+ const source = this.context.createBufferSource();
69
+ source.buffer = buffer;
70
+ source.connect(this.context.destination);
71
+ source.start();
72
+ this.silentSource = source;
73
+ }
74
+ stopSilentTicker() {
75
+ if (this.silentSource) {
76
+ try {
77
+ this.silentSource.onended = null;
78
+ this.silentSource.stop();
79
+ this.silentSource.disconnect();
80
+ }
81
+ catch {
82
+ // already stopped
83
+ }
84
+ this.silentSource = null;
85
+ }
86
+ }
87
+ /** Drives ticks off `requestAnimationFrame`, deriving scene time from elapsed `context.currentTime` (so it stays sample-accurate) and only firing `tick()` when a full frame interval has elapsed. */
88
+ startLoop() {
89
+ if (this.rafId !== null)
90
+ return;
91
+ const frameDt = 1 / this.fps;
92
+ let lastTickTime = this.currentTime;
93
+ const loop = async () => {
94
+ const elapsed = (this.context.currentTime - this.playStartCtxTime) * this.speed;
95
+ const next = this.reverse
96
+ ? this.seekOffset - elapsed
97
+ : this.seekOffset + elapsed;
98
+ const clamped = Math.max(0, Math.min(next, this.duration));
99
+ this.setCurrentTime(clamped);
100
+ if (Math.abs(clamped - lastTickTime) >= frameDt) {
101
+ lastTickTime = clamped;
102
+ // Await so that a slow tick (asset load on a scene
103
+ // boundary) doesn't queue a second concurrent tick.
104
+ await this.tick();
105
+ }
106
+ const ended = this.reverse ? clamped <= 0 : clamped >= this.duration;
107
+ if (ended) {
108
+ this.rafId = null;
109
+ return;
110
+ }
111
+ // If pause() cleared the rafId while we were awaiting tick(),
112
+ // do not resume the loop.
113
+ if (this.rafId === null)
114
+ return;
115
+ this.rafId = requestAnimationFrame(loop);
116
+ };
117
+ this.rafId = requestAnimationFrame(loop);
118
+ }
119
+ stopLoop() {
120
+ if (this.rafId !== null) {
121
+ cancelAnimationFrame(this.rafId);
122
+ this.rafId = null;
123
+ }
124
+ }
125
+ dispose() {
126
+ this.stopLoop();
127
+ this.stopSilentTicker();
128
+ if (this.ownsContext) {
129
+ this.context.close();
130
+ }
131
+ super.dispose();
132
+ }
133
+ }
134
+ //# sourceMappingURL=master-clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-clock.js","sourceRoot":"","sources":["../src/master-clock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { FontStyle, MeasureScope } from "@motion-script/core";
2
+ import { WebStorageAdapter } from "./storage-adapter";
3
+ /**
4
+ * {@link MeasureScope} implementation used by layout (auto/hug sizing) to
5
+ * measure text width before drawing — routes through the same paragraph
6
+ * layout path as rendering so the measured width matches the drawn width
7
+ * exactly, including letter-spacing and font-matching behavior.
8
+ */
9
+ export declare class WebMeasureScope extends MeasureScope {
10
+ private storageAdapter;
11
+ constructor(storageAdapter: WebStorageAdapter);
12
+ measureText(text: string, fontSize: number, fontFamily: string, fontWeight?: number, letterSpacing?: number, fontStyle?: FontStyle): number;
13
+ }
14
+ //# sourceMappingURL=measure-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure-scope.d.ts","sourceRoot":"","sources":["../src/measure-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC7C,OAAO,CAAC,cAAc,CAAoB;gBAE9B,cAAc,EAAE,iBAAiB;IAK7C,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY,EAAE,aAAa,GAAE,MAAU,EAAE,SAAS,GAAE,SAAoB,GAAG,MAAM;CAgBhK"}
@@ -0,0 +1,29 @@
1
+ import { MeasureScope } from "@motion-script/core";
2
+ import { layoutParagraph } from "./shapes/paragraph-layout";
3
+ /**
4
+ * {@link MeasureScope} implementation used by layout (auto/hug sizing) to
5
+ * measure text width before drawing — routes through the same paragraph
6
+ * layout path as rendering so the measured width matches the drawn width
7
+ * exactly, including letter-spacing and font-matching behavior.
8
+ */
9
+ export class WebMeasureScope extends MeasureScope {
10
+ storageAdapter;
11
+ constructor(storageAdapter) {
12
+ super();
13
+ this.storageAdapter = storageAdapter;
14
+ }
15
+ measureText(text, fontSize, fontFamily, fontWeight = 400, letterSpacing = 0, fontStyle = 'normal') {
16
+ if (text.length === 0)
17
+ return 0;
18
+ const ck = this.storageAdapter.getCanvasKit();
19
+ const fontMgr = this.storageAdapter.getFontMgr();
20
+ // Measure through the same paragraph layout used to render, so hug/auto
21
+ // sizing matches the drawn width exactly (incl. letter spacing semantics).
22
+ const layout = layoutParagraph(ck, fontMgr, [{ text, fontFamily, fontSize, fontWeight, letterSpacing, fontStyle }], { align: 'center', lineHeight: 1, maxWidth: Infinity, originX: 0, originY: 0 });
23
+ const w = layout.width;
24
+ for (const f of layout.fonts)
25
+ f.delete();
26
+ return w;
27
+ }
28
+ }
29
+ //# sourceMappingURL=measure-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure-scope.js","sourceRoot":"","sources":["../src/measure-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,OAAO,eAAgB,SAAQ,YAAY;IACrC,cAAc,CAAoB;IAE1C,YAAY,cAAiC;QACzC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,IAAY,EAAE,QAAgB,EAAE,UAAkB,EAAE,aAAqB,GAAG,EAAE,gBAAwB,CAAC,EAAE,YAAuB,QAAQ;QAChJ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAChC,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QACjD,wEAAwE;QACxE,2EAA2E;QAC3E,MAAM,MAAM,GAAG,eAAe,CAC1B,EAAE,EACF,OAAO,EACP,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,EACtE,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CACjF,CAAC;QACF,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;QACvB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK;YAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACzC,OAAO,CAAC,CAAC;IACb,CAAC;CACJ"}