@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.
- package/README.md +47 -0
- package/dist/audio/player.d.ts +43 -0
- package/dist/audio/player.d.ts.map +1 -0
- package/dist/audio/player.js +165 -0
- package/dist/audio/player.js.map +1 -0
- package/dist/effects/bloom.d.ts +19 -0
- package/dist/effects/bloom.d.ts.map +1 -0
- package/dist/effects/bloom.js +64 -0
- package/dist/effects/bloom.js.map +1 -0
- package/dist/effects/blur.d.ts +8 -0
- package/dist/effects/blur.d.ts.map +1 -0
- package/dist/effects/blur.js +12 -0
- package/dist/effects/blur.js.map +1 -0
- package/dist/effects/bulge-pinch.d.ts +20 -0
- package/dist/effects/bulge-pinch.d.ts.map +1 -0
- package/dist/effects/bulge-pinch.js +86 -0
- package/dist/effects/bulge-pinch.js.map +1 -0
- package/dist/effects/chromatic-aberration.d.ts +19 -0
- package/dist/effects/chromatic-aberration.d.ts.map +1 -0
- package/dist/effects/chromatic-aberration.js +59 -0
- package/dist/effects/chromatic-aberration.js.map +1 -0
- package/dist/effects/effect.d.ts +32 -0
- package/dist/effects/effect.d.ts.map +1 -0
- package/dist/effects/effect.js +22 -0
- package/dist/effects/effect.js.map +1 -0
- package/dist/effects/grayscale.d.ts +12 -0
- package/dist/effects/grayscale.d.ts.map +1 -0
- package/dist/effects/grayscale.js +31 -0
- package/dist/effects/grayscale.js.map +1 -0
- package/dist/effects/index.d.ts +13 -0
- package/dist/effects/index.d.ts.map +1 -0
- package/dist/effects/index.js +13 -0
- package/dist/effects/index.js.map +1 -0
- package/dist/effects/pixelate.d.ts +23 -0
- package/dist/effects/pixelate.d.ts.map +1 -0
- package/dist/effects/pixelate.js +37 -0
- package/dist/effects/pixelate.js.map +1 -0
- package/dist/effects/registry.d.ts +17 -0
- package/dist/effects/registry.d.ts.map +1 -0
- package/dist/effects/registry.js +56 -0
- package/dist/effects/registry.js.map +1 -0
- package/dist/effects/sksl-cache.d.ts +6 -0
- package/dist/effects/sksl-cache.d.ts.map +1 -0
- package/dist/effects/sksl-cache.js +21 -0
- package/dist/effects/sksl-cache.js.map +1 -0
- package/dist/effects/sksl-layer.d.ts +30 -0
- package/dist/effects/sksl-layer.d.ts.map +1 -0
- package/dist/effects/sksl-layer.js +82 -0
- package/dist/effects/sksl-layer.js.map +1 -0
- package/dist/effects/texture.d.ts +31 -0
- package/dist/effects/texture.d.ts.map +1 -0
- package/dist/effects/texture.js +66 -0
- package/dist/effects/texture.js.map +1 -0
- package/dist/effects/vintage.d.ts +20 -0
- package/dist/effects/vintage.d.ts.map +1 -0
- package/dist/effects/vintage.js +47 -0
- package/dist/effects/vintage.js.map +1 -0
- package/dist/effects/zoom.d.ts +20 -0
- package/dist/effects/zoom.d.ts.map +1 -0
- package/dist/effects/zoom.js +65 -0
- package/dist/effects/zoom.js.map +1 -0
- package/dist/exporter.d.ts +24 -0
- package/dist/exporter.d.ts.map +1 -0
- package/dist/exporter.js +177 -0
- package/dist/exporter.js.map +1 -0
- package/dist/fills/conic-gradient.d.ts +12 -0
- package/dist/fills/conic-gradient.d.ts.map +1 -0
- package/dist/fills/conic-gradient.js +44 -0
- package/dist/fills/conic-gradient.js.map +1 -0
- package/dist/fills/filters/alpha.d.ts +9 -0
- package/dist/fills/filters/alpha.d.ts.map +1 -0
- package/dist/fills/filters/alpha.js +21 -0
- package/dist/fills/filters/alpha.js.map +1 -0
- package/dist/fills/filters/blur.d.ts +9 -0
- package/dist/fills/filters/blur.d.ts.map +1 -0
- package/dist/fills/filters/blur.js +12 -0
- package/dist/fills/filters/blur.js.map +1 -0
- package/dist/fills/filters/color-adjustment.d.ts +14 -0
- package/dist/fills/filters/color-adjustment.d.ts.map +1 -0
- package/dist/fills/filters/color-adjustment.js +147 -0
- package/dist/fills/filters/color-adjustment.js.map +1 -0
- package/dist/fills/filters/color-matrix.d.ts +9 -0
- package/dist/fills/filters/color-matrix.d.ts.map +1 -0
- package/dist/fills/filters/color-matrix.js +14 -0
- package/dist/fills/filters/color-matrix.js.map +1 -0
- package/dist/fills/filters/curves.d.ts +9 -0
- package/dist/fills/filters/curves.d.ts.map +1 -0
- package/dist/fills/filters/curves.js +89 -0
- package/dist/fills/filters/curves.js.map +1 -0
- package/dist/fills/filters/exposure.d.ts +9 -0
- package/dist/fills/filters/exposure.d.ts.map +1 -0
- package/dist/fills/filters/exposure.js +22 -0
- package/dist/fills/filters/exposure.js.map +1 -0
- package/dist/fills/filters/filter.d.ts +17 -0
- package/dist/fills/filters/filter.d.ts.map +1 -0
- package/dist/fills/filters/filter.js +16 -0
- package/dist/fills/filters/filter.js.map +1 -0
- package/dist/fills/filters/grayscale.d.ts +9 -0
- package/dist/fills/filters/grayscale.d.ts.map +1 -0
- package/dist/fills/filters/grayscale.js +25 -0
- package/dist/fills/filters/grayscale.js.map +1 -0
- package/dist/fills/filters/registry.d.ts +16 -0
- package/dist/fills/filters/registry.d.ts.map +1 -0
- package/dist/fills/filters/registry.js +50 -0
- package/dist/fills/filters/registry.js.map +1 -0
- package/dist/fills/gradient-cache.d.ts +29 -0
- package/dist/fills/gradient-cache.d.ts.map +1 -0
- package/dist/fills/gradient-cache.js +57 -0
- package/dist/fills/gradient-cache.js.map +1 -0
- package/dist/fills/handler.d.ts +49 -0
- package/dist/fills/handler.d.ts.map +1 -0
- package/dist/fills/handler.js +172 -0
- package/dist/fills/handler.js.map +1 -0
- package/dist/fills/image.d.ts +34 -0
- package/dist/fills/image.d.ts.map +1 -0
- package/dist/fills/image.js +91 -0
- package/dist/fills/image.js.map +1 -0
- package/dist/fills/linear-gradient.d.ts +12 -0
- package/dist/fills/linear-gradient.d.ts.map +1 -0
- package/dist/fills/linear-gradient.js +48 -0
- package/dist/fills/linear-gradient.js.map +1 -0
- package/dist/fills/noise.d.ts +11 -0
- package/dist/fills/noise.d.ts.map +1 -0
- package/dist/fills/noise.js +82 -0
- package/dist/fills/noise.js.map +1 -0
- package/dist/fills/radial-gradient.d.ts +9 -0
- package/dist/fills/radial-gradient.d.ts.map +1 -0
- package/dist/fills/radial-gradient.js +43 -0
- package/dist/fills/radial-gradient.js.map +1 -0
- package/dist/fills/registry.d.ts +10 -0
- package/dist/fills/registry.d.ts.map +1 -0
- package/dist/fills/registry.js +34 -0
- package/dist/fills/registry.js.map +1 -0
- package/dist/fills/renderer.d.ts +24 -0
- package/dist/fills/renderer.d.ts.map +1 -0
- package/dist/fills/renderer.js +5 -0
- package/dist/fills/renderer.js.map +1 -0
- package/dist/fills/solid.d.ts +7 -0
- package/dist/fills/solid.d.ts.map +1 -0
- package/dist/fills/solid.js +13 -0
- package/dist/fills/solid.js.map +1 -0
- package/dist/fills/stripe.d.ts +7 -0
- package/dist/fills/stripe.d.ts.map +1 -0
- package/dist/fills/stripe.js +85 -0
- package/dist/fills/stripe.js.map +1 -0
- package/dist/fills/video.d.ts +6 -0
- package/dist/fills/video.d.ts.map +1 -0
- package/dist/fills/video.js +14 -0
- package/dist/fills/video.js.map +1 -0
- package/dist/font-style.d.ts +23 -0
- package/dist/font-style.d.ts.map +1 -0
- package/dist/font-style.js +34 -0
- package/dist/font-style.js.map +1 -0
- package/dist/getter.d.ts +9 -0
- package/dist/getter.d.ts.map +1 -0
- package/dist/getter.js +26 -0
- package/dist/getter.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/master-clock.d.ts +42 -0
- package/dist/master-clock.d.ts.map +1 -0
- package/dist/master-clock.js +134 -0
- package/dist/master-clock.js.map +1 -0
- package/dist/measure-scope.d.ts +14 -0
- package/dist/measure-scope.d.ts.map +1 -0
- package/dist/measure-scope.js +29 -0
- package/dist/measure-scope.js.map +1 -0
- package/dist/render-context.d.ts +107 -0
- package/dist/render-context.d.ts.map +1 -0
- package/dist/render-context.js +940 -0
- package/dist/render-context.js.map +1 -0
- package/dist/shapes/alpha-contour.d.ts +27 -0
- package/dist/shapes/alpha-contour.d.ts.map +1 -0
- package/dist/shapes/alpha-contour.js +330 -0
- package/dist/shapes/alpha-contour.js.map +1 -0
- package/dist/shapes/base.d.ts +46 -0
- package/dist/shapes/base.d.ts.map +1 -0
- package/dist/shapes/base.js +95 -0
- package/dist/shapes/base.js.map +1 -0
- package/dist/shapes/boolean.d.ts +28 -0
- package/dist/shapes/boolean.d.ts.map +1 -0
- package/dist/shapes/boolean.js +90 -0
- package/dist/shapes/boolean.js.map +1 -0
- package/dist/shapes/ellipse.d.ts +32 -0
- package/dist/shapes/ellipse.d.ts.map +1 -0
- package/dist/shapes/ellipse.js +50 -0
- package/dist/shapes/ellipse.js.map +1 -0
- package/dist/shapes/image.d.ts +66 -0
- package/dist/shapes/image.d.ts.map +1 -0
- package/dist/shapes/image.js +214 -0
- package/dist/shapes/image.js.map +1 -0
- package/dist/shapes/index.d.ts +67 -0
- package/dist/shapes/index.d.ts.map +1 -0
- package/dist/shapes/index.js +297 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/line.d.ts +25 -0
- package/dist/shapes/line.d.ts.map +1 -0
- package/dist/shapes/line.js +87 -0
- package/dist/shapes/line.js.map +1 -0
- package/dist/shapes/mask.d.ts +28 -0
- package/dist/shapes/mask.d.ts.map +1 -0
- package/dist/shapes/mask.js +106 -0
- package/dist/shapes/mask.js.map +1 -0
- package/dist/shapes/paragraph-layout.d.ts +64 -0
- package/dist/shapes/paragraph-layout.d.ts.map +1 -0
- package/dist/shapes/paragraph-layout.js +156 -0
- package/dist/shapes/paragraph-layout.js.map +1 -0
- package/dist/shapes/path.d.ts +29 -0
- package/dist/shapes/path.d.ts.map +1 -0
- package/dist/shapes/path.js +71 -0
- package/dist/shapes/path.js.map +1 -0
- package/dist/shapes/polygon.d.ts +33 -0
- package/dist/shapes/polygon.d.ts.map +1 -0
- package/dist/shapes/polygon.js +86 -0
- package/dist/shapes/polygon.js.map +1 -0
- package/dist/shapes/polygram.d.ts +34 -0
- package/dist/shapes/polygram.d.ts.map +1 -0
- package/dist/shapes/polygram.js +90 -0
- package/dist/shapes/polygram.js.map +1 -0
- package/dist/shapes/rect.d.ts +41 -0
- package/dist/shapes/rect.d.ts.map +1 -0
- package/dist/shapes/rect.js +111 -0
- package/dist/shapes/rect.js.map +1 -0
- package/dist/shapes/richtext.d.ts +28 -0
- package/dist/shapes/richtext.d.ts.map +1 -0
- package/dist/shapes/richtext.js +32 -0
- package/dist/shapes/richtext.js.map +1 -0
- package/dist/shapes/shape-handler.d.ts +79 -0
- package/dist/shapes/shape-handler.d.ts.map +1 -0
- package/dist/shapes/shape-handler.js +304 -0
- package/dist/shapes/shape-handler.js.map +1 -0
- package/dist/shapes/text.d.ts +13 -0
- package/dist/shapes/text.d.ts.map +1 -0
- package/dist/shapes/text.js +67 -0
- package/dist/shapes/text.js.map +1 -0
- package/dist/shapes/trim.d.ts +10 -0
- package/dist/shapes/trim.d.ts.map +1 -0
- package/dist/shapes/trim.js +49 -0
- package/dist/shapes/trim.js.map +1 -0
- package/dist/storage-adapter.d.ts +56 -0
- package/dist/storage-adapter.d.ts.map +1 -0
- package/dist/storage-adapter.js +188 -0
- package/dist/storage-adapter.js.map +1 -0
- package/dist/stroke/index.d.ts +34 -0
- package/dist/stroke/index.d.ts.map +1 -0
- package/dist/stroke/index.js +360 -0
- package/dist/stroke/index.js.map +1 -0
- package/dist/stroke/stroke-handler.d.ts +45 -0
- package/dist/stroke/stroke-handler.d.ts.map +1 -0
- package/dist/stroke/stroke-handler.js +371 -0
- package/dist/stroke/stroke-handler.js.map +1 -0
- package/dist/video/extract.d.ts +54 -0
- package/dist/video/extract.d.ts.map +1 -0
- package/dist/video/extract.js +192 -0
- package/dist/video/extract.js.map +1 -0
- package/dist/video/extract.worker.d.ts +50 -0
- package/dist/video/extract.worker.d.ts.map +1 -0
- package/dist/video/extract.worker.js +224 -0
- package/dist/video/extract.worker.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CanvasKit, Shader } from "@motion-script/canvaskit";
|
|
2
|
+
import { type ZoomEffect } from "@motion-script/core";
|
|
3
|
+
/** Drop the cached RuntimeEffect (called when the draw context is disposed). */
|
|
4
|
+
export declare function disposeZoom(): void;
|
|
5
|
+
/**
|
|
6
|
+
* Build a paint shader that draws the backdrop magnified within the lens box and
|
|
7
|
+
* passes it through untouched elsewhere. The caller draws it over the surface
|
|
8
|
+
* (clipped to the node silhouette), replacing the backdrop region with the
|
|
9
|
+
* zoomed version. Returns null when the effect is a no-op.
|
|
10
|
+
*
|
|
11
|
+
* @param effect zoom params (scale, centre).
|
|
12
|
+
* @param ck live CanvasKit instance.
|
|
13
|
+
* @param backdrop child shader wrapping the snapshot of the content beneath.
|
|
14
|
+
* @param centerX lens centre X in device px (node centre).
|
|
15
|
+
* @param centerY lens centre Y in device px.
|
|
16
|
+
* @param width node width in device px (the lens box width).
|
|
17
|
+
* @param height node height in device px (the lens box height).
|
|
18
|
+
*/
|
|
19
|
+
export declare function makeZoomShader(effect: ZoomEffect, ck: CanvasKit, backdrop: Shader, centerX: number, centerY: number, width: number, height: number): Shader | null;
|
|
20
|
+
//# sourceMappingURL=zoom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoom.d.ts","sourceRoot":"","sources":["../../src/effects/zoom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAqCtD,gFAAgF;AAChF,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC1B,MAAM,EAAE,UAAU,EAClB,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAef"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Magnifier lens that *resamples the backdrop* — it reads the content beneath
|
|
3
|
+
* the node (passed in as the `u_backdrop` child shader) at a position scaled
|
|
4
|
+
* toward `u_center`, so the area under the node is genuinely magnified, like a
|
|
5
|
+
* magnifying glass. Unlike bulge/pinch there is no dome falloff: the whole lens
|
|
6
|
+
* box magnifies uniformly by `u_scale`.
|
|
7
|
+
*
|
|
8
|
+
* The lens fills the node's *bounding box*; the caller clips the draw to the
|
|
9
|
+
* node's exact silhouette, so an ellipse magnifies as an ellipse, a rounded rect
|
|
10
|
+
* as a rounded rect, etc.
|
|
11
|
+
*
|
|
12
|
+
* To magnify by `s`, the backdrop is sampled at a point pulled `1/s` of the way
|
|
13
|
+
* from the centre — so a 2× zoom reads from half the distance, doubling apparent
|
|
14
|
+
* size:
|
|
15
|
+
*
|
|
16
|
+
* sample = centre + (fragCoord − centre) / scale
|
|
17
|
+
*/
|
|
18
|
+
const ZOOM_SKSL = `
|
|
19
|
+
uniform shader u_backdrop;
|
|
20
|
+
uniform vec2 u_center; // lens centre, device px
|
|
21
|
+
uniform float u_scale; // magnification factor (1 = none, 2 = 2x)
|
|
22
|
+
|
|
23
|
+
vec4 main(vec2 fragCoord) {
|
|
24
|
+
vec2 samplePos = u_center + (fragCoord - u_center) / max(u_scale, 0.001);
|
|
25
|
+
return u_backdrop.eval(samplePos);
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
let cachedEffect = null;
|
|
29
|
+
function getRuntimeEffect(ck) {
|
|
30
|
+
if (!cachedEffect)
|
|
31
|
+
cachedEffect = ck.RuntimeEffect.Make(ZOOM_SKSL);
|
|
32
|
+
return cachedEffect;
|
|
33
|
+
}
|
|
34
|
+
/** Drop the cached RuntimeEffect (called when the draw context is disposed). */
|
|
35
|
+
export function disposeZoom() {
|
|
36
|
+
cachedEffect?.delete();
|
|
37
|
+
cachedEffect = null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build a paint shader that draws the backdrop magnified within the lens box and
|
|
41
|
+
* passes it through untouched elsewhere. The caller draws it over the surface
|
|
42
|
+
* (clipped to the node silhouette), replacing the backdrop region with the
|
|
43
|
+
* zoomed version. Returns null when the effect is a no-op.
|
|
44
|
+
*
|
|
45
|
+
* @param effect zoom params (scale, centre).
|
|
46
|
+
* @param ck live CanvasKit instance.
|
|
47
|
+
* @param backdrop child shader wrapping the snapshot of the content beneath.
|
|
48
|
+
* @param centerX lens centre X in device px (node centre).
|
|
49
|
+
* @param centerY lens centre Y in device px.
|
|
50
|
+
* @param width node width in device px (the lens box width).
|
|
51
|
+
* @param height node height in device px (the lens box height).
|
|
52
|
+
*/
|
|
53
|
+
export function makeZoomShader(effect, ck, backdrop, centerX, centerY, width, height) {
|
|
54
|
+
const scale = effect.scale;
|
|
55
|
+
if (scale === 1 || scale <= 0 || width <= 0 || height <= 0)
|
|
56
|
+
return null;
|
|
57
|
+
// center is a 0–1 offset from the node centre (0.5,0.5 = dead centre).
|
|
58
|
+
const cx = centerX + (effect.center.x - 0.5) * width;
|
|
59
|
+
const cy = centerY + (effect.center.y - 0.5) * height;
|
|
60
|
+
const runtimeEffect = getRuntimeEffect(ck);
|
|
61
|
+
if (!runtimeEffect)
|
|
62
|
+
return null;
|
|
63
|
+
return runtimeEffect.makeShaderWithChildren([cx, cy, scale], [backdrop]);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=zoom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoom.js","sourceRoot":"","sources":["../../src/effects/zoom.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,SAAS,GAAG;;;;;;;;;CASjB,CAAC;AAEF,IAAI,YAAY,GAAyB,IAAI,CAAC;AAE9C,SAAS,gBAAgB,CAAC,EAAa;IACnC,IAAI,CAAC,YAAY;QAAE,YAAY,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnE,OAAO,YAAY,CAAC;AACxB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,GAAG,IAAI,CAAC;AACxB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAC1B,MAAkB,EAClB,EAAa,EACb,QAAgB,EAChB,OAAe,EACf,OAAe,EACf,KAAa,EACb,MAAc;IAEd,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAExE,uEAAuE;IACvE,MAAM,EAAE,GAAG,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC;IACrD,MAAM,EAAE,GAAG,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC;IAEtD,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAEhC,OAAO,aAAa,CAAC,sBAAsB,CACvC,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EACf,CAAC,QAAQ,CAAC,CACb,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Scene, Size2D, AssetManifest } from "@motion-script/core";
|
|
2
|
+
/** Reports export progress in [0, 1]; video encoding occupies most of the range, audio mixing/finalize the tail. */
|
|
3
|
+
export type ExportProgressCallback = (progress: number) => void;
|
|
4
|
+
export type ExportParams = {
|
|
5
|
+
scenes: Scene[];
|
|
6
|
+
viewport?: Size2D;
|
|
7
|
+
fps?: number;
|
|
8
|
+
scale?: number;
|
|
9
|
+
filename?: string;
|
|
10
|
+
manifest?: AssetManifest;
|
|
11
|
+
onProgress?: ExportProgressCallback;
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
wasmUrl?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Renders `scenes` frame-by-frame to an offscreen canvas and muxes the result
|
|
17
|
+
* into an MP4 via mediabunny: drives the same {@link WebRenderContext}/
|
|
18
|
+
* {@link StateEvaluator} pipeline as live playback, captures each frame to the
|
|
19
|
+
* video track, mixes all audio offline at the end (see {@link mixAudio}), then
|
|
20
|
+
* finalizes and triggers a browser download. Honors `signal` for cancellation
|
|
21
|
+
* between frames.
|
|
22
|
+
*/
|
|
23
|
+
export declare function exportScenesAsVideo(params: ExportParams): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=exporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,EAA8B,MAAM,EAAiB,aAAa,EAAyC,MAAM,qBAAqB,CAAA;AAYjK,oHAAoH;AACpH,MAAM,MAAM,sBAAsB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;AAEhE,MAAM,MAAM,YAAY,GAAG;IACvB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,CAAA;AA0FD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgI7E"}
|
package/dist/exporter.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { AudioDevice, AssetManager, AssetCatalog, Precomp, StateEvaluator } from "@motion-script/core";
|
|
2
|
+
import { AudioBufferSource, BufferTarget, CanvasSource, Mp4OutputFormat, Output, } from 'mediabunny';
|
|
3
|
+
import { WebRenderContext } from "./render-context";
|
|
4
|
+
import { WebStorageAdapter } from "./storage-adapter";
|
|
5
|
+
import { getCanvasKit } from "./getter";
|
|
6
|
+
const EMPTY_MANIFEST = {
|
|
7
|
+
image: {},
|
|
8
|
+
video: {},
|
|
9
|
+
audio: {},
|
|
10
|
+
font: {},
|
|
11
|
+
};
|
|
12
|
+
// ── Audio mixing helpers ─────────────────────────────────────────────────────
|
|
13
|
+
/** Fetches and decodes an audio source against a scratch `OfflineAudioContext` (decoding requires a context but doesn't render through it). */
|
|
14
|
+
async function fetchAudioBuffer(src, ctx) {
|
|
15
|
+
const response = await fetch(src);
|
|
16
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
17
|
+
return ctx.decodeAudioData(arrayBuffer);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Renders every scheduled audio request into a single timeline-length buffer
|
|
21
|
+
* via an `OfflineAudioContext` graph (gain nodes for per-request volume,
|
|
22
|
+
* looping/trimming per request) — done once after the full video pass so the
|
|
23
|
+
* mux step gets one continuous track instead of per-frame audio scheduling.
|
|
24
|
+
*/
|
|
25
|
+
async function mixAudio(requests, totalDuration, sampleRate = 44100) {
|
|
26
|
+
if (requests.length === 0)
|
|
27
|
+
return null;
|
|
28
|
+
const uniqueSrcs = [...new Set(requests.map(r => r.request.src))];
|
|
29
|
+
const scratchCtx = new OfflineAudioContext(2, Math.ceil(totalDuration * sampleRate), sampleRate);
|
|
30
|
+
const decoded = new Map();
|
|
31
|
+
await Promise.all(uniqueSrcs.map(async (src) => {
|
|
32
|
+
decoded.set(src, await fetchAudioBuffer(src, scratchCtx));
|
|
33
|
+
}));
|
|
34
|
+
const mixCtx = new OfflineAudioContext(2, Math.ceil(totalDuration * sampleRate), sampleRate);
|
|
35
|
+
for (const { request: req, globalOffset } of requests) {
|
|
36
|
+
const srcBuffer = decoded.get(req.src);
|
|
37
|
+
if (!srcBuffer)
|
|
38
|
+
continue;
|
|
39
|
+
const globalStart = globalOffset + req.startAt;
|
|
40
|
+
const globalEnd = req.endAt !== null
|
|
41
|
+
? globalOffset + req.endAt
|
|
42
|
+
: totalDuration;
|
|
43
|
+
const clipDuration = Math.min(globalEnd - globalStart, totalDuration - globalStart);
|
|
44
|
+
if (clipDuration <= 0)
|
|
45
|
+
continue;
|
|
46
|
+
const source = mixCtx.createBufferSource();
|
|
47
|
+
source.buffer = srcBuffer;
|
|
48
|
+
source.loop = req.loop;
|
|
49
|
+
const gain = mixCtx.createGain();
|
|
50
|
+
gain.gain.value = req.volume;
|
|
51
|
+
source.connect(gain);
|
|
52
|
+
gain.connect(mixCtx.destination);
|
|
53
|
+
source.start(globalStart, req.trimStart, clipDuration);
|
|
54
|
+
}
|
|
55
|
+
return mixCtx.startRendering();
|
|
56
|
+
}
|
|
57
|
+
/** Hands control back to the browser between frame batches so the export doesn't block the main thread (and stays cancellable/responsive). */
|
|
58
|
+
function yieldToMain() {
|
|
59
|
+
return new Promise(resolve => setTimeout(resolve, 0));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Audio for exports is mixed offline via {@link mixAudio} at the end of the
|
|
63
|
+
* run, so the AssetManager just needs an AudioDevice-shaped sink that does
|
|
64
|
+
* nothing during the per-frame pass.
|
|
65
|
+
*/
|
|
66
|
+
class NoopAudioDevice extends AudioDevice {
|
|
67
|
+
has(_src) { return true; }
|
|
68
|
+
async append(_src, _data) { }
|
|
69
|
+
retain(_keep) { }
|
|
70
|
+
schedule(_requests) { }
|
|
71
|
+
syncTo(_sceneTime) { }
|
|
72
|
+
play(_time, _speed, _reverse) { }
|
|
73
|
+
stop() { }
|
|
74
|
+
}
|
|
75
|
+
// ── Main export ──────────────────────────────────────────────────────────────
|
|
76
|
+
/**
|
|
77
|
+
* Renders `scenes` frame-by-frame to an offscreen canvas and muxes the result
|
|
78
|
+
* into an MP4 via mediabunny: drives the same {@link WebRenderContext}/
|
|
79
|
+
* {@link StateEvaluator} pipeline as live playback, captures each frame to the
|
|
80
|
+
* video track, mixes all audio offline at the end (see {@link mixAudio}), then
|
|
81
|
+
* finalizes and triggers a browser download. Honors `signal` for cancellation
|
|
82
|
+
* between frames.
|
|
83
|
+
*/
|
|
84
|
+
export async function exportScenesAsVideo(params) {
|
|
85
|
+
const { scenes, viewport = { width: 1920, height: 1080 }, fps = 60, scale = 1, filename = 'export.mp4', manifest = EMPTY_MANIFEST, onProgress, signal, wasmUrl, } = params;
|
|
86
|
+
if (scenes.length === 0)
|
|
87
|
+
return;
|
|
88
|
+
signal?.throwIfAborted();
|
|
89
|
+
const resolution = {
|
|
90
|
+
width: viewport.width * scale,
|
|
91
|
+
height: viewport.height * scale,
|
|
92
|
+
};
|
|
93
|
+
const frameDuration = 1 / fps;
|
|
94
|
+
const offscreenCanvas = document.createElement('canvas');
|
|
95
|
+
offscreenCanvas.width = resolution.width;
|
|
96
|
+
offscreenCanvas.height = resolution.height;
|
|
97
|
+
offscreenCanvas.style.display = 'none';
|
|
98
|
+
document.body.appendChild(offscreenCanvas);
|
|
99
|
+
const canvasKit = await getCanvasKit(wasmUrl);
|
|
100
|
+
const assetCatalog = new AssetCatalog(manifest);
|
|
101
|
+
const storageAdapter = new WebStorageAdapter(canvasKit, assetCatalog, viewport, fps);
|
|
102
|
+
const renderContext = new WebRenderContext(canvasKit, storageAdapter);
|
|
103
|
+
renderContext.mount(offscreenCanvas);
|
|
104
|
+
renderContext.pixelRatio = scale;
|
|
105
|
+
const precomp = new Precomp(scenes, viewport, fps, assetCatalog, renderContext).run();
|
|
106
|
+
const { totalFrames, totalDuration } = precomp;
|
|
107
|
+
const tracks = precomp.scenes.map(s => s.frameCount);
|
|
108
|
+
const stateEvaluator = new StateEvaluator(scenes, viewport, fps, assetCatalog, tracks);
|
|
109
|
+
const audioDevice = new NoopAudioDevice();
|
|
110
|
+
const assetManager = new AssetManager(precomp, storageAdapter, audioDevice);
|
|
111
|
+
// Collect audio requests with global offsets from precomp.
|
|
112
|
+
const sceneRequests = [];
|
|
113
|
+
for (const scene of precomp.scenes) {
|
|
114
|
+
const globalOffset = scene.startFrame / fps;
|
|
115
|
+
for (const req of scene.audioRequests) {
|
|
116
|
+
sceneRequests.push({ request: req, globalOffset });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const target = new BufferTarget();
|
|
120
|
+
const videoSource = new CanvasSource(offscreenCanvas, {
|
|
121
|
+
codec: 'avc',
|
|
122
|
+
bitrate: 10_000_000,
|
|
123
|
+
});
|
|
124
|
+
const output = new Output({ format: new Mp4OutputFormat(), target });
|
|
125
|
+
output.addVideoTrack(videoSource, { frameRate: fps });
|
|
126
|
+
let audioSource = null;
|
|
127
|
+
if (sceneRequests.length > 0) {
|
|
128
|
+
audioSource = new AudioBufferSource({ codec: 'aac', bitrate: 192_000 });
|
|
129
|
+
output.addAudioTrack(audioSource);
|
|
130
|
+
}
|
|
131
|
+
await output.start();
|
|
132
|
+
try {
|
|
133
|
+
let globalTime = 0;
|
|
134
|
+
for (let f = 0; f < totalFrames; f++) {
|
|
135
|
+
signal?.throwIfAborted();
|
|
136
|
+
await assetManager.loadAt(f);
|
|
137
|
+
stateEvaluator.stateAt(f);
|
|
138
|
+
stateEvaluator.layout(renderContext);
|
|
139
|
+
await renderContext.render(() => {
|
|
140
|
+
stateEvaluator.render(renderContext);
|
|
141
|
+
});
|
|
142
|
+
await videoSource.add(globalTime, frameDuration);
|
|
143
|
+
globalTime += frameDuration;
|
|
144
|
+
onProgress?.((f + 1) / totalFrames * (audioSource ? 0.85 : 1));
|
|
145
|
+
if ((f + 1) % 4 === 0)
|
|
146
|
+
await yieldToMain();
|
|
147
|
+
}
|
|
148
|
+
videoSource.close();
|
|
149
|
+
if (audioSource) {
|
|
150
|
+
const mixed = await mixAudio(sceneRequests, totalDuration);
|
|
151
|
+
if (mixed) {
|
|
152
|
+
await audioSource.add(mixed);
|
|
153
|
+
}
|
|
154
|
+
audioSource.close();
|
|
155
|
+
onProgress?.(0.97);
|
|
156
|
+
}
|
|
157
|
+
await output.finalize();
|
|
158
|
+
onProgress?.(1);
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
renderContext.dispose();
|
|
162
|
+
document.body.removeChild(offscreenCanvas);
|
|
163
|
+
}
|
|
164
|
+
const buffer = target.buffer;
|
|
165
|
+
if (!buffer)
|
|
166
|
+
throw new Error('Export produced no data');
|
|
167
|
+
const blob = new Blob([buffer], { type: 'video/mp4' });
|
|
168
|
+
const url = URL.createObjectURL(blob);
|
|
169
|
+
const link = document.createElement('a');
|
|
170
|
+
link.href = url;
|
|
171
|
+
link.download = filename;
|
|
172
|
+
document.body.appendChild(link);
|
|
173
|
+
link.click();
|
|
174
|
+
document.body.removeChild(link);
|
|
175
|
+
URL.revokeObjectURL(url);
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=exporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter.js","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ConicGradientFillResolved } from "@motion-script/core";
|
|
2
|
+
import { FillRenderer, type FillRendererContext } from "./renderer";
|
|
3
|
+
/**
|
|
4
|
+
* Builds and caches a sweep-gradient shader spanning a full revolution from
|
|
5
|
+
* `startAngle` (see linear-gradient for the caching pattern).
|
|
6
|
+
*/
|
|
7
|
+
export declare class ConicGradientFillRenderer extends FillRenderer<ConicGradientFillResolved> {
|
|
8
|
+
private cache;
|
|
9
|
+
applyPaint(fill: ConicGradientFillResolved, ctx: FillRendererContext): boolean;
|
|
10
|
+
dispose(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=conic-gradient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conic-gradient.d.ts","sourceRoot":"","sources":["../../src/fills/conic-gradient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAWpE;;;GAGG;AACH,qBAAa,yBAA0B,SAAQ,YAAY,CAAC,yBAAyB,CAAC;IAClF,OAAO,CAAC,KAAK,CAA6B;IAE1C,UAAU,CAAC,IAAI,EAAE,yBAAyB,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO;IAoC9E,OAAO,IAAI,IAAI;CAGlB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { FillRenderer } from "./renderer";
|
|
2
|
+
import { GradientShaderCache, toCkColors, pushNums } from "./gradient-cache";
|
|
3
|
+
function normToPixel(nx, ny, bounds) {
|
|
4
|
+
const cx = (bounds.left + bounds.right) / 2;
|
|
5
|
+
const cy = (bounds.top + bounds.bottom) / 2;
|
|
6
|
+
const hw = (bounds.right - bounds.left) / 2;
|
|
7
|
+
const hh = (bounds.bottom - bounds.top) / 2;
|
|
8
|
+
return [cx + nx * hw, cy - ny * hh];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Builds and caches a sweep-gradient shader spanning a full revolution from
|
|
12
|
+
* `startAngle` (see linear-gradient for the caching pattern).
|
|
13
|
+
*/
|
|
14
|
+
export class ConicGradientFillRenderer extends FillRenderer {
|
|
15
|
+
cache = new GradientShaderCache();
|
|
16
|
+
applyPaint(fill, ctx) {
|
|
17
|
+
const ck = ctx.canvasKit;
|
|
18
|
+
const bounds = ctx.getShapeBounds();
|
|
19
|
+
if (!bounds)
|
|
20
|
+
return false;
|
|
21
|
+
const [cx, cy] = normToPixel(fill.center.x, fill.center.y, bounds);
|
|
22
|
+
const startAngle = fill.startAngle ?? 0;
|
|
23
|
+
const parts = ["C"];
|
|
24
|
+
pushNums(parts, [cx, cy, startAngle]);
|
|
25
|
+
for (const c of fill.colors)
|
|
26
|
+
pushNums(parts, c);
|
|
27
|
+
parts.push("|");
|
|
28
|
+
pushNums(parts, fill.stops);
|
|
29
|
+
const key = parts.join(",");
|
|
30
|
+
const shader = this.cache.get(key, () => {
|
|
31
|
+
const ckColors = toCkColors(ck, fill.colors);
|
|
32
|
+
const pos = fill.stops.length === ckColors.length
|
|
33
|
+
? fill.stops
|
|
34
|
+
: ckColors.map((_, i) => i / (ckColors.length - 1));
|
|
35
|
+
return ck.Shader.MakeSweepGradient(cx, cy, ckColors, pos, ck.TileMode.Clamp, null, 0, startAngle, startAngle + 360);
|
|
36
|
+
});
|
|
37
|
+
ctx.paint.setShader(shader);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
dispose() {
|
|
41
|
+
this.cache.dispose();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=conic-gradient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conic-gradient.js","sourceRoot":"","sources":["../../src/fills/conic-gradient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CanvasKit } from "@motion-script/canvaskit";
|
|
2
|
+
import type { AlphaFilter } from "@motion-script/core";
|
|
3
|
+
import { ImageFillFilter } from "./filter";
|
|
4
|
+
/** Scales the image's alpha channel by `value` via a 4×5 color matrix. */
|
|
5
|
+
export declare class AlphaImageFillFilter extends ImageFillFilter<AlphaFilter> {
|
|
6
|
+
constructor();
|
|
7
|
+
makeImageFilter(filter: AlphaFilter, ck: CanvasKit): any;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=alpha.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alpha.d.ts","sourceRoot":"","sources":["../../../src/fills/filters/alpha.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,0EAA0E;AAC1E,qBAAa,oBAAqB,SAAQ,eAAe,CAAC,WAAW,CAAC;;IAKlE,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,GAAG,GAAG;CAa3D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ImageFillFilter } from "./filter";
|
|
2
|
+
/** Scales the image's alpha channel by `value` via a 4×5 color matrix. */
|
|
3
|
+
export class AlphaImageFillFilter extends ImageFillFilter {
|
|
4
|
+
constructor() {
|
|
5
|
+
super("alpha");
|
|
6
|
+
}
|
|
7
|
+
makeImageFilter(filter, ck) {
|
|
8
|
+
const a = Math.max(0, Math.min(1, filter.value));
|
|
9
|
+
const matrix = [
|
|
10
|
+
1, 0, 0, 0, 0,
|
|
11
|
+
0, 1, 0, 0, 0,
|
|
12
|
+
0, 0, 1, 0, 0,
|
|
13
|
+
0, 0, 0, a, 0,
|
|
14
|
+
];
|
|
15
|
+
const colorFilter = ck.ColorFilter.MakeMatrix(matrix);
|
|
16
|
+
const imageFilter = ck.ImageFilter.MakeColorFilter(colorFilter, null);
|
|
17
|
+
colorFilter.delete();
|
|
18
|
+
return imageFilter;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=alpha.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alpha.js","sourceRoot":"","sources":["../../../src/fills/filters/alpha.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,0EAA0E;AAC1E,MAAM,OAAO,oBAAqB,SAAQ,eAA4B;IAClE;QACI,KAAK,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;IAED,eAAe,CAAC,MAAmB,EAAE,EAAa;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG;YACX,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACb,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACb,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACb,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;SAChB,CAAC;QACF,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC,eAAe,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACtE,WAAW,CAAC,MAAM,EAAE,CAAC;QACrB,OAAO,WAAW,CAAC;IACvB,CAAC;CACJ"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CanvasKit } from "@motion-script/canvaskit";
|
|
2
|
+
import type { BlurFilter } from "@motion-script/core";
|
|
3
|
+
import { ImageFillFilter } from "./filter";
|
|
4
|
+
/** Gaussian blur; `value` is halved to map the spec's units to Skia's sigma. */
|
|
5
|
+
export declare class BlurImageFillFilter extends ImageFillFilter<BlurFilter> {
|
|
6
|
+
constructor();
|
|
7
|
+
makeImageFilter(filter: BlurFilter, ck: CanvasKit): any;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=blur.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blur.d.ts","sourceRoot":"","sources":["../../../src/fills/filters/blur.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,gFAAgF;AAChF,qBAAa,mBAAoB,SAAQ,eAAe,CAAC,UAAU,CAAC;;IAKhE,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,GAAG,GAAG;CAI1D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ImageFillFilter } from "./filter";
|
|
2
|
+
/** Gaussian blur; `value` is halved to map the spec's units to Skia's sigma. */
|
|
3
|
+
export class BlurImageFillFilter extends ImageFillFilter {
|
|
4
|
+
constructor() {
|
|
5
|
+
super("blur");
|
|
6
|
+
}
|
|
7
|
+
makeImageFilter(filter, ck) {
|
|
8
|
+
const sigma = filter.value / 2;
|
|
9
|
+
return ck.ImageFilter.MakeBlur(sigma, sigma, ck.TileMode.Decal, null);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=blur.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blur.js","sourceRoot":"","sources":["../../../src/fills/filters/blur.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,gFAAgF;AAChF,MAAM,OAAO,mBAAoB,SAAQ,eAA2B;IAChE;QACI,KAAK,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED,eAAe,CAAC,MAAkB,EAAE,EAAa;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;QAC/B,OAAO,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC1E,CAAC;CACJ"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CanvasKit } from "@motion-script/canvaskit";
|
|
2
|
+
import type { ColorAdjustmentFilter } from "@motion-script/core";
|
|
3
|
+
import { ImageFillFilter } from "./filter";
|
|
4
|
+
/**
|
|
5
|
+
* Composes brightness/contrast/saturation/vibrance/temperature/tint/shadows/
|
|
6
|
+
* highlights into a single 4×5 color matrix (each enabled adjustment multiplies
|
|
7
|
+
* onto the running matrix, in that order). Returns null if nothing is set —
|
|
8
|
+
* vignette is intentionally unsupported since it needs spatial, not per-pixel, data.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ColorAdjustmentImageFillFilter extends ImageFillFilter<ColorAdjustmentFilter> {
|
|
11
|
+
constructor();
|
|
12
|
+
makeImageFilter(filter: ColorAdjustmentFilter, ck: CanvasKit): any;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=color-adjustment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-adjustment.d.ts","sourceRoot":"","sources":["../../../src/fills/filters/color-adjustment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAyG3C;;;;;GAKG;AACH,qBAAa,8BAA+B,SAAQ,eAAe,CAAC,qBAAqB,CAAC;;IAKtF,eAAe,CAAC,MAAM,EAAE,qBAAqB,EAAE,EAAE,EAAE,SAAS,GAAG,GAAG;CA2CrE"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { ImageFillFilter } from "./filter";
|
|
2
|
+
// ITU-R BT.709 luminance weights
|
|
3
|
+
const LR = 0.2126, LG = 0.7152, LB = 0.0722;
|
|
4
|
+
function identity() {
|
|
5
|
+
return [
|
|
6
|
+
1, 0, 0, 0, 0,
|
|
7
|
+
0, 1, 0, 0, 0,
|
|
8
|
+
0, 0, 1, 0, 0,
|
|
9
|
+
0, 0, 0, 1, 0,
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
// Multiply two 4×5 color matrices: returns outer × inner (inner applied first).
|
|
13
|
+
// Treats each as a 5×5 with implicit last row [0,0,0,0,1].
|
|
14
|
+
function multiply(outer, inner) {
|
|
15
|
+
const out = new Array(20).fill(0);
|
|
16
|
+
for (let i = 0; i < 4; i++) {
|
|
17
|
+
for (let j = 0; j < 5; j++) {
|
|
18
|
+
let sum = 0;
|
|
19
|
+
for (let k = 0; k < 4; k++) {
|
|
20
|
+
sum += outer[i * 5 + k] * inner[k * 5 + j];
|
|
21
|
+
}
|
|
22
|
+
if (j === 4)
|
|
23
|
+
sum += outer[i * 5 + 4];
|
|
24
|
+
out[i * 5 + j] = sum;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
function brightnessMatrix(b) {
|
|
30
|
+
return [
|
|
31
|
+
1, 0, 0, 0, b,
|
|
32
|
+
0, 1, 0, 0, b,
|
|
33
|
+
0, 0, 1, 0, b,
|
|
34
|
+
0, 0, 0, 1, 0,
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
function contrastMatrix(c) {
|
|
38
|
+
const t = 0.5 * (1 - c);
|
|
39
|
+
return [
|
|
40
|
+
c, 0, 0, 0, t,
|
|
41
|
+
0, c, 0, 0, t,
|
|
42
|
+
0, 0, c, 0, t,
|
|
43
|
+
0, 0, 0, 1, 0,
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
function saturationMatrix(s) {
|
|
47
|
+
const i = 1 - s;
|
|
48
|
+
return [
|
|
49
|
+
s + i * LR, i * LG, i * LB, 0, 0,
|
|
50
|
+
i * LR, s + i * LG, i * LB, 0, 0,
|
|
51
|
+
i * LR, i * LG, s + i * LB, 0, 0,
|
|
52
|
+
0, 0, 0, 1, 0,
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
function temperatureMatrix(t) {
|
|
56
|
+
return [
|
|
57
|
+
1, 0, 0, 0, t * 0.1,
|
|
58
|
+
0, 1, 0, 0, 0,
|
|
59
|
+
0, 0, 1, 0, -t * 0.1,
|
|
60
|
+
0, 0, 0, 1, 0,
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
function tintMatrix(t) {
|
|
64
|
+
// Positive = magenta (more R+B, less G); negative = green (more G, less R+B)
|
|
65
|
+
return [
|
|
66
|
+
1, 0, 0, 0, t * 0.05,
|
|
67
|
+
0, 1, 0, 0, -t * 0.1,
|
|
68
|
+
0, 0, 1, 0, t * 0.05,
|
|
69
|
+
0, 0, 0, 1, 0,
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
// Lifts (positive) or crushes (negative) dark areas while keeping whites fixed.
|
|
73
|
+
// r' = r*(1 - 0.2*s) + 0.2*s → at r=0: r'=0.2s; at r=1: r'=1
|
|
74
|
+
function shadowsMatrix(s) {
|
|
75
|
+
const scale = 1 - 0.2 * s;
|
|
76
|
+
const offset = 0.2 * s;
|
|
77
|
+
return [
|
|
78
|
+
scale, 0, 0, 0, offset,
|
|
79
|
+
0, scale, 0, 0, offset,
|
|
80
|
+
0, 0, scale, 0, offset,
|
|
81
|
+
0, 0, 0, 1, 0,
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
// Boosts (positive) or rolls off (negative) bright areas while keeping midtones fixed.
|
|
85
|
+
// r' = r*(1 + 0.2*h) - 0.1*h → at r=0.5: r'=0.5; at r=1: r'=1+0.1h
|
|
86
|
+
function highlightsMatrix(h) {
|
|
87
|
+
const scale = 1 + 0.2 * h;
|
|
88
|
+
const offset = -0.1 * h;
|
|
89
|
+
return [
|
|
90
|
+
scale, 0, 0, 0, offset,
|
|
91
|
+
0, scale, 0, 0, offset,
|
|
92
|
+
0, 0, scale, 0, offset,
|
|
93
|
+
0, 0, 0, 1, 0,
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Composes brightness/contrast/saturation/vibrance/temperature/tint/shadows/
|
|
98
|
+
* highlights into a single 4×5 color matrix (each enabled adjustment multiplies
|
|
99
|
+
* onto the running matrix, in that order). Returns null if nothing is set —
|
|
100
|
+
* vignette is intentionally unsupported since it needs spatial, not per-pixel, data.
|
|
101
|
+
*/
|
|
102
|
+
export class ColorAdjustmentImageFillFilter extends ImageFillFilter {
|
|
103
|
+
constructor() {
|
|
104
|
+
super("colorAdjustment");
|
|
105
|
+
}
|
|
106
|
+
makeImageFilter(filter, ck) {
|
|
107
|
+
let mat = identity();
|
|
108
|
+
let hasAdjustment = false;
|
|
109
|
+
const apply = (m) => {
|
|
110
|
+
mat = multiply(m, mat);
|
|
111
|
+
hasAdjustment = true;
|
|
112
|
+
};
|
|
113
|
+
const b = filter.brightness ?? 0;
|
|
114
|
+
if (b !== 0)
|
|
115
|
+
apply(brightnessMatrix(b));
|
|
116
|
+
const c = filter.contrast ?? 1;
|
|
117
|
+
if (c !== 1)
|
|
118
|
+
apply(contrastMatrix(c));
|
|
119
|
+
const s = filter.saturation ?? 1;
|
|
120
|
+
if (s !== 1)
|
|
121
|
+
apply(saturationMatrix(s));
|
|
122
|
+
// Vibrance: approximate as a lighter saturation pass (muted colors benefit more)
|
|
123
|
+
const v = filter.vibrance ?? 0;
|
|
124
|
+
if (v !== 0)
|
|
125
|
+
apply(saturationMatrix(1 + v * 0.7));
|
|
126
|
+
const temp = filter.temperature ?? 0;
|
|
127
|
+
if (temp !== 0)
|
|
128
|
+
apply(temperatureMatrix(temp));
|
|
129
|
+
const tint = filter.tint ?? 0;
|
|
130
|
+
if (tint !== 0)
|
|
131
|
+
apply(tintMatrix(tint));
|
|
132
|
+
const sh = filter.shadows ?? 0;
|
|
133
|
+
if (sh !== 0)
|
|
134
|
+
apply(shadowsMatrix(sh));
|
|
135
|
+
const hi = filter.highlights ?? 0;
|
|
136
|
+
if (hi !== 0)
|
|
137
|
+
apply(highlightsMatrix(hi));
|
|
138
|
+
// vignette requires spatial data — not implementable via color matrix
|
|
139
|
+
if (!hasAdjustment)
|
|
140
|
+
return null;
|
|
141
|
+
const colorFilter = ck.ColorFilter.MakeMatrix(mat);
|
|
142
|
+
const imageFilter = ck.ImageFilter.MakeColorFilter(colorFilter, null);
|
|
143
|
+
colorFilter.delete();
|
|
144
|
+
return imageFilter;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=color-adjustment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-adjustment.js","sourceRoot":"","sources":["../../../src/fills/filters/color-adjustment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CanvasKit } from "@motion-script/canvaskit";
|
|
2
|
+
import type { ColorMatrixFilter } from "@motion-script/core";
|
|
3
|
+
import { ImageFillFilter } from "./filter";
|
|
4
|
+
/** Applies an arbitrary user-supplied 4×5 color matrix verbatim. */
|
|
5
|
+
export declare class ColorMatrixImageFillFilter extends ImageFillFilter<ColorMatrixFilter> {
|
|
6
|
+
constructor();
|
|
7
|
+
makeImageFilter(filter: ColorMatrixFilter, ck: CanvasKit): any;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=color-matrix.d.ts.map
|