@smoove/core 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/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/animation/color.d.ts +9 -0
- package/dist/animation/color.d.ts.map +1 -0
- package/dist/animation/color.js +224 -0
- package/dist/animation/color.js.map +1 -0
- package/dist/animation/easing.d.ts +22 -0
- package/dist/animation/easing.d.ts.map +1 -0
- package/dist/animation/easing.js +59 -0
- package/dist/animation/easing.js.map +1 -0
- package/dist/animation/interpolate-colors.d.ts +7 -0
- package/dist/animation/interpolate-colors.d.ts.map +1 -0
- package/dist/animation/interpolate-colors.js +19 -0
- package/dist/animation/interpolate-colors.js.map +1 -0
- package/dist/animation/interpolate.d.ts +12 -0
- package/dist/animation/interpolate.d.ts.map +1 -0
- package/dist/animation/interpolate.js +65 -0
- package/dist/animation/interpolate.js.map +1 -0
- package/dist/audio/asset.d.ts +21 -0
- package/dist/audio/asset.d.ts.map +1 -0
- package/dist/audio/asset.js +2 -0
- package/dist/audio/asset.js.map +1 -0
- package/dist/audio/audio-driver.d.ts +34 -0
- package/dist/audio/audio-driver.d.ts.map +1 -0
- package/dist/audio/audio-driver.js +2 -0
- package/dist/audio/audio-driver.js.map +1 -0
- package/dist/audio/audio-for-preview.d.ts +12 -0
- package/dist/audio/audio-for-preview.d.ts.map +1 -0
- package/dist/audio/audio-for-preview.js +70 -0
- package/dist/audio/audio-for-preview.js.map +1 -0
- package/dist/audio/audio-for-rendering.d.ts +16 -0
- package/dist/audio/audio-for-rendering.d.ts.map +1 -0
- package/dist/audio/audio-for-rendering.js +32 -0
- package/dist/audio/audio-for-rendering.js.map +1 -0
- package/dist/audio/audio-source-browser.d.ts +30 -0
- package/dist/audio/audio-source-browser.d.ts.map +1 -0
- package/dist/audio/audio-source-browser.js +139 -0
- package/dist/audio/audio-source-browser.js.map +1 -0
- package/dist/audio/audio-source.d.ts +38 -0
- package/dist/audio/audio-source.d.ts.map +1 -0
- package/dist/audio/audio-source.js +2 -0
- package/dist/audio/audio-source.js.map +1 -0
- package/dist/audio/index.d.ts +45 -0
- package/dist/audio/index.d.ts.map +1 -0
- package/dist/audio/index.js +143 -0
- package/dist/audio/index.js.map +1 -0
- package/dist/audio/mixer.d.ts +43 -0
- package/dist/audio/mixer.d.ts.map +1 -0
- package/dist/audio/mixer.js +51 -0
- package/dist/audio/mixer.js.map +1 -0
- package/dist/audio/types.d.ts +31 -0
- package/dist/audio/types.d.ts.map +1 -0
- package/dist/audio/types.js +2 -0
- package/dist/audio/types.js.map +1 -0
- package/dist/block.d.ts +16 -0
- package/dist/block.d.ts.map +1 -0
- package/dist/block.js +173 -0
- package/dist/block.js.map +1 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js.map +1 -0
- package/dist/easing.d.ts +22 -0
- package/dist/easing.d.ts.map +1 -0
- package/dist/easing.js +59 -0
- package/dist/easing.js.map +1 -0
- package/dist/emitter.d.ts +7 -0
- package/dist/emitter.d.ts.map +1 -0
- package/dist/emitter.js +29 -0
- package/dist/emitter.js.map +1 -0
- package/dist/engine/composition.d.ts +182 -0
- package/dist/engine/composition.d.ts.map +1 -0
- package/dist/engine/composition.js +527 -0
- package/dist/engine/composition.js.map +1 -0
- package/dist/engine/emitter.d.ts +7 -0
- package/dist/engine/emitter.d.ts.map +1 -0
- package/dist/engine/emitter.js +29 -0
- package/dist/engine/emitter.js.map +1 -0
- package/dist/engine/environment.d.ts +30 -0
- package/dist/engine/environment.d.ts.map +1 -0
- package/dist/engine/environment.js +27 -0
- package/dist/engine/environment.js.map +1 -0
- package/dist/engine/offsets.d.ts +39 -0
- package/dist/engine/offsets.d.ts.map +1 -0
- package/dist/engine/offsets.js +54 -0
- package/dist/engine/offsets.js.map +1 -0
- package/dist/engine/runtime-defaults.d.ts +50 -0
- package/dist/engine/runtime-defaults.d.ts.map +1 -0
- package/dist/engine/runtime-defaults.js +77 -0
- package/dist/engine/runtime-defaults.js.map +1 -0
- package/dist/engine/sequence.d.ts +44 -0
- package/dist/engine/sequence.d.ts.map +1 -0
- package/dist/engine/sequence.js +101 -0
- package/dist/engine/sequence.js.map +1 -0
- package/dist/engine/series.d.ts +40 -0
- package/dist/engine/series.d.ts.map +1 -0
- package/dist/engine/series.js +58 -0
- package/dist/engine/series.js.map +1 -0
- package/dist/engine/signal.d.ts +10 -0
- package/dist/engine/signal.d.ts.map +1 -0
- package/dist/engine/signal.js +39 -0
- package/dist/engine/signal.js.map +1 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js.map +1 -0
- package/dist/flex-engine.d.ts +31 -0
- package/dist/flex-engine.d.ts.map +1 -0
- package/dist/flex-engine.js +186 -0
- package/dist/flex-engine.js.map +1 -0
- package/dist/flex-types.d.ts +165 -0
- package/dist/flex-types.d.ts.map +1 -0
- package/dist/flex-types.js +2 -0
- package/dist/flex-types.js.map +1 -0
- package/dist/flex.d.ts +26 -0
- package/dist/flex.d.ts.map +1 -0
- package/dist/flex.js +179 -0
- package/dist/flex.js.map +1 -0
- package/dist/image.d.ts +10 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +156 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/interpolate-colors.d.ts +7 -0
- package/dist/interpolate-colors.d.ts.map +1 -0
- package/dist/interpolate-colors.js +240 -0
- package/dist/interpolate-colors.js.map +1 -0
- package/dist/interpolate.d.ts +12 -0
- package/dist/interpolate.d.ts.map +1 -0
- package/dist/interpolate.js +65 -0
- package/dist/interpolate.js.map +1 -0
- package/dist/layout/block.d.ts +54 -0
- package/dist/layout/block.d.ts.map +1 -0
- package/dist/layout/block.js +186 -0
- package/dist/layout/block.js.map +1 -0
- package/dist/layout/contract.d.ts +41 -0
- package/dist/layout/contract.d.ts.map +1 -0
- package/dist/layout/contract.js +8 -0
- package/dist/layout/contract.js.map +1 -0
- package/dist/layout/flex/engine.d.ts +31 -0
- package/dist/layout/flex/engine.d.ts.map +1 -0
- package/dist/layout/flex/engine.js +186 -0
- package/dist/layout/flex/engine.js.map +1 -0
- package/dist/layout/flex/flex.d.ts +31 -0
- package/dist/layout/flex/flex.d.ts.map +1 -0
- package/dist/layout/flex/flex.js +175 -0
- package/dist/layout/flex/flex.js.map +1 -0
- package/dist/layout/flex/mixin.d.ts +52 -0
- package/dist/layout/flex/mixin.d.ts.map +1 -0
- package/dist/layout/flex/mixin.js +114 -0
- package/dist/layout/flex/mixin.js.map +1 -0
- package/dist/layout/flex/types.d.ts +31 -0
- package/dist/layout/flex/types.d.ts.map +1 -0
- package/dist/layout/flex/types.js +2 -0
- package/dist/layout/flex/types.js.map +1 -0
- package/dist/layout/image.d.ts +46 -0
- package/dist/layout/image.d.ts.map +1 -0
- package/dist/layout/image.js +198 -0
- package/dist/layout/image.js.map +1 -0
- package/dist/layout/shapes.d.ts +72 -0
- package/dist/layout/shapes.d.ts.map +1 -0
- package/dist/layout/shapes.js +29 -0
- package/dist/layout/shapes.js.map +1 -0
- package/dist/layout/text/font.d.ts +92 -0
- package/dist/layout/text/font.d.ts.map +1 -0
- package/dist/layout/text/font.js +166 -0
- package/dist/layout/text/font.js.map +1 -0
- package/dist/layout/text/geometry.d.ts +31 -0
- package/dist/layout/text/geometry.d.ts.map +1 -0
- package/dist/layout/text/geometry.js +81 -0
- package/dist/layout/text/geometry.js.map +1 -0
- package/dist/layout/text/text.d.ts +98 -0
- package/dist/layout/text/text.d.ts.map +1 -0
- package/dist/layout/text/text.js +676 -0
- package/dist/layout/text/text.js.map +1 -0
- package/dist/layout/text/types.d.ts +103 -0
- package/dist/layout/text/types.d.ts.map +1 -0
- package/dist/layout/text/types.js +2 -0
- package/dist/layout/text/types.js.map +1 -0
- package/dist/media/audio/asset.d.ts +21 -0
- package/dist/media/audio/asset.d.ts.map +1 -0
- package/dist/media/audio/asset.js +2 -0
- package/dist/media/audio/asset.js.map +1 -0
- package/dist/media/audio/audio-driver.d.ts +34 -0
- package/dist/media/audio/audio-driver.d.ts.map +1 -0
- package/dist/media/audio/audio-driver.js +2 -0
- package/dist/media/audio/audio-driver.js.map +1 -0
- package/dist/media/audio/audio-for-preview.d.ts +47 -0
- package/dist/media/audio/audio-for-preview.d.ts.map +1 -0
- package/dist/media/audio/audio-for-preview.js +232 -0
- package/dist/media/audio/audio-for-preview.js.map +1 -0
- package/dist/media/audio/audio-for-rendering.d.ts +16 -0
- package/dist/media/audio/audio-for-rendering.d.ts.map +1 -0
- package/dist/media/audio/audio-for-rendering.js +32 -0
- package/dist/media/audio/audio-for-rendering.js.map +1 -0
- package/dist/media/audio/audio-source-browser.d.ts +30 -0
- package/dist/media/audio/audio-source-browser.d.ts.map +1 -0
- package/dist/media/audio/audio-source-browser.js +139 -0
- package/dist/media/audio/audio-source-browser.js.map +1 -0
- package/dist/media/audio/audio-source-mediabunny.d.ts +45 -0
- package/dist/media/audio/audio-source-mediabunny.d.ts.map +1 -0
- package/dist/media/audio/audio-source-mediabunny.js +79 -0
- package/dist/media/audio/audio-source-mediabunny.js.map +1 -0
- package/dist/media/audio/audio-source.d.ts +38 -0
- package/dist/media/audio/audio-source.d.ts.map +1 -0
- package/dist/media/audio/audio-source.js +2 -0
- package/dist/media/audio/audio-source.js.map +1 -0
- package/dist/media/audio/index.d.ts +57 -0
- package/dist/media/audio/index.d.ts.map +1 -0
- package/dist/media/audio/index.js +170 -0
- package/dist/media/audio/index.js.map +1 -0
- package/dist/media/audio/mixer.d.ts +43 -0
- package/dist/media/audio/mixer.d.ts.map +1 -0
- package/dist/media/audio/mixer.js +51 -0
- package/dist/media/audio/mixer.js.map +1 -0
- package/dist/media/audio/shared-audio-context.d.ts +30 -0
- package/dist/media/audio/shared-audio-context.d.ts.map +1 -0
- package/dist/media/audio/shared-audio-context.js +68 -0
- package/dist/media/audio/shared-audio-context.js.map +1 -0
- package/dist/media/audio/types.d.ts +31 -0
- package/dist/media/audio/types.d.ts.map +1 -0
- package/dist/media/audio/types.js +2 -0
- package/dist/media/audio/types.js.map +1 -0
- package/dist/media/media-marker.d.ts +26 -0
- package/dist/media/media-marker.d.ts.map +1 -0
- package/dist/media/media-marker.js +26 -0
- package/dist/media/media-marker.js.map +1 -0
- package/dist/media/media-time.d.ts +17 -0
- package/dist/media/media-time.d.ts.map +1 -0
- package/dist/media/media-time.js +17 -0
- package/dist/media/media-time.js.map +1 -0
- package/dist/media/video/driver.d.ts +31 -0
- package/dist/media/video/driver.d.ts.map +1 -0
- package/dist/media/video/driver.js +3 -0
- package/dist/media/video/driver.js.map +1 -0
- package/dist/media/video/index.d.ts +66 -0
- package/dist/media/video/index.d.ts.map +1 -0
- package/dist/media/video/index.js +372 -0
- package/dist/media/video/index.js.map +1 -0
- package/dist/media/video/types.d.ts +36 -0
- package/dist/media/video/types.d.ts.map +1 -0
- package/dist/media/video/types.js +2 -0
- package/dist/media/video/types.js.map +1 -0
- package/dist/media/video/video-for-preview.d.ts +17 -0
- package/dist/media/video/video-for-preview.d.ts.map +1 -0
- package/dist/media/video/video-for-preview.js +30 -0
- package/dist/media/video/video-for-preview.js.map +1 -0
- package/dist/media/video/video-for-rendering.d.ts +17 -0
- package/dist/media/video/video-for-rendering.d.ts.map +1 -0
- package/dist/media/video/video-for-rendering.js +59 -0
- package/dist/media/video/video-for-rendering.js.map +1 -0
- package/dist/media/video/video-source-browser.d.ts +37 -0
- package/dist/media/video/video-source-browser.d.ts.map +1 -0
- package/dist/media/video/video-source-browser.js +171 -0
- package/dist/media/video/video-source-browser.js.map +1 -0
- package/dist/media/video/video-source-mediabunny.d.ts +69 -0
- package/dist/media/video/video-source-mediabunny.d.ts.map +1 -0
- package/dist/media/video/video-source-mediabunny.js +236 -0
- package/dist/media/video/video-source-mediabunny.js.map +1 -0
- package/dist/media/video/video-source.d.ts +48 -0
- package/dist/media/video/video-source.d.ts.map +1 -0
- package/dist/media/video/video-source.js +2 -0
- package/dist/media/video/video-source.js.map +1 -0
- package/dist/media-marker.d.ts +19 -0
- package/dist/media-marker.d.ts.map +1 -0
- package/dist/media-marker.js +19 -0
- package/dist/media-marker.js.map +1 -0
- package/dist/media-time.d.ts +17 -0
- package/dist/media-time.d.ts.map +1 -0
- package/dist/media-time.js +17 -0
- package/dist/media-time.js.map +1 -0
- package/dist/signal.d.ts +10 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +39 -0
- package/dist/signal.js.map +1 -0
- package/dist/text.d.ts +91 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +704 -0
- package/dist/text.js.map +1 -0
- package/dist/video/driver.d.ts +31 -0
- package/dist/video/driver.d.ts.map +1 -0
- package/dist/video/driver.js +3 -0
- package/dist/video/driver.js.map +1 -0
- package/dist/video/index.d.ts +45 -0
- package/dist/video/index.d.ts.map +1 -0
- package/dist/video/index.js +276 -0
- package/dist/video/index.js.map +1 -0
- package/dist/video/types.d.ts +35 -0
- package/dist/video/types.d.ts.map +1 -0
- package/dist/video/types.js +2 -0
- package/dist/video/types.js.map +1 -0
- package/dist/video/video-for-preview.d.ts +12 -0
- package/dist/video/video-for-preview.d.ts.map +1 -0
- package/dist/video/video-for-preview.js +73 -0
- package/dist/video/video-for-preview.js.map +1 -0
- package/dist/video/video-for-rendering.d.ts +16 -0
- package/dist/video/video-for-rendering.d.ts.map +1 -0
- package/dist/video/video-for-rendering.js +45 -0
- package/dist/video/video-for-rendering.js.map +1 -0
- package/dist/video/video-source-browser.d.ts +37 -0
- package/dist/video/video-source-browser.d.ts.map +1 -0
- package/dist/video/video-source-browser.js +171 -0
- package/dist/video/video-source-browser.js.map +1 -0
- package/dist/video/video-source.d.ts +48 -0
- package/dist/video/video-source.d.ts.map +1 -0
- package/dist/video/video-source.js +2 -0
- package/dist/video/video-source.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import Konva from "konva";
|
|
2
|
+
import { AudioMixer } from "../media/audio/mixer.js";
|
|
3
|
+
import { FONT_MARK, MEDIA_MARK } from "../media/media-marker.js";
|
|
4
|
+
import { createEmitter } from "./emitter.js";
|
|
5
|
+
import { detectEnvironment } from "./environment.js";
|
|
6
|
+
import { Sequence } from "./sequence.js";
|
|
7
|
+
import { createSignal, derived } from "./signal.js";
|
|
8
|
+
/** A SequenceProvider duck-types on a `sequences()` method (Konva layers lack one). */
|
|
9
|
+
function isSequenceProvider(x) {
|
|
10
|
+
return typeof x.sequences === "function";
|
|
11
|
+
}
|
|
12
|
+
const COMP_EVENTS = new Set(["play", "stop", "time"]);
|
|
13
|
+
const isCompositionEvent = (e) => COMP_EVENTS.has(e);
|
|
14
|
+
const raf = typeof globalThis.requestAnimationFrame === "function"
|
|
15
|
+
? globalThis.requestAnimationFrame.bind(globalThis)
|
|
16
|
+
: null;
|
|
17
|
+
const caf = typeof globalThis.cancelAnimationFrame === "function"
|
|
18
|
+
? globalThis.cancelAnimationFrame.bind(globalThis)
|
|
19
|
+
: null;
|
|
20
|
+
const wallNow = () => typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now();
|
|
21
|
+
export function getComposition(stage) {
|
|
22
|
+
return stage.__SmooveComposition ?? null;
|
|
23
|
+
}
|
|
24
|
+
export class Composition extends Konva.Stage {
|
|
25
|
+
fps;
|
|
26
|
+
environment;
|
|
27
|
+
/** Composition-level audio bus — master volume/mute scaling every Video and Audio. */
|
|
28
|
+
mixer = new AudioMixer();
|
|
29
|
+
frame;
|
|
30
|
+
isPlaying;
|
|
31
|
+
durationInFrames;
|
|
32
|
+
isStopped;
|
|
33
|
+
isPaused;
|
|
34
|
+
loop;
|
|
35
|
+
/** Playback speed multiplier. 1 = realtime; negative plays in reverse. */
|
|
36
|
+
playbackRate;
|
|
37
|
+
/** Live props the scene reads. Pushed to with {@link setProps} by a player or
|
|
38
|
+
the studio form; updaters read it via `comp.props.get()`. */
|
|
39
|
+
props;
|
|
40
|
+
/** Asset-buffering state — `"idle"` | `"buffering"` | `"ready"`. See {@link registerAsset}. */
|
|
41
|
+
buffer;
|
|
42
|
+
/** Convenience: `buffer.get() === "buffering"`. */
|
|
43
|
+
isBuffering;
|
|
44
|
+
_frame;
|
|
45
|
+
_props;
|
|
46
|
+
_isPlaying;
|
|
47
|
+
_durationInFrames;
|
|
48
|
+
_loop;
|
|
49
|
+
_playbackRate;
|
|
50
|
+
_buffer;
|
|
51
|
+
_emitter;
|
|
52
|
+
_rafId = null;
|
|
53
|
+
_startWallMs = 0;
|
|
54
|
+
_startFrame = 0;
|
|
55
|
+
// Background work released by suspend() until resume() re-acquires it.
|
|
56
|
+
_suspended = false;
|
|
57
|
+
// Asset-buffering gate (the preview analogue of the delayRender render gate):
|
|
58
|
+
// outstanding asset loads that should be ready before playback advances.
|
|
59
|
+
_assets = new Set();
|
|
60
|
+
_readyWaiters = [];
|
|
61
|
+
// Set when play() is called while buffering — playback starts on buffer ready.
|
|
62
|
+
_resumeOnReady = false;
|
|
63
|
+
// delayRender/continueRender gate — outstanding async work that must complete
|
|
64
|
+
// before a rendered frame is captured (Remotion's delayRender model).
|
|
65
|
+
_renderHandles = new Set();
|
|
66
|
+
_nextHandle = 0;
|
|
67
|
+
_renderWaiters = [];
|
|
68
|
+
// Audio samples collected during offline rendering (one per Audio per frame),
|
|
69
|
+
// for an external audio-mux pass. Empty during preview.
|
|
70
|
+
_audioAssets = [];
|
|
71
|
+
// Reused scratch canvas for captureCanvas() — avoids a per-frame skia Canvas
|
|
72
|
+
// allocation (native memory V8's GC can't see) during long renders.
|
|
73
|
+
_captureCanvas = null;
|
|
74
|
+
constructor(opts) {
|
|
75
|
+
if (!opts.id)
|
|
76
|
+
throw new Error("Composition: id is required");
|
|
77
|
+
if (!Number.isFinite(opts.fps) || opts.fps <= 0) {
|
|
78
|
+
throw new Error("Composition: fps must be a positive number");
|
|
79
|
+
}
|
|
80
|
+
if (!Number.isInteger(opts.durationInFrames) || opts.durationInFrames <= 0) {
|
|
81
|
+
throw new Error("Composition: durationInFrames must be a positive integer");
|
|
82
|
+
}
|
|
83
|
+
const { fps, durationInFrames, loop = false, props, mode, ...stageOpts } = opts;
|
|
84
|
+
// Konva requires a container element. In the browser, fall back to a
|
|
85
|
+
// detached <div> when none is given, so a Composition can be constructed
|
|
86
|
+
// up-front and mounted later via `setContainer` (e.g. handed to a player).
|
|
87
|
+
// In non-browser runtimes (server rendering) there's no DOM, so leave it
|
|
88
|
+
// unset — frames are driven with `setFrame`/`renderFrame`, not a canvas.
|
|
89
|
+
if (stageOpts.container == null && typeof document !== "undefined") {
|
|
90
|
+
stageOpts.container = document.createElement("div");
|
|
91
|
+
}
|
|
92
|
+
super(stageOpts);
|
|
93
|
+
const marker = this;
|
|
94
|
+
if (marker.__SmooveComposition) {
|
|
95
|
+
throw new Error("A Composition is already attached to this Stage.");
|
|
96
|
+
}
|
|
97
|
+
marker.__SmooveComposition = this;
|
|
98
|
+
this.fps = fps;
|
|
99
|
+
this.environment = detectEnvironment(mode);
|
|
100
|
+
this._frame = createSignal(0);
|
|
101
|
+
this._isPlaying = createSignal(false);
|
|
102
|
+
this._durationInFrames = createSignal(durationInFrames);
|
|
103
|
+
this._loop = createSignal(loop);
|
|
104
|
+
this._playbackRate = createSignal(1);
|
|
105
|
+
this._props = createSignal(props ?? {});
|
|
106
|
+
this._buffer = createSignal("idle");
|
|
107
|
+
this.frame = this._frame;
|
|
108
|
+
this.isPlaying = this._isPlaying;
|
|
109
|
+
this.durationInFrames = this._durationInFrames;
|
|
110
|
+
this.loop = this._loop;
|
|
111
|
+
this.playbackRate = this._playbackRate;
|
|
112
|
+
this.props = this._props;
|
|
113
|
+
this.buffer = this._buffer;
|
|
114
|
+
this.isBuffering = derived([this._buffer], () => this._buffer.get() === "buffering");
|
|
115
|
+
this.isStopped = derived([this._isPlaying, this._frame], () => !this._isPlaying.get() && this._frame.get() === 0);
|
|
116
|
+
this.isPaused = derived([this._isPlaying, this._frame], () => !this._isPlaying.get() && this._frame.get() > 0);
|
|
117
|
+
this._emitter = createEmitter();
|
|
118
|
+
}
|
|
119
|
+
// biome-ignore lint/suspicious/noExplicitAny: bridges Konva's typed event API with our composition events.
|
|
120
|
+
on(evtStr, handler) {
|
|
121
|
+
if (typeof evtStr === "string" && isCompositionEvent(evtStr)) {
|
|
122
|
+
return this._emitter.on(evtStr, handler);
|
|
123
|
+
}
|
|
124
|
+
return super.on(evtStr, handler);
|
|
125
|
+
}
|
|
126
|
+
// biome-ignore lint/suspicious/noExplicitAny: see on() above.
|
|
127
|
+
off(evtStr, handler) {
|
|
128
|
+
if (typeof evtStr === "string" && isCompositionEvent(evtStr)) {
|
|
129
|
+
if (handler)
|
|
130
|
+
this._emitter.off(evtStr, handler);
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
return super.off(evtStr, handler);
|
|
134
|
+
}
|
|
135
|
+
add(first, ...rest) {
|
|
136
|
+
// Expand any SequenceProvider (Series / TransitionSeries) into its layers,
|
|
137
|
+
// so `comp.add(series)` works as well as `comp.add(layer)`.
|
|
138
|
+
const layers = [];
|
|
139
|
+
for (const item of [first, ...rest]) {
|
|
140
|
+
if (isSequenceProvider(item))
|
|
141
|
+
layers.push(...item.sequences());
|
|
142
|
+
else
|
|
143
|
+
layers.push(item);
|
|
144
|
+
}
|
|
145
|
+
if (layers.length === 0)
|
|
146
|
+
return this;
|
|
147
|
+
super.add(...layers);
|
|
148
|
+
const frame = this._frame.get();
|
|
149
|
+
// Pass 1 — register assets first (across ALL added layers) so a Font in any
|
|
150
|
+
// of them flips the buffer to "buffering" before we paint anything. Media is
|
|
151
|
+
// registered eagerly so mixer channels exist before playback (lazy fallback
|
|
152
|
+
// lives in each node's _ensureDriver / Font._kmTick).
|
|
153
|
+
for (const l of layers) {
|
|
154
|
+
if (l instanceof Sequence) {
|
|
155
|
+
for (const v of l.find((n) => n.getAttr(MEDIA_MARK) === true)) {
|
|
156
|
+
this.mixer.register(v);
|
|
157
|
+
}
|
|
158
|
+
for (const f of l.find((n) => n.getAttr(FONT_MARK) === true)) {
|
|
159
|
+
f._kmRegister?.(this);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Pass 2 — paint the current frame, unless we're now buffering: leave the
|
|
164
|
+
// sequences hidden (transparent) until assets load. The buffer-drain in
|
|
165
|
+
// registerAsset paints the first frame once everything is ready.
|
|
166
|
+
if (this._buffer.get() !== "buffering") {
|
|
167
|
+
for (const l of layers) {
|
|
168
|
+
if (l instanceof Sequence)
|
|
169
|
+
l._apply(frame, true);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
play() {
|
|
175
|
+
if (!raf || !caf) {
|
|
176
|
+
throw new Error("Composition.play() requires requestAnimationFrame. In non-browser environments, drive playback with setFrame() instead.");
|
|
177
|
+
}
|
|
178
|
+
if (this._isPlaying.get())
|
|
179
|
+
return;
|
|
180
|
+
// Buffer-aware: if assets are still loading, defer the clock and resume
|
|
181
|
+
// automatically once buffering completes (see registerAsset).
|
|
182
|
+
if (this._buffer.get() === "buffering") {
|
|
183
|
+
this._resumeOnReady = true;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
this._startClock();
|
|
187
|
+
}
|
|
188
|
+
_startClock() {
|
|
189
|
+
this._isPlaying.set(true);
|
|
190
|
+
this._startFrame = this._frame.get();
|
|
191
|
+
this._startWallMs = wallNow();
|
|
192
|
+
this._applyFrame(this._frame.get(), false);
|
|
193
|
+
this._emitter.emit("play", this._event());
|
|
194
|
+
this._scheduleTick();
|
|
195
|
+
}
|
|
196
|
+
destroy() {
|
|
197
|
+
this._cancelTick();
|
|
198
|
+
this._isPlaying.set(false);
|
|
199
|
+
return super.destroy();
|
|
200
|
+
}
|
|
201
|
+
pause() {
|
|
202
|
+
this._resumeOnReady = false;
|
|
203
|
+
if (!this._isPlaying.get())
|
|
204
|
+
return;
|
|
205
|
+
this._cancelTick();
|
|
206
|
+
this._isPlaying.set(false);
|
|
207
|
+
}
|
|
208
|
+
/** `true` between {@link suspend} and {@link resume}. */
|
|
209
|
+
get isSuspended() {
|
|
210
|
+
return this._suspended;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Release background work — halt the clock and tell every media node to drop
|
|
214
|
+
* its source, so a composition that isn't being shown (e.g. a `<smoove-player>`
|
|
215
|
+
* removed from the DOM) stops downloading/decoding video and audio. This does
|
|
216
|
+
* NOT tear the composition down: the scene graph stays intact and {@link resume}
|
|
217
|
+
* re-acquires the sources. No-op if already suspended.
|
|
218
|
+
*/
|
|
219
|
+
suspend() {
|
|
220
|
+
if (this._suspended)
|
|
221
|
+
return;
|
|
222
|
+
this._suspended = true;
|
|
223
|
+
this._resumeOnReady = false;
|
|
224
|
+
this._cancelTick();
|
|
225
|
+
if (this._isPlaying.get())
|
|
226
|
+
this._isPlaying.set(false);
|
|
227
|
+
this._forEachMedia((n) => n._kmSuspend?.());
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Undo {@link suspend}: re-acquire the media sources released while suspended
|
|
231
|
+
* (they re-download and redraw once ready) and repaint the current frame.
|
|
232
|
+
* No-op if not suspended.
|
|
233
|
+
*/
|
|
234
|
+
resume() {
|
|
235
|
+
if (!this._suspended)
|
|
236
|
+
return;
|
|
237
|
+
this._suspended = false;
|
|
238
|
+
this._forEachMedia((n) => n._kmResume?.());
|
|
239
|
+
// force: sources were dropped, so the same frame must be re-applied.
|
|
240
|
+
this._applyFrame(this._frame.get(), false, true);
|
|
241
|
+
}
|
|
242
|
+
/** Walk every media node (Video/Audio) across all sequences. */
|
|
243
|
+
_forEachMedia(cb) {
|
|
244
|
+
for (const child of this.getChildren()) {
|
|
245
|
+
if (child instanceof Sequence) {
|
|
246
|
+
for (const n of child.find((x) => x.getAttr(MEDIA_MARK) === true)) {
|
|
247
|
+
cb(n);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
stop() {
|
|
253
|
+
this._resumeOnReady = false;
|
|
254
|
+
this._cancelTick();
|
|
255
|
+
if (this._isPlaying.get())
|
|
256
|
+
this._isPlaying.set(false);
|
|
257
|
+
this._frame.set(0);
|
|
258
|
+
this._applyFrame(0, false);
|
|
259
|
+
this._emitter.emit("stop", this._event());
|
|
260
|
+
}
|
|
261
|
+
setLoop(value) {
|
|
262
|
+
this._loop.set(value);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Set the playback speed multiplier. `1` is realtime; `2` is double speed;
|
|
266
|
+
* negative values play in reverse. Clamped to `[-10, 10]`; `0` throws (it
|
|
267
|
+
* would freeze the clock). Changing the rate mid-playback resyncs the clock
|
|
268
|
+
* so the new speed takes effect from the current frame onward.
|
|
269
|
+
*/
|
|
270
|
+
setPlaybackRate(rate) {
|
|
271
|
+
if (!Number.isFinite(rate) || rate === 0) {
|
|
272
|
+
throw new Error("Composition.setPlaybackRate(): rate must be a non-zero finite number");
|
|
273
|
+
}
|
|
274
|
+
const clamped = Math.max(-10, Math.min(10, rate));
|
|
275
|
+
if (clamped === this._playbackRate.get())
|
|
276
|
+
return;
|
|
277
|
+
this._playbackRate.set(clamped);
|
|
278
|
+
if (this._isPlaying.get()) {
|
|
279
|
+
this._startFrame = this._frame.get();
|
|
280
|
+
this._startWallMs = wallNow();
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
setFrame(target) {
|
|
284
|
+
const clamped = Math.max(0, Math.min(this._durationInFrames.get() - 1, Math.floor(target)));
|
|
285
|
+
if (clamped === this._frame.get())
|
|
286
|
+
return;
|
|
287
|
+
this._frame.set(clamped);
|
|
288
|
+
if (this._isPlaying.get()) {
|
|
289
|
+
this._startFrame = clamped;
|
|
290
|
+
this._startWallMs = wallNow();
|
|
291
|
+
}
|
|
292
|
+
this._applyFrame(clamped, true);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Re-apply the **current** frame to every sequence without advancing the
|
|
296
|
+
* playhead — the engine's "re-render" hook. Call this after mutating external
|
|
297
|
+
* state that updaters read (e.g. live-edited props) so the change shows
|
|
298
|
+
* immediately while paused. Updaters re-run, `Flex`/`Block` re-layout, and
|
|
299
|
+
* active sequences `batchDraw` — exactly like a normal tick at the same frame.
|
|
300
|
+
*/
|
|
301
|
+
refresh() {
|
|
302
|
+
// force: props/external state may have changed at the same frame, so the
|
|
303
|
+
// sequence dedupe must not skip this re-apply.
|
|
304
|
+
this._applyFrame(this._frame.get(), false, true);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Replace the live props and re-render the current frame. Any holder — a bare
|
|
308
|
+
* `<smoove-player>` or the studio form — drives the scene by calling this; the
|
|
309
|
+
* `createSignal` `Object.is` guard skips a redundant refresh when nothing
|
|
310
|
+
* changed. Pass an updater to derive the next value from the previous one.
|
|
311
|
+
*/
|
|
312
|
+
setProps(next) {
|
|
313
|
+
const value = typeof next === "function" ? next(this._props.get()) : next;
|
|
314
|
+
if (Object.is(value, this._props.get()))
|
|
315
|
+
return;
|
|
316
|
+
this._props.set(value);
|
|
317
|
+
this.refresh();
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Register an outstanding asset load (e.g. a {@link Font}). While any asset is
|
|
321
|
+
* pending, {@link buffer} is `"buffering"`; once all settle it flips to
|
|
322
|
+
* `"ready"` and {@link whenReady} waiters resolve. A `play()` issued while
|
|
323
|
+
* buffering is deferred and starts automatically here. Errors are swallowed
|
|
324
|
+
* (the asset logs its own) so one bad asset can't wedge playback.
|
|
325
|
+
*
|
|
326
|
+
* This is the preview-side buffer; offline rendering uses the per-frame
|
|
327
|
+
* {@link delayRender}/{@link renderFrame} gate instead.
|
|
328
|
+
*/
|
|
329
|
+
registerAsset(load, _label) {
|
|
330
|
+
this._assets.add(load);
|
|
331
|
+
if (this._buffer.get() !== "buffering") {
|
|
332
|
+
this._buffer.set("buffering");
|
|
333
|
+
// Hide everything so the stage is transparent while assets load — no frame
|
|
334
|
+
// is shown over not-yet-loaded fonts.
|
|
335
|
+
this._hideAllSequences();
|
|
336
|
+
}
|
|
337
|
+
const settle = () => {
|
|
338
|
+
if (!this._assets.delete(load))
|
|
339
|
+
return;
|
|
340
|
+
if (this._assets.size > 0)
|
|
341
|
+
return;
|
|
342
|
+
this._buffer.set("ready");
|
|
343
|
+
const waiters = this._readyWaiters;
|
|
344
|
+
this._readyWaiters = [];
|
|
345
|
+
for (const resolve of waiters)
|
|
346
|
+
resolve();
|
|
347
|
+
// Now that assets are loaded, paint. If a play() was deferred, resume the
|
|
348
|
+
// clock (which applies the frame); otherwise paint the current frame once.
|
|
349
|
+
if (this._resumeOnReady) {
|
|
350
|
+
this._resumeOnReady = false;
|
|
351
|
+
this._startClock();
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
// force: first paint after assets settled, even though the frame is unchanged.
|
|
355
|
+
this._applyFrame(this._frame.get(), false, true);
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
load.then(settle, settle);
|
|
359
|
+
}
|
|
360
|
+
/** Resolves once no assets are pending — immediately if idle/ready. */
|
|
361
|
+
whenReady() {
|
|
362
|
+
if (this._assets.size === 0)
|
|
363
|
+
return Promise.resolve();
|
|
364
|
+
return new Promise((resolve) => {
|
|
365
|
+
this._readyWaiters.push(resolve);
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Register an outstanding async task that must finish before the current
|
|
370
|
+
* frame is considered fully rendered — Remotion's `delayRender`. Returns a
|
|
371
|
+
* handle to clear with {@link continueRender}.
|
|
372
|
+
*/
|
|
373
|
+
delayRender(_label) {
|
|
374
|
+
const handle = this._nextHandle++;
|
|
375
|
+
this._renderHandles.add(handle);
|
|
376
|
+
return handle;
|
|
377
|
+
}
|
|
378
|
+
/** Clear a {@link delayRender} handle; resolves `renderFrame()` once all clear. */
|
|
379
|
+
continueRender(handle) {
|
|
380
|
+
if (!this._renderHandles.delete(handle))
|
|
381
|
+
return;
|
|
382
|
+
if (this._renderHandles.size === 0) {
|
|
383
|
+
const waiters = this._renderWaiters;
|
|
384
|
+
this._renderWaiters = [];
|
|
385
|
+
for (const resolve of waiters)
|
|
386
|
+
resolve();
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Apply a frame and wait until all {@link delayRender} handles registered
|
|
391
|
+
* during that application clear. This is the offline / server render
|
|
392
|
+
* entrypoint — e.g. `for (f) { await comp.renderFrame(f); capture(); }`.
|
|
393
|
+
*/
|
|
394
|
+
async renderFrame(target) {
|
|
395
|
+
const clamped = Math.max(0, Math.min(this._durationInFrames.get() - 1, Math.floor(target)));
|
|
396
|
+
this._frame.set(clamped);
|
|
397
|
+
// force: offline render must apply every frame, even a re-rendered duplicate.
|
|
398
|
+
this._applyFrame(clamped, true, true);
|
|
399
|
+
if (this._renderHandles.size === 0)
|
|
400
|
+
return;
|
|
401
|
+
await new Promise((resolve) => {
|
|
402
|
+
this._renderWaiters.push(resolve);
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Composite every visible sequence layer into a single canvas and return it.
|
|
407
|
+
* Works headlessly (no DOM container needed); under the server skia backend
|
|
408
|
+
* the result is a skia `Canvas`, on which a renderer can call
|
|
409
|
+
* `.toBufferSync("raw")` for RGBA pixels.
|
|
410
|
+
*
|
|
411
|
+
* Unlike `Stage.toCanvas()`, this **reuses one scratch canvas** across calls.
|
|
412
|
+
* Allocating a fresh skia `Canvas` per frame leaks native memory (invisible to
|
|
413
|
+
* V8's GC), which balloons RSS and collapses throughput over a long render.
|
|
414
|
+
*/
|
|
415
|
+
captureCanvas() {
|
|
416
|
+
const w = this.width();
|
|
417
|
+
const h = this.height();
|
|
418
|
+
let scratch = this._captureCanvas;
|
|
419
|
+
if (!scratch) {
|
|
420
|
+
scratch = Konva.Util.createCanvasElement();
|
|
421
|
+
this._captureCanvas = scratch;
|
|
422
|
+
}
|
|
423
|
+
if (scratch.width !== w || scratch.height !== h) {
|
|
424
|
+
scratch.width = w;
|
|
425
|
+
scratch.height = h;
|
|
426
|
+
}
|
|
427
|
+
const ctx = scratch.getContext("2d");
|
|
428
|
+
if (!ctx)
|
|
429
|
+
return scratch;
|
|
430
|
+
ctx.clearRect(0, 0, w, h);
|
|
431
|
+
for (const child of this.getChildren()) {
|
|
432
|
+
if (child instanceof Konva.Layer && child.visible()) {
|
|
433
|
+
// Force a synchronous scene draw so the layer's own canvas is current
|
|
434
|
+
// (a `Sequence` may have only scheduled an async `batchDraw`).
|
|
435
|
+
child.drawScene();
|
|
436
|
+
ctx.drawImage(child.getNativeCanvasElement(), 0, 0, w, h);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return scratch;
|
|
440
|
+
}
|
|
441
|
+
/** @internal — {@link RenderingAudioDriver} records one sample per audio per frame. */
|
|
442
|
+
_collectAudioAsset(asset) {
|
|
443
|
+
this._audioAssets.push(asset);
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Audio samples collected during offline rendering — one per {@link Audio}
|
|
447
|
+
* per rendered frame. Feed these to an external mux pass (e.g. ffmpeg) to
|
|
448
|
+
* assemble the audio track. Empty during preview.
|
|
449
|
+
*/
|
|
450
|
+
getAudioAssets() {
|
|
451
|
+
return [...this._audioAssets];
|
|
452
|
+
}
|
|
453
|
+
/** Reset the collected audio samples — call before re-rendering a range. */
|
|
454
|
+
clearAudioAssets() {
|
|
455
|
+
this._audioAssets = [];
|
|
456
|
+
}
|
|
457
|
+
_event() {
|
|
458
|
+
return {
|
|
459
|
+
frame: this._frame.get(),
|
|
460
|
+
durationInFrames: this._durationInFrames.get(),
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
_applyFrame(frame, emit, force = false) {
|
|
464
|
+
// While buffering, draw nothing — the stage stays transparent until every
|
|
465
|
+
// registered asset (fonts, …) has loaded. Sequences are left hidden so no
|
|
466
|
+
// frame is painted over not-yet-loaded fonts. Offline rendering never
|
|
467
|
+
// buffers (fonts gate via delayRender), so this only affects preview.
|
|
468
|
+
if (this._buffer.get() === "buffering")
|
|
469
|
+
return;
|
|
470
|
+
for (const child of this.getChildren()) {
|
|
471
|
+
if (child instanceof Sequence)
|
|
472
|
+
child._apply(frame, force);
|
|
473
|
+
}
|
|
474
|
+
if (emit)
|
|
475
|
+
this._emitter.emit("time", this._event());
|
|
476
|
+
}
|
|
477
|
+
/** Hide every sequence (transparent stage) — used while buffering assets. */
|
|
478
|
+
_hideAllSequences() {
|
|
479
|
+
for (const child of this.getChildren()) {
|
|
480
|
+
if (child instanceof Sequence)
|
|
481
|
+
child._kmHide();
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
_scheduleTick() {
|
|
485
|
+
if (!raf)
|
|
486
|
+
return;
|
|
487
|
+
this._rafId = raf(this._tick);
|
|
488
|
+
}
|
|
489
|
+
_cancelTick() {
|
|
490
|
+
if (this._rafId !== null && caf) {
|
|
491
|
+
caf(this._rafId);
|
|
492
|
+
this._rafId = null;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
_tick = (now) => {
|
|
496
|
+
if (!this._isPlaying.get())
|
|
497
|
+
return;
|
|
498
|
+
const rate = this._playbackRate.get();
|
|
499
|
+
const elapsedMs = now - this._startWallMs;
|
|
500
|
+
// round (not floor) so small negative advances still register frame-by-frame.
|
|
501
|
+
const advance = Math.round((elapsedMs / 1000) * this.fps * rate);
|
|
502
|
+
const lastFrame = this._durationInFrames.get() - 1;
|
|
503
|
+
const target = Math.max(0, Math.min(lastFrame, this._startFrame + advance));
|
|
504
|
+
if (target !== this._frame.get()) {
|
|
505
|
+
this._frame.set(target);
|
|
506
|
+
this._applyFrame(target, true);
|
|
507
|
+
}
|
|
508
|
+
const atEnd = rate > 0 && target >= lastFrame;
|
|
509
|
+
const atStart = rate < 0 && target <= 0;
|
|
510
|
+
if (atEnd || atStart) {
|
|
511
|
+
if (this._loop.get()) {
|
|
512
|
+
const wrap = atEnd ? 0 : lastFrame;
|
|
513
|
+
this._startFrame = wrap;
|
|
514
|
+
this._startWallMs = now;
|
|
515
|
+
this._frame.set(wrap);
|
|
516
|
+
this._applyFrame(wrap, true);
|
|
517
|
+
this._scheduleTick();
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
this._cancelTick();
|
|
521
|
+
this._isPlaying.set(false);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
this._scheduleTick();
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
//# sourceMappingURL=composition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition.js","sourceRoot":"","sources":["../../src/engine/composition.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type Emitter<Events extends Record<string, unknown>> = {
|
|
2
|
+
on<K extends keyof Events>(event: K, listener: (payload: Events[K]) => void): () => void;
|
|
3
|
+
off<K extends keyof Events>(event: K, listener: (payload: Events[K]) => void): void;
|
|
4
|
+
emit<K extends keyof Events>(event: K, payload: Events[K]): void;
|
|
5
|
+
};
|
|
6
|
+
export declare function createEmitter<Events extends Record<string, unknown>>(): Emitter<Events>;
|
|
7
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/engine/emitter.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAC5D,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACzF,GAAG,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACpF,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAClE,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CA2BvF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function createEmitter() {
|
|
2
|
+
const listeners = new Map();
|
|
3
|
+
const getBucket = (event) => {
|
|
4
|
+
let bucket = listeners.get(event);
|
|
5
|
+
if (!bucket) {
|
|
6
|
+
bucket = new Set();
|
|
7
|
+
listeners.set(event, bucket);
|
|
8
|
+
}
|
|
9
|
+
return bucket;
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
on(event, listener) {
|
|
13
|
+
const bucket = getBucket(event);
|
|
14
|
+
bucket.add(listener);
|
|
15
|
+
return () => bucket.delete(listener);
|
|
16
|
+
},
|
|
17
|
+
off(event, listener) {
|
|
18
|
+
listeners.get(event)?.delete(listener);
|
|
19
|
+
},
|
|
20
|
+
emit(event, payload) {
|
|
21
|
+
const bucket = listeners.get(event);
|
|
22
|
+
if (!bucket)
|
|
23
|
+
return;
|
|
24
|
+
for (const fn of bucket)
|
|
25
|
+
fn(payload);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/engine/emitter.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,aAAa;IAC3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAC;IAE3E,MAAM,SAAS,GAAG,CAAyB,KAAQ,EAAE,EAAE;QACrD,IAAI,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;YACnB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO;QACL,EAAE,CAAC,KAAK,EAAE,QAAQ;YAChB,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,CAAC,GAAG,CAAC,QAAsC,CAAC,CAAC;YACnD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,QAAsC,CAAC,CAAC;QACrE,CAAC;QACD,GAAG,CAAC,KAAK,EAAE,QAAQ;YACjB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,QAAsC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,OAAO;YACjB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,KAAK,MAAM,EAAE,IAAI,MAAM;gBAAE,EAAE,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type Konva from "konva";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime mode the engine is operating in — mirrors Remotion's
|
|
4
|
+
* `getRemotionEnvironment()`. `Video` (and any environment-aware node) branches
|
|
5
|
+
* its behavior on this: realtime playback in preview, deterministic frame-by-frame
|
|
6
|
+
* seeking when rendering.
|
|
7
|
+
*/
|
|
8
|
+
export type Environment = {
|
|
9
|
+
/** Server / offline frame-by-frame rendering (e.g. Bun + Skia Canvas). */
|
|
10
|
+
isRendering: boolean;
|
|
11
|
+
/** Browser realtime playback / scrubbing. */
|
|
12
|
+
isPreview: boolean;
|
|
13
|
+
/** Reserved to mirror Remotion; always false for now. */
|
|
14
|
+
isClientSideRendering: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type EnvironmentMode = "preview" | "rendering";
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the environment. An explicit `override` (from `CompositionOptions.mode`)
|
|
19
|
+
* always wins; otherwise we detect from a global flag — Remotion reads
|
|
20
|
+
* `window.remotion_*`, we read `globalThis.__KONVA_MOTION_RENDERING__`, which a
|
|
21
|
+
* server renderer sets before constructing the composition.
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectEnvironment(override?: EnvironmentMode): Environment;
|
|
24
|
+
/**
|
|
25
|
+
* The environment of the Composition attached to `stage`, mirroring Remotion's
|
|
26
|
+
* `getRemotionEnvironment()`. Falls back to ambient detection if no Composition
|
|
27
|
+
* is attached.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getEnvironment(stage: Konva.Stage): Environment;
|
|
30
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/engine/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,0EAA0E;IAC1E,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,yDAAyD;IACzD,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,WAAW,CAAC;AAMtD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,WAAW,CAUzE;AAKD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,WAAW,CAG9D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const RENDERING_FLAG = "__KONVA_MOTION_RENDERING__";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the environment. An explicit `override` (from `CompositionOptions.mode`)
|
|
4
|
+
* always wins; otherwise we detect from a global flag — Remotion reads
|
|
5
|
+
* `window.remotion_*`, we read `globalThis.__KONVA_MOTION_RENDERING__`, which a
|
|
6
|
+
* server renderer sets before constructing the composition.
|
|
7
|
+
*/
|
|
8
|
+
export function detectEnvironment(override) {
|
|
9
|
+
const isRendering = override !== undefined
|
|
10
|
+
? override === "rendering"
|
|
11
|
+
: globalThis[RENDERING_FLAG] === true;
|
|
12
|
+
return {
|
|
13
|
+
isRendering,
|
|
14
|
+
isPreview: !isRendering,
|
|
15
|
+
isClientSideRendering: false,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The environment of the Composition attached to `stage`, mirroring Remotion's
|
|
20
|
+
* `getRemotionEnvironment()`. Falls back to ambient detection if no Composition
|
|
21
|
+
* is attached.
|
|
22
|
+
*/
|
|
23
|
+
export function getEnvironment(stage) {
|
|
24
|
+
const comp = stage.__SmooveComposition;
|
|
25
|
+
return comp?.environment ?? detectEnvironment();
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/engine/environment.ts"],"names":[],"mappings":"AAmBA,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAIpD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAA0B;IAC1D,MAAM,WAAW,GACf,QAAQ,KAAK,SAAS;QACpB,CAAC,CAAC,QAAQ,KAAK,WAAW;QAC1B,CAAC,CAAE,UAA8B,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC/D,OAAO;QACL,WAAW;QACX,SAAS,EAAE,CAAC,WAAW;QACvB,qBAAqB,EAAE,KAAK;KAC7B,CAAC;AACJ,CAAC;AAKD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,MAAM,IAAI,GAAI,KAA4D,CAAC,mBAAmB,CAAC;IAC/F,OAAO,IAAI,EAAE,WAAW,IAAI,iBAAiB,EAAE,CAAC;AAClD,CAAC"}
|