@motionscript/browser 0.1.0-alpha.0 → 0.1.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +148 -0
- package/LICENSE +201 -201
- package/NOTICE +48 -0
- package/README.md +118 -69
- package/dist/asset-bytes.d.ts +7 -1
- package/dist/asset-bytes.d.ts.map +1 -1
- package/dist/asset-bytes.js +14 -1
- package/dist/asset-bytes.js.map +1 -1
- package/dist/audio/bus-graph.d.ts +12 -3
- package/dist/audio/bus-graph.d.ts.map +1 -1
- package/dist/audio/bus-graph.js +24 -29
- package/dist/audio/bus-graph.js.map +1 -1
- package/dist/audio/filter-graph.d.ts +6 -5
- package/dist/audio/filter-graph.d.ts.map +1 -1
- package/dist/audio/filter-graph.js +29 -23
- package/dist/audio/filter-graph.js.map +1 -1
- package/dist/audio/index.js.map +1 -1
- package/dist/audio/loop-region.d.ts +31 -0
- package/dist/audio/loop-region.d.ts.map +1 -0
- package/dist/audio/loop-region.js +43 -0
- package/dist/audio/loop-region.js.map +1 -0
- package/dist/audio/mixer.d.ts.map +1 -1
- package/dist/audio/mixer.js +30 -11
- package/dist/audio/mixer.js.map +1 -1
- package/dist/audio/player.d.ts +4 -4
- package/dist/audio/player.d.ts.map +1 -1
- package/dist/audio/player.js +19 -15
- package/dist/audio/player.js.map +1 -1
- package/dist/browser/THIRD_PARTY_LICENSES.txt +432 -0
- package/dist/browser/audio.js +1 -1
- package/dist/browser/chunks/chunk-2MAFJWBZ.js +2 -0
- package/dist/browser/chunks/chunk-2MAFJWBZ.js.map +7 -0
- package/dist/browser/index.js +133 -279
- package/dist/browser/index.js.map +4 -4
- package/dist/browser/manifest.json +19 -2
- package/dist/concat.js.map +1 -1
- package/dist/decode/image-levels.js.map +1 -1
- package/dist/decode/levels.js.map +1 -1
- package/dist/decode/video-levels.js.map +1 -1
- package/dist/dynamic-nodes.d.ts.map +1 -1
- package/dist/dynamic-nodes.js +5 -1
- package/dist/dynamic-nodes.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +18 -5
- package/dist/engine.js.map +1 -1
- package/dist/exporter.d.ts +10 -2
- package/dist/exporter.d.ts.map +1 -1
- package/dist/exporter.js +8 -7
- package/dist/exporter.js.map +1 -1
- package/dist/getter.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -27
- package/dist/index.js.map +1 -1
- package/dist/measure-context.js.map +1 -1
- package/dist/mix-timeline-audio.d.ts +2 -2
- package/dist/mix-timeline-audio.d.ts.map +1 -1
- package/dist/mix-timeline-audio.js +1 -2
- package/dist/mix-timeline-audio.js.map +1 -1
- package/dist/render-context.d.ts +5 -3
- package/dist/render-context.d.ts.map +1 -1
- package/dist/render-context.js +7 -3
- package/dist/render-context.js.map +1 -1
- package/dist/screenshot.d.ts +3 -3
- package/dist/screenshot.d.ts.map +1 -1
- package/dist/screenshot.js +1 -2
- package/dist/screenshot.js.map +1 -1
- package/dist/still.d.ts +18 -8
- package/dist/still.d.ts.map +1 -1
- package/dist/still.js +28 -21
- package/dist/still.js.map +1 -1
- package/dist/storage-adapter.d.ts +1 -1
- package/dist/storage-adapter.d.ts.map +1 -1
- package/dist/storage-adapter.js +12 -10
- package/dist/storage-adapter.js.map +1 -1
- package/dist/three/renderer.d.ts +10 -11
- package/dist/three/renderer.d.ts.map +1 -1
- package/dist/three/renderer.js +18 -13
- package/dist/three/renderer.js.map +1 -1
- package/dist/ticker.d.ts +22 -4
- package/dist/ticker.d.ts.map +1 -1
- package/dist/ticker.js +65 -28
- package/dist/ticker.js.map +1 -1
- package/package.json +8 -6
- package/dist/browser/chunks/chunk-NSFLRI4P.js +0 -2
- package/dist/browser/chunks/chunk-NSFLRI4P.js.map +0 -7
- package/dist/output.d.ts +0 -7
- package/dist/output.d.ts.map +0 -1
- package/dist/output.js +0 -6
- package/dist/output.js.map +0 -1
package/dist/still.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Registry, type AssetManifest, type ProjectDocument, type
|
|
2
|
-
import { type DrawnFrame, type
|
|
1
|
+
import { Registry, type AssetManifest, type FrameSpec, type ProjectDocument, type VisualDocument, type Size2D, type Theme } from "@motionscript/core";
|
|
2
|
+
import { type DrawnFrame, type ScreenshotFormat } from "@motionscript/skia-render/export";
|
|
3
3
|
import { getCanvasKit } from "./getter";
|
|
4
4
|
/** Anything a still can be rendered from: a project, or a lone still or composition as the one track of one. */
|
|
5
|
-
export type StillSource = ProjectDocument |
|
|
5
|
+
export type StillSource = ProjectDocument | VisualDocument;
|
|
6
6
|
/**
|
|
7
7
|
* Which frame to draw, in whatever form is most convenient — a global frame
|
|
8
8
|
* index, the timeline's first or last frame, or a `FrameSpec`.
|
|
@@ -41,9 +41,10 @@ export interface RenderStillOptions {
|
|
|
41
41
|
/** Seconds into the timeline, converted with the document's fps. Wins over `frame`. */
|
|
42
42
|
time?: number;
|
|
43
43
|
/**
|
|
44
|
-
* Draw at this pixel ratio instead of the renderer's. **Resizes the
|
|
45
|
-
* rebuilds the Skia surface**,
|
|
46
|
-
*
|
|
44
|
+
* Draw this call at this pixel ratio instead of the renderer's. **Resizes the
|
|
45
|
+
* canvas and rebuilds the Skia surface**, and the next call without it rebuilds
|
|
46
|
+
* them back, so keep it off the per-edit path — render the preview at its
|
|
47
|
+
* normal scale and pass this only when capturing at a higher one.
|
|
47
48
|
*/
|
|
48
49
|
scale?: number;
|
|
49
50
|
}
|
|
@@ -54,7 +55,7 @@ export interface EncodeStillOptions {
|
|
|
54
55
|
quality?: number;
|
|
55
56
|
}
|
|
56
57
|
/** Normalize the many ways a caller can name a frame into the engine's own form. */
|
|
57
|
-
export declare function
|
|
58
|
+
export declare function stillFrameSpec(options: RenderStillOptions | undefined, fps: number): FrameSpec;
|
|
58
59
|
/**
|
|
59
60
|
* A long-lived single-frame renderer.
|
|
60
61
|
*
|
|
@@ -84,6 +85,11 @@ export declare function toFrameSpec(options: RenderStillOptions | undefined, fps
|
|
|
84
85
|
* different themes still each draw correctly; but anything else that calls
|
|
85
86
|
* `setTheme` between a render and a read of the surface will have been
|
|
86
87
|
* overwritten by the next render.
|
|
88
|
+
*
|
|
89
|
+
* **One surface, one caller at a time.** A render and the encode of its result
|
|
90
|
+
* are two calls, and the next render draws over the surface between them, so
|
|
91
|
+
* callers that share a renderer without knowing of each other must be queued —
|
|
92
|
+
* as `session.image()` queues its calls.
|
|
87
93
|
*/
|
|
88
94
|
export declare class StillRenderer {
|
|
89
95
|
readonly canvas: HTMLCanvasElement;
|
|
@@ -95,11 +101,15 @@ export declare class StillRenderer {
|
|
|
95
101
|
private readonly ownsCanvas;
|
|
96
102
|
private viewportValue;
|
|
97
103
|
private readonly fpsValue;
|
|
98
|
-
private scaleValue;
|
|
104
|
+
private readonly scaleValue;
|
|
105
|
+
/** What the canvas is sized at now, which a call's own `scale` changes. */
|
|
106
|
+
private surfaceScale;
|
|
99
107
|
private manifest;
|
|
100
108
|
private theme?;
|
|
101
109
|
private readonly registry;
|
|
102
110
|
private disposed;
|
|
111
|
+
/** False until a frame has been drawn onto the current surface; a remount clears it. */
|
|
112
|
+
private drawn;
|
|
103
113
|
/** @internal Use {@link createStillRenderer}, which loads CanvasKit first. */
|
|
104
114
|
constructor(canvasKit: Awaited<ReturnType<typeof getCanvasKit>>, options: StillRendererOptions);
|
|
105
115
|
get viewport(): Size2D;
|
package/dist/still.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"still.d.ts","sourceRoot":"","sources":["../src/still.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"still.d.ts","sourceRoot":"","sources":["../src/still.ts"],"names":[],"mappings":"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"}
|
package/dist/still.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { ManifestAssetCatalog, Registry, resolveProjectDocument,
|
|
1
|
+
import { DEFAULT_OUTPUT, ManifestAssetCatalog, frameSpecAtTime, Registry, resolveProjectDocument, } from "@motionscript/core";
|
|
2
2
|
import { drawFrameAt, } from "@motionscript/skia-render/export";
|
|
3
3
|
import { WebRenderContext } from "./render-context";
|
|
4
4
|
import { WebStorageAdapter } from "./storage-adapter";
|
|
5
5
|
import { getCanvasKit } from "./getter";
|
|
6
|
-
import { DEFAULT_OUTPUT } from "./output";
|
|
7
6
|
const EMPTY_MANIFEST = { image: {}, video: {}, audio: {}, font: {} };
|
|
8
7
|
/** Normalize the many ways a caller can name a frame into the engine's own form. */
|
|
9
|
-
export function
|
|
10
|
-
if (options?.time !== undefined)
|
|
11
|
-
return
|
|
12
|
-
}
|
|
8
|
+
export function stillFrameSpec(options, fps) {
|
|
9
|
+
if (options?.time !== undefined)
|
|
10
|
+
return frameSpecAtTime(options.time, fps);
|
|
13
11
|
const frame = options?.frame;
|
|
14
12
|
if (frame === undefined || frame === "first")
|
|
15
13
|
return { kind: "first" };
|
|
@@ -51,6 +49,11 @@ function mimeOf(format) {
|
|
|
51
49
|
* different themes still each draw correctly; but anything else that calls
|
|
52
50
|
* `setTheme` between a render and a read of the surface will have been
|
|
53
51
|
* overwritten by the next render.
|
|
52
|
+
*
|
|
53
|
+
* **One surface, one caller at a time.** A render and the encode of its result
|
|
54
|
+
* are two calls, and the next render draws over the surface between them, so
|
|
55
|
+
* callers that share a renderer without knowing of each other must be queued —
|
|
56
|
+
* as `session.image()` queues its calls.
|
|
54
57
|
*/
|
|
55
58
|
export class StillRenderer {
|
|
56
59
|
canvas;
|
|
@@ -63,16 +66,21 @@ export class StillRenderer {
|
|
|
63
66
|
viewportValue;
|
|
64
67
|
fpsValue;
|
|
65
68
|
scaleValue;
|
|
69
|
+
/** What the canvas is sized at now, which a call's own `scale` changes. */
|
|
70
|
+
surfaceScale;
|
|
66
71
|
manifest;
|
|
67
72
|
theme;
|
|
68
73
|
registry;
|
|
69
74
|
disposed = false;
|
|
75
|
+
/** False until a frame has been drawn onto the current surface; a remount clears it. */
|
|
76
|
+
drawn = false;
|
|
70
77
|
/** @internal Use {@link createStillRenderer}, which loads CanvasKit first. */
|
|
71
78
|
constructor(canvasKit, options) {
|
|
72
79
|
this.canvasKit = canvasKit;
|
|
73
80
|
this.viewportValue = options.viewport ?? DEFAULT_OUTPUT.viewport;
|
|
74
81
|
this.fpsValue = options.fps ?? DEFAULT_OUTPUT.fps;
|
|
75
82
|
this.scaleValue = options.scale ?? 1;
|
|
83
|
+
this.surfaceScale = this.scaleValue;
|
|
76
84
|
this.manifest = options.manifest ?? EMPTY_MANIFEST;
|
|
77
85
|
this.theme = options.theme;
|
|
78
86
|
this.registry = options.registry ?? new Registry();
|
|
@@ -98,24 +106,21 @@ export class StillRenderer {
|
|
|
98
106
|
async render(source, options) {
|
|
99
107
|
this.assertLive();
|
|
100
108
|
const scale = options?.scale ?? this.scaleValue;
|
|
101
|
-
if (scale !== this.
|
|
102
|
-
this.
|
|
103
|
-
this.remount();
|
|
104
|
-
}
|
|
109
|
+
if (scale !== this.surfaceScale)
|
|
110
|
+
this.remount(scale);
|
|
105
111
|
const project = resolveProjectDocument(source, { viewport: this.viewportValue }, { viewport: this.viewportValue, fps: this.fpsValue });
|
|
106
|
-
|
|
107
|
-
// registry, so a second renderer (or the player) may have replaced it
|
|
108
|
-
// since. Cheap — a map swap.
|
|
109
|
-
setTheme(project.theme ?? this.theme);
|
|
110
|
-
return drawFrameAt({
|
|
112
|
+
const frame = await drawFrameAt({
|
|
111
113
|
project,
|
|
112
114
|
registry: this.registry,
|
|
115
|
+
theme: this.theme,
|
|
113
116
|
scale,
|
|
114
117
|
renderContext: this.renderContext,
|
|
115
118
|
storageAdapter: this.storageAdapter,
|
|
116
119
|
assetCatalog: this.catalog,
|
|
117
|
-
frame:
|
|
120
|
+
frame: stillFrameSpec(options, project.fps),
|
|
118
121
|
});
|
|
122
|
+
this.drawn = true;
|
|
123
|
+
return frame;
|
|
119
124
|
}
|
|
120
125
|
/** Theme for a document that carries none of its own. */
|
|
121
126
|
setTheme(theme) { this.theme = theme; }
|
|
@@ -146,7 +151,7 @@ export class StillRenderer {
|
|
|
146
151
|
this.renderContext.dispose();
|
|
147
152
|
this.storageAdapter = new WebStorageAdapter(this.canvasKit, this.catalog, viewport, this.fpsValue);
|
|
148
153
|
this.renderContext = new WebRenderContext(this.canvasKit, this.storageAdapter);
|
|
149
|
-
this.remount();
|
|
154
|
+
this.remount(this.scaleValue);
|
|
150
155
|
}
|
|
151
156
|
/** Encode the frame currently on the surface. */
|
|
152
157
|
async toBytes(options) {
|
|
@@ -183,7 +188,7 @@ export class StillRenderer {
|
|
|
183
188
|
*/
|
|
184
189
|
snapshotToCanvas() {
|
|
185
190
|
this.assertLive();
|
|
186
|
-
const snapshot = this.renderContext.snapshotPixels();
|
|
191
|
+
const snapshot = this.drawn ? this.renderContext.snapshotPixels() : undefined;
|
|
187
192
|
if (!snapshot)
|
|
188
193
|
throw new Error("Nothing has been rendered yet.");
|
|
189
194
|
const canvas = document.createElement("canvas");
|
|
@@ -197,11 +202,13 @@ export class StillRenderer {
|
|
|
197
202
|
return canvas;
|
|
198
203
|
}
|
|
199
204
|
sizeCanvas() {
|
|
200
|
-
this.canvas.width = this.viewportValue.width * this.
|
|
201
|
-
this.canvas.height = this.viewportValue.height * this.
|
|
205
|
+
this.canvas.width = this.viewportValue.width * this.surfaceScale;
|
|
206
|
+
this.canvas.height = this.viewportValue.height * this.surfaceScale;
|
|
202
207
|
}
|
|
203
208
|
/** Resize the backing store and build a fresh Skia surface over it. */
|
|
204
|
-
remount() {
|
|
209
|
+
remount(scale) {
|
|
210
|
+
this.surfaceScale = scale;
|
|
211
|
+
this.drawn = false;
|
|
205
212
|
this.sizeCanvas();
|
|
206
213
|
this.renderContext.mount(this.canvas);
|
|
207
214
|
}
|
package/dist/still.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"still.js","sourceRoot":"","sources":["../src/still.ts"],"names":[],"mappings":"AAAA,OAAO,EACW,oBAAoB,EAClC,QAAQ,EACR,sBAAsB,EACtB,QAAQ,GAMX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACH,WAAW,GAId,MAAM,kCAAkC,CAAC;AAC1C,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,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,cAAc,GAAkB,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AA2DpF,oFAAoF;AACpF,MAAM,UAAU,WAAW,CAAC,OAAuC,EAAE,GAAW;IAC5E,IAAI,OAAO,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;IACpE,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;IAC7B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACvE,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC/D,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,MAAM,CAAC,MAAwB;IACpC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,OAAO,aAAa;IACb,MAAM,CAAoB;IAE3B,aAAa,CAAmB;IAChC,cAAc,CAAoB;IAClC,OAAO,CAAe;IAEb,SAAS,CAA2C;IACrE,yDAAyD;IACxC,UAAU,CAAU;IAE7B,aAAa,CAAS;IACb,QAAQ,CAAS;IAC1B,UAAU,CAAS;IACnB,QAAQ,CAAgB;IACxB,KAAK,CAAS;IACL,QAAQ,CAAW;IAC5B,QAAQ,GAAG,KAAK,CAAC;IAEzB,8EAA8E;IAC9E,YACI,SAAmD,EACnD,OAA6B;QAE7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC;QACjE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,CAAC;QACnD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,QAAQ,EAAE,CAAC;QAEnD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC;QAC/C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YACnC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,UAAU,EAAE,CAAC;QAElB,IAAI,CAAC,OAAO,GAAG,IAAI,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,CAAC,cAAc,GAAG,IAAI,iBAAiB,CACvC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAC7D,CAAC;QACF,IAAI,CAAC,aAAa,GAAG,IAAI,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1E,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,QAAQ,KAAa,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACrD,IAAI,GAAG,KAAa,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAa,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE/C;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,MAAmB,EAAE,OAA4B;QAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC;QAChD,IAAI,KAAK,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;QAED,MAAM,OAAO,GAAG,sBAAsB,CAClC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,CACjG,CAAC;QACF,kEAAkE;QAClE,sEAAsE;QACtE,6BAA6B;QAC7B,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAEtC,OAAO,WAAW,CAAC;YACf,OAAO;YACP,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK;YACL,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,YAAY,EAAE,IAAI,CAAC,OAAO;YAC1B,KAAK,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GAAI,CAAC;SAC5C,CAAC,CAAC;IACP,CAAC;IAED,yDAAyD;IACzD,QAAQ,CAAC,KAAa,IAAU,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;IAErD,oEAAoE;IACpE,WAAW,CAAC,QAAuB;QAC/B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;;OAQG;IACH,WAAW,CAAC,QAAgB;QACxB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YAC/F,OAAO;QACX,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,wEAAwE;QACxE,8DAA8D;QAC9D,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,IAAI,iBAAiB,CACvC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CACxD,CAAC;QACF,IAAI,CAAC,aAAa,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/E,IAAI,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,OAAO,CAAC,OAA4B;QACtC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,iDAAiD;IACjD,MAAM,CAAC,OAA4B;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvC,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,MAAM,CAAC,MAAM,CACT,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;gBACV,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;gBACf,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,EACzD,MAAM,CAAC,MAAM,CAAC,EACd,OAAO,CACV,CAAC;QACN,CAAC,CAAC,CAAC;IACP,CAAC;IAED,iDAAiD;IACjD,SAAS,CAAC,OAA4B;QAClC,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAED,OAAO;QACH,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACK,gBAAgB;QACpB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,CAAC;QACrD,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QAC9B,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAChC,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACvE,6EAA6E;QAC7E,GAAG,CAAC,YAAY,CACZ,IAAI,SAAS,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtF,CAAC,EAAE,CAAC,CACP,CAAC;QACF,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,UAAU;QACd,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;IACrE,CAAC;IAED,uEAAuE;IAC/D,OAAO;QACX,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAEO,UAAU;QACd,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAChF,CAAC;CACJ;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACrC,UAAgC,EAAE;IAElC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,OAAO,IAAI,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import {\n AssetCatalog, ManifestAssetCatalog,\n Registry,\n resolveProjectDocument,\n setTheme,\n type AssetManifest,\n type ProjectDocument,\n type SceneDocument,\n type Size2D,\n type Theme,\n} from \"@motionscript/core\";\nimport {\n drawFrameAt,\n type DrawnFrame,\n type FrameSpec,\n type ScreenshotFormat,\n} from \"@motionscript/skia-render/export\";\nimport { WebRenderContext } from \"./render-context\";\nimport { WebStorageAdapter } from \"./storage-adapter\";\nimport { getCanvasKit } from \"./getter\";\nimport { DEFAULT_OUTPUT } from \"./output\";\n\nconst EMPTY_MANIFEST: AssetManifest = { image: {}, video: {}, audio: {}, font: {} };\n\n/** Anything a still can be rendered from: a project, or a lone still or composition as the one track of one. */\nexport type StillSource = ProjectDocument | SceneDocument;\n\n/**\n * Which frame to draw, in whatever form is most convenient — a global frame\n * index, the timeline's first or last frame, or a `FrameSpec`.\n */\nexport type FrameRef = FrameSpec | number | \"first\" | \"last\";\n\nexport interface StillRendererOptions {\n /**\n * The canvas to draw into. Omit and the renderer creates its own hidden one\n * and removes it on {@link StillRenderer.dispose} — which is what a one-shot\n * capture wants, while a live preview passes the canvas it already shows.\n */\n canvas?: HTMLCanvasElement;\n /** Output resolution in pixels, whatever the document asks for. Defaults to 1920×1080. */\n viewport?: Size2D;\n /** Frame rate for a document that sets none. Defaults to 60. */\n fps?: number;\n /** Device pixel ratio the surface is sized at. Defaults to 1. */\n scale?: number;\n manifest?: AssetManifest;\n /** Theme for a document that carries none of its own. */\n theme?: Theme;\n wasmUrl?: string;\n /**\n * The vocabulary a document is compiled against.\n *\n * Defaults to a fresh one carrying only what the library ships — a renderer\n * owns its registry the way an engine does, so a host with custom node types\n * passes the same one it gave its engine rather than relying on whatever a\n * module happened to register.\n */\n registry?: Registry;\n}\n\nexport interface RenderStillOptions {\n /** Which frame to draw. Defaults to the timeline's first. */\n frame?: FrameRef;\n /** Seconds into the timeline, converted with the document's fps. Wins over `frame`. */\n time?: number;\n /**\n * Draw at this pixel ratio instead of the renderer's. **Resizes the canvas and\n * rebuilds the Skia surface**, so keep it off the per-edit path — render the\n * preview at its normal scale and pass this only when capturing at a higher one.\n */\n scale?: number;\n}\n\nexport interface EncodeStillOptions {\n /** Defaults to `\"png\"`. */\n format?: ScreenshotFormat;\n /** JPEG quality in [0,1]; ignored for png. Defaults to 0.92. */\n quality?: number;\n}\n\n/** Normalize the many ways a caller can name a frame into the engine's own form. */\nexport function toFrameSpec(options: RenderStillOptions | undefined, fps: number): FrameSpec {\n if (options?.time !== undefined) {\n return { kind: \"frame\", frame: Math.round(options.time * fps) };\n }\n const frame = options?.frame;\n if (frame === undefined || frame === \"first\") return { kind: \"first\" };\n if (frame === \"last\") return { kind: \"last\" };\n if (typeof frame === \"number\") return { kind: \"frame\", frame };\n return frame;\n}\n\nfunction mimeOf(format: ScreenshotFormat): string {\n return format === \"jpeg\" ? \"image/jpeg\" : \"image/png\";\n}\n\n/**\n * A long-lived single-frame renderer.\n *\n * Where `exportScreenshot` is one frame from a standing start, this keeps the\n * expensive things — the CanvasKit module, the WebGL Skia surface, and the\n * storage adapter's decoded-asset cache — alive across calls, so re-rendering\n * after an edit costs discovering one frame and a draw rather than a new GL\n * context. That is\n * the difference between a one-off capture and a builder that repaints while the\n * user types.\n *\n * It is also the *same* draw: {@link render} goes through `drawFrameAt`, which is\n * the pass the video exporter runs per frame. A preview and its exported image\n * cannot drift apart, because there is only one path.\n *\n * ```ts\n * const renderer = await createStillRenderer({ canvas, viewport, manifest, theme });\n * await renderer.render({ kind: \"still\", nodes: [\n * { id: \"bg\", type: \"rect\", parentId: null, layerOrder: 0, props: { width: 1920, height: 1080, fill: \"bg\" } },\n * ] });\n * const blob = await renderer.toBlob({ format: \"png\" });\n * renderer.dispose();\n * ```\n *\n * **The theme is process-global in core.** {@link render} re-applies the\n * document's (or this renderer's) before every draw, so two renderers with\n * different themes still each draw correctly; but anything else that calls\n * `setTheme` between a render and a read of the surface will have been\n * overwritten by the next render.\n */\nexport class StillRenderer {\n readonly canvas: HTMLCanvasElement;\n\n private renderContext: WebRenderContext;\n private storageAdapter: WebStorageAdapter;\n private catalog: AssetCatalog;\n\n private readonly canvasKit: Awaited<ReturnType<typeof getCanvasKit>>;\n /** True when we made the canvas and must clean it up. */\n private readonly ownsCanvas: boolean;\n\n private viewportValue: Size2D;\n private readonly fpsValue: number;\n private scaleValue: number;\n private manifest: AssetManifest;\n private theme?: Theme;\n private readonly registry: Registry;\n private disposed = false;\n\n /** @internal Use {@link createStillRenderer}, which loads CanvasKit first. */\n constructor(\n canvasKit: Awaited<ReturnType<typeof getCanvasKit>>,\n options: StillRendererOptions,\n ) {\n this.canvasKit = canvasKit;\n this.viewportValue = options.viewport ?? DEFAULT_OUTPUT.viewport;\n this.fpsValue = options.fps ?? DEFAULT_OUTPUT.fps;\n this.scaleValue = options.scale ?? 1;\n this.manifest = options.manifest ?? EMPTY_MANIFEST;\n this.theme = options.theme;\n this.registry = options.registry ?? new Registry();\n\n this.ownsCanvas = options.canvas === undefined;\n this.canvas = options.canvas ?? document.createElement(\"canvas\");\n if (this.ownsCanvas) {\n this.canvas.style.display = \"none\";\n document.body.appendChild(this.canvas);\n }\n this.sizeCanvas();\n\n this.catalog = new ManifestAssetCatalog(this.manifest);\n this.storageAdapter = new WebStorageAdapter(\n canvasKit, this.catalog, this.viewportValue, this.fpsValue,\n );\n this.renderContext = new WebRenderContext(canvasKit, this.storageAdapter);\n this.renderContext.mount(this.canvas);\n }\n\n get viewport(): Size2D { return this.viewportValue; }\n get fps(): number { return this.fpsValue; }\n get scale(): number { return this.scaleValue; }\n\n /**\n * Draw one frame of `source`, at this renderer's viewport — the surface is\n * the output, so it wins over any size the document asks for.\n */\n async render(source: StillSource, options?: RenderStillOptions): Promise<DrawnFrame> {\n this.assertLive();\n const scale = options?.scale ?? this.scaleValue;\n if (scale !== this.scaleValue) {\n this.scaleValue = scale;\n this.remount();\n }\n\n const project = resolveProjectDocument(\n source, { viewport: this.viewportValue }, { viewport: this.viewportValue, fps: this.fpsValue },\n );\n // Re-applied per render, not once at construction: it is a global\n // registry, so a second renderer (or the player) may have replaced it\n // since. Cheap — a map swap.\n setTheme(project.theme ?? this.theme);\n\n return drawFrameAt({\n project,\n registry: this.registry,\n scale,\n renderContext: this.renderContext,\n storageAdapter: this.storageAdapter,\n assetCatalog: this.catalog,\n frame: toFrameSpec(options, project.fps!),\n });\n }\n\n /** Theme for a document that carries none of its own. */\n setTheme(theme?: Theme): void { this.theme = theme; }\n\n /** Swap the asset manifest, keeping every decode already cached. */\n setManifest(manifest: AssetManifest): void {\n this.assertLive();\n this.manifest = manifest;\n this.catalog = new ManifestAssetCatalog(manifest);\n this.storageAdapter.setCatalog(this.catalog);\n }\n\n /**\n * Change the output resolution.\n *\n * A full reset, unlike {@link setManifest}: the viewport clamps the resolution\n * images are decoded *at*, so cached decodes made for the old one would be\n * soft at the new one, and the render context's handlers captured the adapter\n * when they were built — so both are rebuilt. Call this when the output format\n * changes, not per edit.\n */\n setViewport(viewport: Size2D): void {\n this.assertLive();\n if (viewport.width === this.viewportValue.width && viewport.height === this.viewportValue.height) {\n return;\n }\n this.viewportValue = viewport;\n // Disposing the context disposes the adapter it holds, so this releases\n // the old surface, its handlers and every decode in one call.\n this.renderContext.dispose();\n this.storageAdapter = new WebStorageAdapter(\n this.canvasKit, this.catalog, viewport, this.fpsValue,\n );\n this.renderContext = new WebRenderContext(this.canvasKit, this.storageAdapter);\n this.remount();\n }\n\n /** Encode the frame currently on the surface. */\n async toBytes(options?: EncodeStillOptions): Promise<Uint8Array> {\n const blob = await this.toBlob(options);\n return new Uint8Array(await blob.arrayBuffer());\n }\n\n /** Encode the frame currently on the surface. */\n toBlob(options?: EncodeStillOptions): Promise<Blob> {\n const canvas = this.snapshotToCanvas();\n const { format = \"png\", quality = 0.92 } = options ?? {};\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => blob\n ? resolve(blob)\n : reject(new Error(\"Still encode produced no data.\")),\n mimeOf(format),\n quality,\n );\n });\n }\n\n /** Encode the frame currently on the surface. */\n toDataURL(options?: EncodeStillOptions): string {\n const { format = \"png\", quality = 0.92 } = options ?? {};\n return this.snapshotToCanvas().toDataURL(mimeOf(format), quality);\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.renderContext.dispose();\n if (this.ownsCanvas) this.canvas.remove();\n }\n\n /**\n * Read the surface back into a 2D canvas, which is what actually encodes: this\n * CanvasKit build ships no wasm image encoders, so the browser's own codecs are\n * the only ones available.\n */\n private snapshotToCanvas(): HTMLCanvasElement {\n this.assertLive();\n const snapshot = this.renderContext.snapshotPixels();\n if (!snapshot) throw new Error(\"Nothing has been rendered yet.\");\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = snapshot.width;\n canvas.height = snapshot.height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"Still encode: could not get a 2d context.\");\n // `pixels` is unpremultiplied RGBA8888, which is exactly ImageData's layout.\n ctx.putImageData(\n new ImageData(new Uint8ClampedArray(snapshot.pixels), snapshot.width, snapshot.height),\n 0, 0,\n );\n return canvas;\n }\n\n private sizeCanvas(): void {\n this.canvas.width = this.viewportValue.width * this.scaleValue;\n this.canvas.height = this.viewportValue.height * this.scaleValue;\n }\n\n /** Resize the backing store and build a fresh Skia surface over it. */\n private remount(): void {\n this.sizeCanvas();\n this.renderContext.mount(this.canvas);\n }\n\n private assertLive(): void {\n if (this.disposed) throw new Error(\"This StillRenderer has been disposed.\");\n }\n}\n\n/**\n * Create a {@link StillRenderer}, loading CanvasKit if it isn't already.\n *\n * `getCanvasKit` memoizes, so a second renderer in the same page is cheap.\n */\nexport async function createStillRenderer(\n options: StillRendererOptions = {},\n): Promise<StillRenderer> {\n const canvasKit = await getCanvasKit(options.wasmUrl);\n return new StillRenderer(canvasKit, options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"still.js","sourceRoot":"","sources":["../src/still.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n AssetCatalog, DEFAULT_OUTPUT, ManifestAssetCatalog,\r\n frameSpecAtTime,\r\n Registry,\r\n resolveProjectDocument,\r\n type AssetManifest,\r\n type FrameSpec,\r\n type ProjectDocument,\r\n type VisualDocument,\r\n type Size2D,\r\n type Theme,\r\n} from \"@motionscript/core\";\r\nimport {\r\n drawFrameAt,\r\n type DrawnFrame,\r\n type ScreenshotFormat,\r\n} from \"@motionscript/skia-render/export\";\r\nimport { WebRenderContext } from \"./render-context\";\r\nimport { WebStorageAdapter } from \"./storage-adapter\";\r\nimport { getCanvasKit } from \"./getter\";\r\n\r\nconst EMPTY_MANIFEST: AssetManifest = { image: {}, video: {}, audio: {}, font: {} };\r\n\r\n/** Anything a still can be rendered from: a project, or a lone still or composition as the one track of one. */\r\nexport type StillSource = ProjectDocument | VisualDocument;\r\n\r\n/**\r\n * Which frame to draw, in whatever form is most convenient — a global frame\r\n * index, the timeline's first or last frame, or a `FrameSpec`.\r\n */\r\nexport type FrameRef = FrameSpec | number | \"first\" | \"last\";\r\n\r\nexport interface StillRendererOptions {\r\n /**\r\n * The canvas to draw into. Omit and the renderer creates its own hidden one\r\n * and removes it on {@link StillRenderer.dispose} — which is what a one-shot\r\n * capture wants, while a live preview passes the canvas it already shows.\r\n */\r\n canvas?: HTMLCanvasElement;\r\n /** Output resolution in pixels, whatever the document asks for. Defaults to 1920×1080. */\r\n viewport?: Size2D;\r\n /** Frame rate for a document that sets none. Defaults to 60. */\r\n fps?: number;\r\n /** Device pixel ratio the surface is sized at. Defaults to 1. */\r\n scale?: number;\r\n manifest?: AssetManifest;\r\n /** Theme for a document that carries none of its own. */\r\n theme?: Theme;\r\n wasmUrl?: string;\r\n /**\r\n * The vocabulary a document is compiled against.\r\n *\r\n * Defaults to a fresh one carrying only what the library ships — a renderer\r\n * owns its registry the way an engine does, so a host with custom node types\r\n * passes the same one it gave its engine rather than relying on whatever a\r\n * module happened to register.\r\n */\r\n registry?: Registry;\r\n}\r\n\r\nexport interface RenderStillOptions {\r\n /** Which frame to draw. Defaults to the timeline's first. */\r\n frame?: FrameRef;\r\n /** Seconds into the timeline, converted with the document's fps. Wins over `frame`. */\r\n time?: number;\r\n /**\r\n * Draw this call at this pixel ratio instead of the renderer's. **Resizes the\r\n * canvas and rebuilds the Skia surface**, and the next call without it rebuilds\r\n * them back, so keep it off the per-edit path — render the preview at its\r\n * normal scale and pass this only when capturing at a higher one.\r\n */\r\n scale?: number;\r\n}\r\n\r\nexport interface EncodeStillOptions {\r\n /** Defaults to `\"png\"`. */\r\n format?: ScreenshotFormat;\r\n /** JPEG quality in [0,1]; ignored for png. Defaults to 0.92. */\r\n quality?: number;\r\n}\r\n\r\n/** Normalize the many ways a caller can name a frame into the engine's own form. */\r\nexport function stillFrameSpec(options: RenderStillOptions | undefined, fps: number): FrameSpec {\r\n if (options?.time !== undefined) return frameSpecAtTime(options.time, fps);\r\n const frame = options?.frame;\r\n if (frame === undefined || frame === \"first\") return { kind: \"first\" };\r\n if (frame === \"last\") return { kind: \"last\" };\r\n if (typeof frame === \"number\") return { kind: \"frame\", frame };\r\n return frame;\r\n}\r\n\r\nfunction mimeOf(format: ScreenshotFormat): string {\r\n return format === \"jpeg\" ? \"image/jpeg\" : \"image/png\";\r\n}\r\n\r\n/**\r\n * A long-lived single-frame renderer.\r\n *\r\n * Where `exportScreenshot` is one frame from a standing start, this keeps the\r\n * expensive things — the CanvasKit module, the WebGL Skia surface, and the\r\n * storage adapter's decoded-asset cache — alive across calls, so re-rendering\r\n * after an edit costs discovering one frame and a draw rather than a new GL\r\n * context. That is\r\n * the difference between a one-off capture and a builder that repaints while the\r\n * user types.\r\n *\r\n * It is also the *same* draw: {@link render} goes through `drawFrameAt`, which is\r\n * the pass the video exporter runs per frame. A preview and its exported image\r\n * cannot drift apart, because there is only one path.\r\n *\r\n * ```ts\r\n * const renderer = await createStillRenderer({ canvas, viewport, manifest, theme });\r\n * await renderer.render({ kind: \"still\", nodes: [\r\n * { id: \"bg\", type: \"rect\", parentId: null, layerOrder: 0, props: { width: 1920, height: 1080, fill: \"bg\" } },\r\n * ] });\r\n * const blob = await renderer.toBlob({ format: \"png\" });\r\n * renderer.dispose();\r\n * ```\r\n *\r\n * **The theme is process-global in core.** {@link render} re-applies the\r\n * document's (or this renderer's) before every draw, so two renderers with\r\n * different themes still each draw correctly; but anything else that calls\r\n * `setTheme` between a render and a read of the surface will have been\r\n * overwritten by the next render.\r\n *\r\n * **One surface, one caller at a time.** A render and the encode of its result\r\n * are two calls, and the next render draws over the surface between them, so\r\n * callers that share a renderer without knowing of each other must be queued —\r\n * as `session.image()` queues its calls.\r\n */\r\nexport class StillRenderer {\r\n readonly canvas: HTMLCanvasElement;\r\n\r\n private renderContext: WebRenderContext;\r\n private storageAdapter: WebStorageAdapter;\r\n private catalog: AssetCatalog;\r\n\r\n private readonly canvasKit: Awaited<ReturnType<typeof getCanvasKit>>;\r\n /** True when we made the canvas and must clean it up. */\r\n private readonly ownsCanvas: boolean;\r\n\r\n private viewportValue: Size2D;\r\n private readonly fpsValue: number;\r\n private readonly scaleValue: number;\r\n /** What the canvas is sized at now, which a call's own `scale` changes. */\r\n private surfaceScale: number;\r\n private manifest: AssetManifest;\r\n private theme?: Theme;\r\n private readonly registry: Registry;\r\n private disposed = false;\r\n /** False until a frame has been drawn onto the current surface; a remount clears it. */\r\n private drawn = false;\r\n\r\n /** @internal Use {@link createStillRenderer}, which loads CanvasKit first. */\r\n constructor(\r\n canvasKit: Awaited<ReturnType<typeof getCanvasKit>>,\r\n options: StillRendererOptions,\r\n ) {\r\n this.canvasKit = canvasKit;\r\n this.viewportValue = options.viewport ?? DEFAULT_OUTPUT.viewport;\r\n this.fpsValue = options.fps ?? DEFAULT_OUTPUT.fps;\r\n this.scaleValue = options.scale ?? 1;\r\n this.surfaceScale = this.scaleValue;\r\n this.manifest = options.manifest ?? EMPTY_MANIFEST;\r\n this.theme = options.theme;\r\n this.registry = options.registry ?? new Registry();\r\n\r\n this.ownsCanvas = options.canvas === undefined;\r\n this.canvas = options.canvas ?? document.createElement(\"canvas\");\r\n if (this.ownsCanvas) {\r\n this.canvas.style.display = \"none\";\r\n document.body.appendChild(this.canvas);\r\n }\r\n this.sizeCanvas();\r\n\r\n this.catalog = new ManifestAssetCatalog(this.manifest);\r\n this.storageAdapter = new WebStorageAdapter(\r\n canvasKit, this.catalog, this.viewportValue, this.fpsValue,\r\n );\r\n this.renderContext = new WebRenderContext(canvasKit, this.storageAdapter);\r\n this.renderContext.mount(this.canvas);\r\n }\r\n\r\n get viewport(): Size2D { return this.viewportValue; }\r\n get fps(): number { return this.fpsValue; }\r\n get scale(): number { return this.scaleValue; }\r\n\r\n /**\r\n * Draw one frame of `source`, at this renderer's viewport — the surface is\r\n * the output, so it wins over any size the document asks for.\r\n */\r\n async render(source: StillSource, options?: RenderStillOptions): Promise<DrawnFrame> {\r\n this.assertLive();\r\n const scale = options?.scale ?? this.scaleValue;\r\n if (scale !== this.surfaceScale) this.remount(scale);\r\n\r\n const project = resolveProjectDocument(\r\n source, { viewport: this.viewportValue }, { viewport: this.viewportValue, fps: this.fpsValue },\r\n );\r\n\r\n const frame = await drawFrameAt({\r\n project,\r\n registry: this.registry,\r\n theme: this.theme,\r\n scale,\r\n renderContext: this.renderContext,\r\n storageAdapter: this.storageAdapter,\r\n assetCatalog: this.catalog,\r\n frame: stillFrameSpec(options, project.fps!),\r\n });\r\n this.drawn = true;\r\n return frame;\r\n }\r\n\r\n /** Theme for a document that carries none of its own. */\r\n setTheme(theme?: Theme): void { this.theme = theme; }\r\n\r\n /** Swap the asset manifest, keeping every decode already cached. */\r\n setManifest(manifest: AssetManifest): void {\r\n this.assertLive();\r\n this.manifest = manifest;\r\n this.catalog = new ManifestAssetCatalog(manifest);\r\n this.storageAdapter.setCatalog(this.catalog);\r\n }\r\n\r\n /**\r\n * Change the output resolution.\r\n *\r\n * A full reset, unlike {@link setManifest}: the viewport clamps the resolution\r\n * images are decoded *at*, so cached decodes made for the old one would be\r\n * soft at the new one, and the render context's handlers captured the adapter\r\n * when they were built — so both are rebuilt. Call this when the output format\r\n * changes, not per edit.\r\n */\r\n setViewport(viewport: Size2D): void {\r\n this.assertLive();\r\n if (viewport.width === this.viewportValue.width && viewport.height === this.viewportValue.height) {\r\n return;\r\n }\r\n this.viewportValue = viewport;\r\n // Disposing the context disposes the adapter it holds, so this releases\r\n // the old surface, its handlers and every decode in one call.\r\n this.renderContext.dispose();\r\n this.storageAdapter = new WebStorageAdapter(\r\n this.canvasKit, this.catalog, viewport, this.fpsValue,\r\n );\r\n this.renderContext = new WebRenderContext(this.canvasKit, this.storageAdapter);\r\n this.remount(this.scaleValue);\r\n }\r\n\r\n /** Encode the frame currently on the surface. */\r\n async toBytes(options?: EncodeStillOptions): Promise<Uint8Array> {\r\n const blob = await this.toBlob(options);\r\n return new Uint8Array(await blob.arrayBuffer());\r\n }\r\n\r\n /** Encode the frame currently on the surface. */\r\n toBlob(options?: EncodeStillOptions): Promise<Blob> {\r\n const canvas = this.snapshotToCanvas();\r\n const { format = \"png\", quality = 0.92 } = options ?? {};\r\n return new Promise((resolve, reject) => {\r\n canvas.toBlob(\r\n (blob) => blob\r\n ? resolve(blob)\r\n : reject(new Error(\"Still encode produced no data.\")),\r\n mimeOf(format),\r\n quality,\r\n );\r\n });\r\n }\r\n\r\n /** Encode the frame currently on the surface. */\r\n toDataURL(options?: EncodeStillOptions): string {\r\n const { format = \"png\", quality = 0.92 } = options ?? {};\r\n return this.snapshotToCanvas().toDataURL(mimeOf(format), quality);\r\n }\r\n\r\n dispose(): void {\r\n if (this.disposed) return;\r\n this.disposed = true;\r\n this.renderContext.dispose();\r\n if (this.ownsCanvas) this.canvas.remove();\r\n }\r\n\r\n /**\r\n * Read the surface back into a 2D canvas, which is what actually encodes: this\r\n * CanvasKit build ships no wasm image encoders, so the browser's own codecs are\r\n * the only ones available.\r\n */\r\n private snapshotToCanvas(): HTMLCanvasElement {\r\n this.assertLive();\r\n const snapshot = this.drawn ? this.renderContext.snapshotPixels() : undefined;\r\n if (!snapshot) throw new Error(\"Nothing has been rendered yet.\");\r\n\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.width = snapshot.width;\r\n canvas.height = snapshot.height;\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) throw new Error(\"Still encode: could not get a 2d context.\");\r\n // `pixels` is unpremultiplied RGBA8888, which is exactly ImageData's layout.\r\n ctx.putImageData(\r\n new ImageData(new Uint8ClampedArray(snapshot.pixels), snapshot.width, snapshot.height),\r\n 0, 0,\r\n );\r\n return canvas;\r\n }\r\n\r\n private sizeCanvas(): void {\r\n this.canvas.width = this.viewportValue.width * this.surfaceScale;\r\n this.canvas.height = this.viewportValue.height * this.surfaceScale;\r\n }\r\n\r\n /** Resize the backing store and build a fresh Skia surface over it. */\r\n private remount(scale: number): void {\r\n this.surfaceScale = scale;\r\n this.drawn = false;\r\n this.sizeCanvas();\r\n this.renderContext.mount(this.canvas);\r\n }\r\n\r\n private assertLive(): void {\r\n if (this.disposed) throw new Error(\"This StillRenderer has been disposed.\");\r\n }\r\n}\r\n\r\n/**\r\n * Create a {@link StillRenderer}, loading CanvasKit if it isn't already.\r\n *\r\n * `getCanvasKit` memoizes, so a second renderer in the same page is cheap.\r\n */\r\nexport async function createStillRenderer(\r\n options: StillRendererOptions = {},\r\n): Promise<StillRenderer> {\r\n const canvasKit = await getCanvasKit(options.wasmUrl);\r\n return new StillRenderer(canvasKit, options);\r\n}\r\n"]}
|
|
@@ -170,7 +170,7 @@ export declare class WebStorageAdapter extends StorageAdapter implements SkiaAss
|
|
|
170
170
|
* The compressed bytes for `src`, from the host's local store if it has
|
|
171
171
|
* them and from the network otherwise. Every byte-reading path goes through
|
|
172
172
|
* this, so a source is local for all of images, video, audio and fonts or
|
|
173
|
-
* for none of them.
|
|
173
|
+
* for none of them. A response that is not OK rejects, naming the address.
|
|
174
174
|
*/
|
|
175
175
|
private fetchBlob;
|
|
176
176
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-adapter.d.ts","sourceRoot":"","sources":["../src/storage-adapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"storage-adapter.d.ts","sourceRoot":"","sources":["../src/storage-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/storage-adapter.js
CHANGED
|
@@ -3,7 +3,7 @@ import { ALL_FORMATS, BlobSource, Input, UrlSource, VideoSampleSink } from "medi
|
|
|
3
3
|
import { ParagraphShapeCache } from "@motionscript/skia-render/shapes/paragraph-cache";
|
|
4
4
|
// Type-only three usage keeps this a real lazy boundary — see three/bridge.ts.
|
|
5
5
|
import { hasPendingCanvas3D, warmPendingCanvas3D } from "@motionscript/skia-render/three/bridge";
|
|
6
|
-
import { localAssetBytes } from "./asset-bytes";
|
|
6
|
+
import { fetchAssetBytes, localAssetBytes } from "./asset-bytes";
|
|
7
7
|
import { ImageLevelCache } from "./decode/image-levels";
|
|
8
8
|
import { levelCap, levelSize, MAX_IMAGE_DECODE_EDGE } from "./decode/levels";
|
|
9
9
|
import { VideoLevel, videoWindowFrames } from "./decode/video-levels";
|
|
@@ -366,13 +366,13 @@ export class WebStorageAdapter extends StorageAdapter {
|
|
|
366
366
|
* The compressed bytes for `src`, from the host's local store if it has
|
|
367
367
|
* them and from the network otherwise. Every byte-reading path goes through
|
|
368
368
|
* this, so a source is local for all of images, video, audio and fonts or
|
|
369
|
-
* for none of them.
|
|
369
|
+
* for none of them. A response that is not OK rejects, naming the address.
|
|
370
370
|
*/
|
|
371
371
|
async fetchBlob(src) {
|
|
372
372
|
const local = await localAssetBytes(src);
|
|
373
373
|
if (local)
|
|
374
374
|
return local;
|
|
375
|
-
return (
|
|
375
|
+
return fetchAssetBytes(src);
|
|
376
376
|
}
|
|
377
377
|
/**
|
|
378
378
|
* The address `src` is fetched from.
|
|
@@ -1197,10 +1197,11 @@ export class WebStorageAdapter extends StorageAdapter {
|
|
|
1197
1197
|
return true;
|
|
1198
1198
|
const metas = this.catalog.getFontFamilyMetas(fontFamily);
|
|
1199
1199
|
if (metas.length === 0) {
|
|
1200
|
-
// Not an error: an undescribed family shapes against
|
|
1201
|
-
// fallback.
|
|
1202
|
-
//
|
|
1203
|
-
|
|
1200
|
+
// Not an error while previewing: an undescribed family shapes against
|
|
1201
|
+
// the platform fallback. A blocking caller is refused by the base
|
|
1202
|
+
// class instead, so only a preview is warned, once per family per
|
|
1203
|
+
// catalog, since it retries on every `loadAt`.
|
|
1204
|
+
if (this.decodePolicy === "interactive" && !this.unknownFontFamilies.has(fontFamily)) {
|
|
1204
1205
|
this.unknownFontFamilies.add(fontFamily);
|
|
1205
1206
|
console.warn(`[WebStorageAdapter] No font manifest entry for "${key}"; shaping against the fallback face. Add it to the manifest font record.`);
|
|
1206
1207
|
}
|
|
@@ -1208,10 +1209,11 @@ export class WebStorageAdapter extends StorageAdapter {
|
|
|
1208
1209
|
}
|
|
1209
1210
|
// Dedupe by src in case the same file is registered under multiple keys.
|
|
1210
1211
|
const sources = [...new Set(metas.map(m => m.src))];
|
|
1211
|
-
|
|
1212
|
-
|
|
1212
|
+
// Every file arrives before any registers: a family missing a weight would
|
|
1213
|
+
// shape that weight against another, and the retry would register the rest twice.
|
|
1214
|
+
const files = await Promise.all(sources.map(async (src) => (await this.fetchBlob(src)).arrayBuffer()));
|
|
1215
|
+
for (const bytes of files)
|
|
1213
1216
|
this.fontMgr.registerFont(new Uint8Array(bytes), fontFamily);
|
|
1214
|
-
}));
|
|
1215
1217
|
this.registeredFontFamilies.add(fontFamily);
|
|
1216
1218
|
this.unknownFontFamilies.delete(fontFamily);
|
|
1217
1219
|
this.fontEpoch++;
|