@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,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sequential offset engine shared by `Series` (auto-offsets) and
|
|
3
|
+
* `TransitionSeries` (offsets with overlap). Pure and deterministic: the same
|
|
4
|
+
* scene list + start frame always yields the same placements, so it is safe for
|
|
5
|
+
* offline / server rendering.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/** A scene to place: its length, plus an optional delta from the previous end. */
|
|
10
|
+
export type OffsetScene = {
|
|
11
|
+
durationInFrames: number;
|
|
12
|
+
/**
|
|
13
|
+
* Frames added to the previous scene's end before this scene starts. `0`
|
|
14
|
+
* (default) butts scenes back-to-back; positive leaves a gap; negative
|
|
15
|
+
* overlaps (e.g. a transition overlapping the outgoing scene).
|
|
16
|
+
*/
|
|
17
|
+
offset?: number;
|
|
18
|
+
};
|
|
19
|
+
/** A scene after placement — where it starts and how long it runs. */
|
|
20
|
+
export type PlacedScene = {
|
|
21
|
+
from: number;
|
|
22
|
+
durationInFrames: number;
|
|
23
|
+
};
|
|
24
|
+
export type ComputeOffsetsResult = {
|
|
25
|
+
placed: PlacedScene[];
|
|
26
|
+
/** `max(from + durationInFrames) − seriesFrom` — the total span of the series. */
|
|
27
|
+
durationInFrames: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Chain `scenes` from `seriesFrom`, computing each scene's `from` as
|
|
31
|
+
* `previousEnd + offset`. The first scene starts at `seriesFrom + offset`.
|
|
32
|
+
*
|
|
33
|
+
* A computed `from` may never fall below `seriesFrom` or below 0 — a negative
|
|
34
|
+
* `offset` that would underflow throws.
|
|
35
|
+
*
|
|
36
|
+
* @internal Engine util reused by `Series` and `@smoove/transitions`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function computeOffsets(scenes: OffsetScene[], seriesFrom?: number): ComputeOffsetsResult;
|
|
39
|
+
//# sourceMappingURL=offsets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offsets.d.ts","sourceRoot":"","sources":["../../src/engine/offsets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,kFAAkF;IAClF,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,UAAU,SAAI,GAAG,oBAAoB,CAwC1F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sequential offset engine shared by `Series` (auto-offsets) and
|
|
3
|
+
* `TransitionSeries` (offsets with overlap). Pure and deterministic: the same
|
|
4
|
+
* scene list + start frame always yields the same placements, so it is safe for
|
|
5
|
+
* offline / server rendering.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Chain `scenes` from `seriesFrom`, computing each scene's `from` as
|
|
11
|
+
* `previousEnd + offset`. The first scene starts at `seriesFrom + offset`.
|
|
12
|
+
*
|
|
13
|
+
* A computed `from` may never fall below `seriesFrom` or below 0 — a negative
|
|
14
|
+
* `offset` that would underflow throws.
|
|
15
|
+
*
|
|
16
|
+
* @internal Engine util reused by `Series` and `@smoove/transitions`.
|
|
17
|
+
*/
|
|
18
|
+
export function computeOffsets(scenes, seriesFrom = 0) {
|
|
19
|
+
if (!Number.isInteger(seriesFrom) || seriesFrom < 0) {
|
|
20
|
+
throw new Error("Series: from must be a non-negative integer");
|
|
21
|
+
}
|
|
22
|
+
if (scenes.length === 0) {
|
|
23
|
+
throw new Error("Series: add at least one scene before reading sequences");
|
|
24
|
+
}
|
|
25
|
+
const placed = [];
|
|
26
|
+
let previousEnd = seriesFrom;
|
|
27
|
+
let maxEnd = seriesFrom;
|
|
28
|
+
for (let i = 0; i < scenes.length; i++) {
|
|
29
|
+
const scene = scenes[i];
|
|
30
|
+
if (scene === undefined)
|
|
31
|
+
continue;
|
|
32
|
+
const { durationInFrames } = scene;
|
|
33
|
+
const offset = scene.offset ?? 0;
|
|
34
|
+
if (!Number.isInteger(durationInFrames) || durationInFrames <= 0) {
|
|
35
|
+
throw new Error(`Series: scene ${i} durationInFrames must be a positive integer (got ${durationInFrames})`);
|
|
36
|
+
}
|
|
37
|
+
if (!Number.isInteger(offset)) {
|
|
38
|
+
throw new Error(`Series: scene ${i} offset must be an integer (got ${offset})`);
|
|
39
|
+
}
|
|
40
|
+
const from = previousEnd + offset;
|
|
41
|
+
if (from < seriesFrom) {
|
|
42
|
+
throw new Error(`Series: scene ${i} offset ${offset} pushes from (${from}) before the series start (${seriesFrom})`);
|
|
43
|
+
}
|
|
44
|
+
if (from < 0) {
|
|
45
|
+
throw new Error(`Series: scene ${i} offset ${offset} pushes from (${from}) below 0`);
|
|
46
|
+
}
|
|
47
|
+
placed.push({ from, durationInFrames });
|
|
48
|
+
previousEnd = from + durationInFrames;
|
|
49
|
+
if (previousEnd > maxEnd)
|
|
50
|
+
maxEnd = previousEnd;
|
|
51
|
+
}
|
|
52
|
+
return { placed, durationInFrames: maxEnd - seriesFrom };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=offsets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offsets.js","sourceRoot":"","sources":["../../src/engine/offsets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAsBH;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,MAAqB,EAAE,UAAU,GAAG,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,WAAW,GAAG,UAAU,CAAC;IAC7B,IAAI,MAAM,GAAG,UAAU,CAAC;IAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,MAAM,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,IAAI,CAAC,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CACb,iBAAiB,CAAC,qDAAqD,gBAAgB,GAAG,CAC3F,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,mCAAmC,MAAM,GAAG,CAAC,CAAC;QAClF,CAAC;QACD,MAAM,IAAI,GAAG,WAAW,GAAG,MAAM,CAAC;QAClC,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,iBAAiB,CAAC,WAAW,MAAM,iBAAiB,IAAI,8BAA8B,UAAU,GAAG,CACpG,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,WAAW,MAAM,iBAAiB,IAAI,WAAW,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACxC,WAAW,GAAG,IAAI,GAAG,gBAAgB,CAAC;QACtC,IAAI,WAAW,GAAG,MAAM;YAAE,MAAM,GAAG,WAAW,CAAC;IACjD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,UAAU,EAAE,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Globally-overridable factories for the media sources and image loader that
|
|
3
|
+
* nodes build at construction time. The browser is the default everywhere; a
|
|
4
|
+
* server renderer swaps in Node-safe implementations **before** any composition
|
|
5
|
+
* is constructed (e.g. `@smoove/renderer`'s `setupServerRendering()`),
|
|
6
|
+
* since the browser defaults ({@link MediabunnyAudioSource}/
|
|
7
|
+
* {@link MediabunnyVideoSource}) rely on `document`/WebCodecs and would throw in Node.
|
|
8
|
+
*/
|
|
9
|
+
import type { AudioSourceFactory } from "../media/audio/audio-source.js";
|
|
10
|
+
import type { VideoSourceFactory } from "../media/video/video-source.js";
|
|
11
|
+
/** A drawable, loaded image with intrinsic dimensions — what {@link ImageLoader} resolves. */
|
|
12
|
+
export type LoadedImage = CanvasImageSource & {
|
|
13
|
+
readonly naturalWidth: number;
|
|
14
|
+
readonly naturalHeight: number;
|
|
15
|
+
};
|
|
16
|
+
/** Loads an image source string into a drawable. Defaults to the DOM `<img>` loader. */
|
|
17
|
+
export type ImageLoader = (src: string) => Promise<LoadedImage>;
|
|
18
|
+
/**
|
|
19
|
+
* A single, resolved font face — what {@link FontLoader} receives. `weight` and
|
|
20
|
+
* `style` are normalized strings (e.g. `"400"`, `"italic"`); `src` is a font
|
|
21
|
+
* file URL (browser) or path/URL (server). Mirrors `Font`'s internal face shape
|
|
22
|
+
* without importing it (which would cycle: `font.ts` imports this module).
|
|
23
|
+
*/
|
|
24
|
+
export type FontFaceDescriptor = {
|
|
25
|
+
readonly weight: string;
|
|
26
|
+
readonly style: string;
|
|
27
|
+
readonly src: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Loads one font face into the active text backend. Defaults to the browser
|
|
31
|
+
* `FontFace` API; a server renderer swaps in a skia-canvas implementation via
|
|
32
|
+
* {@link setDefaultFontLoader}. Always call faces through {@link loadFontFace},
|
|
33
|
+
* not this directly — that adds dedup so each face loads at most once.
|
|
34
|
+
*/
|
|
35
|
+
export type FontLoader = (family: string, face: FontFaceDescriptor) => Promise<void>;
|
|
36
|
+
export declare function setDefaultVideoSourceFactory(factory: VideoSourceFactory): void;
|
|
37
|
+
export declare function getDefaultVideoSourceFactory(): VideoSourceFactory;
|
|
38
|
+
export declare function setDefaultAudioSourceFactory(factory: AudioSourceFactory): void;
|
|
39
|
+
export declare function getDefaultAudioSourceFactory(): AudioSourceFactory;
|
|
40
|
+
export declare function setDefaultImageLoader(loader: ImageLoader): void;
|
|
41
|
+
export declare function getDefaultImageLoader(): ImageLoader;
|
|
42
|
+
export declare function setDefaultFontLoader(loader: FontLoader): void;
|
|
43
|
+
export declare function getDefaultFontLoader(): FontLoader;
|
|
44
|
+
/**
|
|
45
|
+
* Load a single font face through the active {@link FontLoader}, deduped by
|
|
46
|
+
* `family|weight|style|src` so the same face is fetched/registered at most once
|
|
47
|
+
* across every `Font`, `Text`, and re-render. Returns the shared promise.
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadFontFace(family: string, face: FontFaceDescriptor): Promise<void>;
|
|
50
|
+
//# sourceMappingURL=runtime-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-defaults.d.ts","sourceRoot":"","sources":["../../src/engine/runtime-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEtF,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGtF,8FAA8F;AAC9F,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,wFAAwF;AACxF,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAYhE;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAwBrF,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAE9E;AACD,wBAAgB,4BAA4B,IAAI,kBAAkB,CAEjE;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAE9E;AACD,wBAAgB,4BAA4B,IAAI,kBAAkB,CAEjE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAE/D;AACD,wBAAgB,qBAAqB,IAAI,WAAW,CAEnD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAE7D;AACD,wBAAgB,oBAAoB,IAAI,UAAU,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Globally-overridable factories for the media sources and image loader that
|
|
3
|
+
* nodes build at construction time. The browser is the default everywhere; a
|
|
4
|
+
* server renderer swaps in Node-safe implementations **before** any composition
|
|
5
|
+
* is constructed (e.g. `@smoove/renderer`'s `setupServerRendering()`),
|
|
6
|
+
* since the browser defaults ({@link MediabunnyAudioSource}/
|
|
7
|
+
* {@link MediabunnyVideoSource}) rely on `document`/WebCodecs and would throw in Node.
|
|
8
|
+
*/
|
|
9
|
+
import { MediabunnyAudioSource } from "../media/audio/audio-source-mediabunny.js";
|
|
10
|
+
import { MediabunnyVideoSource } from "../media/video/video-source-mediabunny.js";
|
|
11
|
+
function domLoadImage(src) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const img = document.createElement("img");
|
|
14
|
+
img.crossOrigin = "anonymous";
|
|
15
|
+
img.onload = () => resolve(img);
|
|
16
|
+
img.onerror = reject;
|
|
17
|
+
img.src = src;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function domLoadFont(family, face) {
|
|
21
|
+
// The FontFace API force-fetches and parses the binary — canvas text does NOT
|
|
22
|
+
// trigger CSS @font-face lazy loading, so this is the reliable path for Konva.
|
|
23
|
+
// Remote URLs are HTTP-cached by the browser; remote hosts must send CORS
|
|
24
|
+
// headers or `.load()` rejects.
|
|
25
|
+
const ff = new FontFace(family, `url(${face.src})`, {
|
|
26
|
+
weight: face.weight,
|
|
27
|
+
style: face.style,
|
|
28
|
+
});
|
|
29
|
+
return ff.load().then((loaded) => {
|
|
30
|
+
document.fonts.add(loaded);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
let videoFactory = () => new MediabunnyVideoSource();
|
|
34
|
+
let audioFactory = () => new MediabunnyAudioSource();
|
|
35
|
+
let imageLoader = domLoadImage;
|
|
36
|
+
let fontLoader = domLoadFont;
|
|
37
|
+
/** Deduped face loads, keyed by `family|weight|style|src` — see {@link loadFontFace}. */
|
|
38
|
+
const fontCache = new Map();
|
|
39
|
+
export function setDefaultVideoSourceFactory(factory) {
|
|
40
|
+
videoFactory = factory;
|
|
41
|
+
}
|
|
42
|
+
export function getDefaultVideoSourceFactory() {
|
|
43
|
+
return videoFactory;
|
|
44
|
+
}
|
|
45
|
+
export function setDefaultAudioSourceFactory(factory) {
|
|
46
|
+
audioFactory = factory;
|
|
47
|
+
}
|
|
48
|
+
export function getDefaultAudioSourceFactory() {
|
|
49
|
+
return audioFactory;
|
|
50
|
+
}
|
|
51
|
+
export function setDefaultImageLoader(loader) {
|
|
52
|
+
imageLoader = loader;
|
|
53
|
+
}
|
|
54
|
+
export function getDefaultImageLoader() {
|
|
55
|
+
return imageLoader;
|
|
56
|
+
}
|
|
57
|
+
export function setDefaultFontLoader(loader) {
|
|
58
|
+
fontLoader = loader;
|
|
59
|
+
}
|
|
60
|
+
export function getDefaultFontLoader() {
|
|
61
|
+
return fontLoader;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Load a single font face through the active {@link FontLoader}, deduped by
|
|
65
|
+
* `family|weight|style|src` so the same face is fetched/registered at most once
|
|
66
|
+
* across every `Font`, `Text`, and re-render. Returns the shared promise.
|
|
67
|
+
*/
|
|
68
|
+
export function loadFontFace(family, face) {
|
|
69
|
+
const key = `${family}|${face.weight}|${face.style}|${face.src}`;
|
|
70
|
+
let p = fontCache.get(key);
|
|
71
|
+
if (!p) {
|
|
72
|
+
p = fontLoader(family, face);
|
|
73
|
+
fontCache.set(key, p);
|
|
74
|
+
}
|
|
75
|
+
return p;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=runtime-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-defaults.js","sourceRoot":"","sources":["../../src/engine/runtime-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAElF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAWlF,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1C,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;QAC9B,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;QACrB,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAsBD,SAAS,WAAW,CAAC,MAAc,EAAE,IAAwB;IAC3D,8EAA8E;IAC9E,+EAA+E;IAC/E,0EAA0E;IAC1E,gCAAgC;IAChC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,GAAG,GAAG,EAAE;QAClD,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAC9B,QAA6D,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,YAAY,GAAuB,GAAgB,EAAE,CAAC,IAAI,qBAAqB,EAAE,CAAC;AACtF,IAAI,YAAY,GAAuB,GAAgB,EAAE,CAAC,IAAI,qBAAqB,EAAE,CAAC;AACtF,IAAI,WAAW,GAAgB,YAAY,CAAC;AAC5C,IAAI,UAAU,GAAe,WAAW,CAAC;AAEzC,yFAAyF;AACzF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;AAEnD,MAAM,UAAU,4BAA4B,CAAC,OAA2B;IACtE,YAAY,GAAG,OAAO,CAAC;AACzB,CAAC;AACD,MAAM,UAAU,4BAA4B;IAC1C,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,OAA2B;IACtE,YAAY,GAAG,OAAO,CAAC;AACzB,CAAC;AACD,MAAM,UAAU,4BAA4B;IAC1C,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAmB;IACvD,WAAW,GAAG,MAAM,CAAC;AACvB,CAAC;AACD,MAAM,UAAU,qBAAqB;IACnC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,UAAU,GAAG,MAAM,CAAC;AACtB,CAAC;AACD,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAwB;IACnE,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACjE,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7B,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import Konva from "konva";
|
|
2
|
+
export type SequenceOptions = Konva.LayerConfig & {
|
|
3
|
+
from: number;
|
|
4
|
+
durationInFrames: number;
|
|
5
|
+
};
|
|
6
|
+
export type Updater = (localFrame: number) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Anything that expands into a list of `Sequence`s — e.g. `Series` or
|
|
9
|
+
* `@smoove/transitions`' `TransitionSeries`. `Composition.add` accepts a
|
|
10
|
+
* provider directly and adds each sequence it yields, so callers can write
|
|
11
|
+
* `comp.add(series)` instead of looping over `series.sequences()`.
|
|
12
|
+
*/
|
|
13
|
+
export type SequenceProvider = {
|
|
14
|
+
sequences(): Sequence[];
|
|
15
|
+
};
|
|
16
|
+
export declare class Sequence extends Konva.Layer {
|
|
17
|
+
readonly from: number;
|
|
18
|
+
readonly durationInFrames: number;
|
|
19
|
+
private readonly _updaters;
|
|
20
|
+
private _active;
|
|
21
|
+
private _media;
|
|
22
|
+
private _lastLocal;
|
|
23
|
+
constructor(opts: SequenceOptions);
|
|
24
|
+
register(updater: Updater): () => void;
|
|
25
|
+
/**
|
|
26
|
+
* Internal — called by Composition on each frame change.
|
|
27
|
+
*
|
|
28
|
+
* `force` re-runs the frame even when the local playhead hasn't moved — needed
|
|
29
|
+
* when external state updaters read (props) changed at the same frame
|
|
30
|
+
* (`refresh()`), on the initial paint, and for offline rendering. During normal
|
|
31
|
+
* playback the local frame advances every tick, so the dedupe never trips; it
|
|
32
|
+
* only skips genuinely redundant re-applies (e.g. a `refresh()` that changed
|
|
33
|
+
* nothing, or a same-frame re-entry), avoiding a wasted updater + layout + draw.
|
|
34
|
+
*/
|
|
35
|
+
_apply(frame: number, force?: boolean): void;
|
|
36
|
+
/**
|
|
37
|
+
* Internal — force this sequence hidden and inactive, regardless of frame
|
|
38
|
+
* range. Used by `Composition` while it buffers assets so the stage stays
|
|
39
|
+
* transparent (no frame painted over not-yet-loaded fonts). The next
|
|
40
|
+
* {@link _apply} re-activates it normally.
|
|
41
|
+
*/
|
|
42
|
+
_kmHide(): void;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=sequence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../../src/engine/sequence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,GAAG;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,SAAS,IAAI,QAAQ,EAAE,CAAA;CAAE,CAAC;AAQ3D,qBAAa,QAAS,SAAQ,KAAK,CAAC,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAmB;IAIjC,OAAO,CAAC,UAAU,CAAM;gBAEZ,IAAI,EAAE,eAAe;IAajC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,IAAI;IAOtC;;;;;;;;;OASG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG,IAAI;IAsC1C;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CAOhB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import Konva from "konva";
|
|
2
|
+
import { isKMLayoutRoot } from "../layout/contract.js";
|
|
3
|
+
import { MEDIA_MARK, TICK_MARK } from "../media/media-marker.js";
|
|
4
|
+
export class Sequence extends Konva.Layer {
|
|
5
|
+
from;
|
|
6
|
+
durationInFrames;
|
|
7
|
+
_updaters = new Set();
|
|
8
|
+
_active = false;
|
|
9
|
+
_media = [];
|
|
10
|
+
// Last local frame applied while active — used to skip redundant re-applies
|
|
11
|
+
// (updaters + layout + draw) when nothing about the playhead changed. `-1` is
|
|
12
|
+
// a sentinel that never equals a real local frame, so the first apply always runs.
|
|
13
|
+
_lastLocal = -1;
|
|
14
|
+
constructor(opts) {
|
|
15
|
+
if (!Number.isInteger(opts.from) || opts.from < 0) {
|
|
16
|
+
throw new Error("Sequence: from must be a non-negative integer");
|
|
17
|
+
}
|
|
18
|
+
if (!Number.isInteger(opts.durationInFrames) || opts.durationInFrames <= 0) {
|
|
19
|
+
throw new Error("Sequence: durationInFrames must be a positive integer");
|
|
20
|
+
}
|
|
21
|
+
const { from, durationInFrames, ...layerOpts } = opts;
|
|
22
|
+
super({ ...layerOpts, visible: false });
|
|
23
|
+
this.from = from;
|
|
24
|
+
this.durationInFrames = durationInFrames;
|
|
25
|
+
}
|
|
26
|
+
register(updater) {
|
|
27
|
+
this._updaters.add(updater);
|
|
28
|
+
return () => {
|
|
29
|
+
this._updaters.delete(updater);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Internal — called by Composition on each frame change.
|
|
34
|
+
*
|
|
35
|
+
* `force` re-runs the frame even when the local playhead hasn't moved — needed
|
|
36
|
+
* when external state updaters read (props) changed at the same frame
|
|
37
|
+
* (`refresh()`), on the initial paint, and for offline rendering. During normal
|
|
38
|
+
* playback the local frame advances every tick, so the dedupe never trips; it
|
|
39
|
+
* only skips genuinely redundant re-applies (e.g. a `refresh()` that changed
|
|
40
|
+
* nothing, or a same-frame re-entry), avoiding a wasted updater + layout + draw.
|
|
41
|
+
*/
|
|
42
|
+
_apply(frame, force = false) {
|
|
43
|
+
const inRange = frame >= this.from && frame < this.from + this.durationInFrames;
|
|
44
|
+
if (inRange) {
|
|
45
|
+
const becameActive = !this._active;
|
|
46
|
+
if (becameActive) {
|
|
47
|
+
this.visible(true);
|
|
48
|
+
this._active = true;
|
|
49
|
+
// Cache tickable nodes once per activation — avoids a subtree walk every
|
|
50
|
+
// frame. Includes media (video/audio) plus non-media tickers (Text typewriter).
|
|
51
|
+
this._media = this.find((n) => n.getAttr(MEDIA_MARK) === true || n.getAttr(TICK_MARK) === true);
|
|
52
|
+
}
|
|
53
|
+
const local = frame - this.from;
|
|
54
|
+
// Skip redundant work: same playhead, already active, and not forced.
|
|
55
|
+
if (!becameActive && !force && local === this._lastLocal)
|
|
56
|
+
return;
|
|
57
|
+
this._lastLocal = local;
|
|
58
|
+
for (const u of this._updaters)
|
|
59
|
+
u(local);
|
|
60
|
+
// Tick BEFORE layout: a ticked node may change its measured size (e.g. a
|
|
61
|
+
// Text typewriter revealing another line), and the flex pass must see the
|
|
62
|
+
// up-to-date size this frame rather than lagging one behind.
|
|
63
|
+
for (const v of this._media)
|
|
64
|
+
v._kmTick?.(local);
|
|
65
|
+
for (const c of this.getChildren()) {
|
|
66
|
+
if (isKMLayoutRoot(c))
|
|
67
|
+
c._kmComputeLayout();
|
|
68
|
+
}
|
|
69
|
+
// Draw synchronously the frame in which a sequence becomes visible — this
|
|
70
|
+
// ensures fresh pixels are on the canvas before the browser paints the
|
|
71
|
+
// newly-displayed layer (avoids a one-frame flash of stale content).
|
|
72
|
+
if (becameActive)
|
|
73
|
+
this.draw();
|
|
74
|
+
else
|
|
75
|
+
this.batchDraw();
|
|
76
|
+
}
|
|
77
|
+
else if (this._active) {
|
|
78
|
+
this.visible(false);
|
|
79
|
+
this._active = false;
|
|
80
|
+
this._lastLocal = -1;
|
|
81
|
+
for (const v of this._media)
|
|
82
|
+
v._kmDeactivate?.();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Internal — force this sequence hidden and inactive, regardless of frame
|
|
87
|
+
* range. Used by `Composition` while it buffers assets so the stage stays
|
|
88
|
+
* transparent (no frame painted over not-yet-loaded fonts). The next
|
|
89
|
+
* {@link _apply} re-activates it normally.
|
|
90
|
+
*/
|
|
91
|
+
_kmHide() {
|
|
92
|
+
if (!this._active && !this.visible())
|
|
93
|
+
return;
|
|
94
|
+
this.visible(false);
|
|
95
|
+
this._active = false;
|
|
96
|
+
this._lastLocal = -1;
|
|
97
|
+
for (const v of this._media)
|
|
98
|
+
v._kmDeactivate?.();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=sequence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequence.js","sourceRoot":"","sources":["../../src/engine/sequence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Sequence, type SequenceProvider } from "./sequence.js";
|
|
2
|
+
export type SeriesOptions = {
|
|
3
|
+
/** Frame the series starts at. Default `0`. */
|
|
4
|
+
from?: number;
|
|
5
|
+
};
|
|
6
|
+
export type SeriesSceneOptions = {
|
|
7
|
+
durationInFrames: number;
|
|
8
|
+
/**
|
|
9
|
+
* Frames added to the previous scene's end before this scene starts. Negative
|
|
10
|
+
* overlaps the previous scene; positive leaves a gap. Default `0` (back-to-back).
|
|
11
|
+
*/
|
|
12
|
+
offset?: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Sequential sequencer: collects ordered scenes and auto-computes each
|
|
16
|
+
* `Sequence`'s `from`, so callers never hand-compute offsets. Mirrors Remotion's
|
|
17
|
+
* `<Series>` / `<Series.Sequence>`.
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const series = new Series({ from: 0 });
|
|
21
|
+
* series
|
|
22
|
+
* .add({ durationInFrames: 60 }, (seq) => seq.add(rect))
|
|
23
|
+
* .add({ durationInFrames: 90, offset: -10 }, (seq) => seq.add(circle));
|
|
24
|
+
* composition.add(series); // adds each sequence the series yields
|
|
25
|
+
* series.durationInFrames; // total span accounting for offsets
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class Series implements SequenceProvider {
|
|
29
|
+
readonly from: number;
|
|
30
|
+
private readonly _scenes;
|
|
31
|
+
constructor(opts?: SeriesOptions);
|
|
32
|
+
/** Append a scene. The `build` callback populates the created `Sequence`. */
|
|
33
|
+
add(opts: SeriesSceneOptions, build: (seq: Sequence) => void): this;
|
|
34
|
+
private _place;
|
|
35
|
+
/** Build one `Sequence` per scene, with `from` resolved from the offsets. */
|
|
36
|
+
sequences(): Sequence[];
|
|
37
|
+
/** Total span of the series, `max(from + duration) − series.from`. */
|
|
38
|
+
get durationInFrames(): number;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=series.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../../src/engine/series.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEhE,MAAM,MAAM,aAAa,GAAG;IAC1B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAOF;;;;;;;;;;;;;GAaG;AACH,qBAAa,MAAO,YAAW,gBAAgB;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAE9B,IAAI,GAAE,aAAkB;IAQpC,6EAA6E;IAC7E,GAAG,CAAC,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAKnE,OAAO,CAAC,MAAM;IAQd,6EAA6E;IAC7E,SAAS,IAAI,QAAQ,EAAE;IAUvB,sEAAsE;IACtE,IAAI,gBAAgB,IAAI,MAAM,CAM7B;CACF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { computeOffsets } from "./offsets.js";
|
|
2
|
+
import { Sequence } from "./sequence.js";
|
|
3
|
+
/**
|
|
4
|
+
* Sequential sequencer: collects ordered scenes and auto-computes each
|
|
5
|
+
* `Sequence`'s `from`, so callers never hand-compute offsets. Mirrors Remotion's
|
|
6
|
+
* `<Series>` / `<Series.Sequence>`.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const series = new Series({ from: 0 });
|
|
10
|
+
* series
|
|
11
|
+
* .add({ durationInFrames: 60 }, (seq) => seq.add(rect))
|
|
12
|
+
* .add({ durationInFrames: 90, offset: -10 }, (seq) => seq.add(circle));
|
|
13
|
+
* composition.add(series); // adds each sequence the series yields
|
|
14
|
+
* series.durationInFrames; // total span accounting for offsets
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export class Series {
|
|
18
|
+
from;
|
|
19
|
+
_scenes = [];
|
|
20
|
+
constructor(opts = {}) {
|
|
21
|
+
const from = opts.from ?? 0;
|
|
22
|
+
if (!Number.isInteger(from) || from < 0) {
|
|
23
|
+
throw new Error("Series: from must be a non-negative integer");
|
|
24
|
+
}
|
|
25
|
+
this.from = from;
|
|
26
|
+
}
|
|
27
|
+
/** Append a scene. The `build` callback populates the created `Sequence`. */
|
|
28
|
+
add(opts, build) {
|
|
29
|
+
this._scenes.push({ opts, build });
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
_place() {
|
|
33
|
+
const scenes = this._scenes.map((s) => ({
|
|
34
|
+
durationInFrames: s.opts.durationInFrames,
|
|
35
|
+
offset: s.opts.offset,
|
|
36
|
+
}));
|
|
37
|
+
return computeOffsets(scenes, this.from).placed;
|
|
38
|
+
}
|
|
39
|
+
/** Build one `Sequence` per scene, with `from` resolved from the offsets. */
|
|
40
|
+
sequences() {
|
|
41
|
+
const placed = this._place();
|
|
42
|
+
return placed.map((p, i) => {
|
|
43
|
+
const def = this._scenes[i];
|
|
44
|
+
const seq = new Sequence({ from: p.from, durationInFrames: p.durationInFrames });
|
|
45
|
+
def?.build(seq);
|
|
46
|
+
return seq;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** Total span of the series, `max(from + duration) − series.from`. */
|
|
50
|
+
get durationInFrames() {
|
|
51
|
+
const scenes = this._scenes.map((s) => ({
|
|
52
|
+
durationInFrames: s.opts.durationInFrames,
|
|
53
|
+
offset: s.opts.offset,
|
|
54
|
+
}));
|
|
55
|
+
return computeOffsets(scenes, this.from).durationInFrames;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=series.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"series.js","sourceRoot":"","sources":["../../src/engine/series.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAsC,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAyB,MAAM,eAAe,CAAC;AAqBhE;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,MAAM;IACR,IAAI,CAAS;IACL,OAAO,GAAe,EAAE,CAAC;IAE1C,YAAY,OAAsB,EAAE;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,6EAA6E;IAC7E,GAAG,CAAC,IAAwB,EAAE,KAA8B;QAC1D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,MAAM;QACZ,MAAM,MAAM,GAAkB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrD,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB;YACzC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;SACtB,CAAC,CAAC,CAAC;QACJ,OAAO,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAClD,CAAC;IAED,6EAA6E;IAC7E,SAAS;QACP,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC;YACjF,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAChB,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,IAAI,gBAAgB;QAClB,MAAM,MAAM,GAAkB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrD,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB;YACzC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;SACtB,CAAC,CAAC,CAAC;QACJ,OAAO,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC;IAC5D,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ReadonlySignal<T> = {
|
|
2
|
+
get(): T;
|
|
3
|
+
subscribe(listener: (value: T) => void): () => void;
|
|
4
|
+
};
|
|
5
|
+
export type Signal<T> = ReadonlySignal<T> & {
|
|
6
|
+
set(value: T): void;
|
|
7
|
+
};
|
|
8
|
+
export declare function createSignal<T>(initial: T): Signal<T>;
|
|
9
|
+
export declare function derived<T>(sources: ReadonlySignal<unknown>[], compute: () => T): ReadonlySignal<T>;
|
|
10
|
+
//# sourceMappingURL=signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../src/engine/signal.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,GAAG,IAAI,CAAC,CAAC;IACT,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,GAAG;IAC1C,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAerD;AAED,wBAAgB,OAAO,CAAC,CAAC,EACvB,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,EAClC,OAAO,EAAE,MAAM,CAAC,GACf,cAAc,CAAC,CAAC,CAAC,CAiBnB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function createSignal(initial) {
|
|
2
|
+
let value = initial;
|
|
3
|
+
const listeners = new Set();
|
|
4
|
+
return {
|
|
5
|
+
get: () => value,
|
|
6
|
+
set(next) {
|
|
7
|
+
if (Object.is(next, value))
|
|
8
|
+
return;
|
|
9
|
+
value = next;
|
|
10
|
+
for (const fn of listeners)
|
|
11
|
+
fn(value);
|
|
12
|
+
},
|
|
13
|
+
subscribe(listener) {
|
|
14
|
+
listeners.add(listener);
|
|
15
|
+
return () => listeners.delete(listener);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function derived(sources, compute) {
|
|
20
|
+
return {
|
|
21
|
+
get: compute,
|
|
22
|
+
subscribe(listener) {
|
|
23
|
+
let last = compute();
|
|
24
|
+
const fire = () => {
|
|
25
|
+
const next = compute();
|
|
26
|
+
if (Object.is(next, last))
|
|
27
|
+
return;
|
|
28
|
+
last = next;
|
|
29
|
+
listener(next);
|
|
30
|
+
};
|
|
31
|
+
const unsubs = sources.map((s) => s.subscribe(fire));
|
|
32
|
+
return () => {
|
|
33
|
+
for (const u of unsubs)
|
|
34
|
+
u();
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../src/engine/signal.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,YAAY,CAAI,OAAU;IACxC,IAAI,KAAK,GAAG,OAAO,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsB,CAAC;IAChD,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;QAChB,GAAG,CAAC,IAAO;YACT,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;gBAAE,OAAO;YACnC,KAAK,GAAG,IAAI,CAAC;YACb,KAAK,MAAM,EAAE,IAAI,SAAS;gBAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;QACD,SAAS,CAAC,QAAQ;YAChB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,OAAkC,EAClC,OAAgB;IAEhB,OAAO;QACL,GAAG,EAAE,OAAO;QACZ,SAAS,CAAC,QAAQ;YAChB,IAAI,IAAI,GAAG,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,GAAG,EAAE;gBAChB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;gBACvB,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;oBAAE,OAAO;gBAClC,IAAI,GAAG,IAAI,CAAC;gBACZ,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC,CAAC;YACF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YACrD,OAAO,GAAG,EAAE;gBACV,KAAK,MAAM,CAAC,IAAI,MAAM;oBAAE,CAAC,EAAE,CAAC;YAC9B,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/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,CAI9D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/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,KAAiE;SAC5E,wBAAwB,CAAC;IAC5B,OAAO,IAAI,EAAE,WAAW,IAAI,iBAAiB,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Node as FlexilyNode } from "flexily/classic";
|
|
2
|
+
import type Konva from "konva";
|
|
3
|
+
import type { EdgeValue, FlexChildProps, FlexProps, SizeValue } from "./flex-types.js";
|
|
4
|
+
export type Edges = [number, number, number, number];
|
|
5
|
+
export declare function normalizeEdges(v: EdgeValue | undefined): Edges | null;
|
|
6
|
+
export declare function parseSize(v: SizeValue | undefined): {
|
|
7
|
+
kind: "px";
|
|
8
|
+
value: number;
|
|
9
|
+
} | {
|
|
10
|
+
kind: "pct";
|
|
11
|
+
value: number;
|
|
12
|
+
} | null;
|
|
13
|
+
export declare function applyEdges(node: FlexilyNode, edges: Edges | null, setter: "setPadding" | "setMargin" | "setBorder"): void;
|
|
14
|
+
export declare function applySize(node: FlexilyNode, w: SizeValue | undefined, h: SizeValue | undefined): void;
|
|
15
|
+
export declare function applyContainerProps(node: FlexilyNode, props: FlexProps): void;
|
|
16
|
+
export declare function applyChildProps(node: FlexilyNode, props: FlexChildProps): void;
|
|
17
|
+
export declare function setTextMeasure(node: FlexilyNode, text: Konva.Text, parentIsColumn: boolean): void;
|
|
18
|
+
/**
|
|
19
|
+
* Structural view of the `Text` wrapper — typed here (rather than imported)
|
|
20
|
+
* so this leaf module stays free of a cycle through `text.ts`.
|
|
21
|
+
*/
|
|
22
|
+
type TextWrapper = {
|
|
23
|
+
_measureForFlex: (avail: number) => {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export declare function setTextWrapperMeasure(node: FlexilyNode, wrapper: TextWrapper, parentIsColumn: boolean): void;
|
|
29
|
+
export declare function setImageMeasure(node: FlexilyNode, image: Konva.Image): void;
|
|
30
|
+
export { FlexilyNode };
|
|
31
|
+
//# sourceMappingURL=flex-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flex-engine.d.ts","sourceRoot":"","sources":["../src/flex-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAcL,IAAI,IAAI,WAAW,EAQpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAGV,SAAS,EACT,cAAc,EAEd,SAAS,EAET,SAAS,EACV,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAErD,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,IAAI,CAUrE;AAED,wBAAgB,SAAS,CACvB,CAAC,EAAE,SAAS,GAAG,SAAS,GACvB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMvE;AAmDD,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,WAAW,GAC/C,IAAI,CAON;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,WAAW,EACjB,CAAC,EAAE,SAAS,GAAG,SAAS,EACxB,CAAC,EAAE,SAAS,GAAG,SAAS,GACvB,IAAI,CAWN;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAM7E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAM9E;AAOD,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI,CAgCjG;AAED;;;GAGG;AACH,KAAK,WAAW,GAAG;IACjB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACvE,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,OAAO,GACtB,IAAI,CAeN;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAc3E;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|