@smoove/transitions 0.1.1
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 +55 -0
- package/dist/gl/compositor.d.ts +67 -0
- package/dist/gl/compositor.d.ts.map +1 -0
- package/dist/gl/compositor.js +147 -0
- package/dist/gl/compositor.js.map +1 -0
- package/dist/gl/gl-transition.d.ts +8 -0
- package/dist/gl/gl-transition.d.ts.map +1 -0
- package/dist/gl/gl-transition.js +9 -0
- package/dist/gl/gl-transition.js.map +1 -0
- package/dist/gl/shared.d.ts +10 -0
- package/dist/gl/shared.d.ts.map +1 -0
- package/dist/gl/shared.js +56 -0
- package/dist/gl/shared.js.map +1 -0
- package/dist/gl/transpile.d.ts +16 -0
- package/dist/gl/transpile.d.ts.map +1 -0
- package/dist/gl/transpile.js +29 -0
- package/dist/gl/transpile.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/presentations/book-flip.d.ts +8 -0
- package/dist/presentations/book-flip.d.ts.map +1 -0
- package/dist/presentations/book-flip.js +124 -0
- package/dist/presentations/book-flip.js.map +1 -0
- package/dist/presentations/clock-wipe.d.ts +12 -0
- package/dist/presentations/clock-wipe.d.ts.map +1 -0
- package/dist/presentations/clock-wipe.js +27 -0
- package/dist/presentations/clock-wipe.js.map +1 -0
- package/dist/presentations/cross-zoom.d.ts +7 -0
- package/dist/presentations/cross-zoom.d.ts.map +1 -0
- package/dist/presentations/cross-zoom.js +80 -0
- package/dist/presentations/cross-zoom.js.map +1 -0
- package/dist/presentations/crosswarp.d.ts +5 -0
- package/dist/presentations/crosswarp.d.ts.map +1 -0
- package/dist/presentations/crosswarp.js +32 -0
- package/dist/presentations/crosswarp.js.map +1 -0
- package/dist/presentations/dissolve.d.ts +11 -0
- package/dist/presentations/dissolve.d.ts.map +1 -0
- package/dist/presentations/dissolve.js +69 -0
- package/dist/presentations/dissolve.js.map +1 -0
- package/dist/presentations/dreamy-zoom.d.ts +8 -0
- package/dist/presentations/dreamy-zoom.d.ts.map +1 -0
- package/dist/presentations/dreamy-zoom.js +52 -0
- package/dist/presentations/dreamy-zoom.js.map +1 -0
- package/dist/presentations/fade.d.ts +9 -0
- package/dist/presentations/fade.d.ts.map +1 -0
- package/dist/presentations/fade.js +17 -0
- package/dist/presentations/fade.js.map +1 -0
- package/dist/presentations/film-burn.d.ts +7 -0
- package/dist/presentations/film-burn.d.ts.map +1 -0
- package/dist/presentations/film-burn.js +146 -0
- package/dist/presentations/film-burn.js.map +1 -0
- package/dist/presentations/flip.d.ts +13 -0
- package/dist/presentations/flip.d.ts.map +1 -0
- package/dist/presentations/flip.js +39 -0
- package/dist/presentations/flip.js.map +1 -0
- package/dist/presentations/index.d.ts +19 -0
- package/dist/presentations/index.d.ts.map +1 -0
- package/dist/presentations/index.js +21 -0
- package/dist/presentations/index.js.map +1 -0
- package/dist/presentations/iris.d.ts +12 -0
- package/dist/presentations/iris.d.ts.map +1 -0
- package/dist/presentations/iris.js +21 -0
- package/dist/presentations/iris.js.map +1 -0
- package/dist/presentations/linear-blur.d.ts +7 -0
- package/dist/presentations/linear-blur.d.ts.map +1 -0
- package/dist/presentations/linear-blur.js +47 -0
- package/dist/presentations/linear-blur.js.map +1 -0
- package/dist/presentations/none.d.ts +8 -0
- package/dist/presentations/none.d.ts.map +1 -0
- package/dist/presentations/none.js +12 -0
- package/dist/presentations/none.js.map +1 -0
- package/dist/presentations/ripple.d.ts +8 -0
- package/dist/presentations/ripple.d.ts.map +1 -0
- package/dist/presentations/ripple.js +39 -0
- package/dist/presentations/ripple.js.map +1 -0
- package/dist/presentations/slide.d.ts +11 -0
- package/dist/presentations/slide.d.ts.map +1 -0
- package/dist/presentations/slide.js +43 -0
- package/dist/presentations/slide.js.map +1 -0
- package/dist/presentations/swap.d.ts +9 -0
- package/dist/presentations/swap.d.ts.map +1 -0
- package/dist/presentations/swap.js +95 -0
- package/dist/presentations/swap.js.map +1 -0
- package/dist/presentations/wipe.d.ts +12 -0
- package/dist/presentations/wipe.d.ts.map +1 -0
- package/dist/presentations/wipe.js +31 -0
- package/dist/presentations/wipe.js.map +1 -0
- package/dist/presentations/zoom-blur.d.ts +7 -0
- package/dist/presentations/zoom-blur.d.ts.map +1 -0
- package/dist/presentations/zoom-blur.js +69 -0
- package/dist/presentations/zoom-blur.js.map +1 -0
- package/dist/presentations/zoom-in-out.d.ts +5 -0
- package/dist/presentations/zoom-in-out.d.ts.map +1 -0
- package/dist/presentations/zoom-in-out.js +33 -0
- package/dist/presentations/zoom-in-out.js.map +1 -0
- package/dist/timings/index.d.ts +4 -0
- package/dist/timings/index.d.ts.map +1 -0
- package/dist/timings/index.js +4 -0
- package/dist/timings/index.js.map +1 -0
- package/dist/timings/linear-timing.d.ts +12 -0
- package/dist/timings/linear-timing.d.ts.map +1 -0
- package/dist/timings/linear-timing.js +20 -0
- package/dist/timings/linear-timing.js.map +1 -0
- package/dist/timings/spring/index.d.ts +19 -0
- package/dist/timings/spring/index.d.ts.map +1 -0
- package/dist/timings/spring/index.js +30 -0
- package/dist/timings/spring/index.js.map +1 -0
- package/dist/timings/spring/measure-spring.d.ts +12 -0
- package/dist/timings/spring/measure-spring.d.ts.map +1 -0
- package/dist/timings/spring/measure-spring.js +37 -0
- package/dist/timings/spring/measure-spring.js.map +1 -0
- package/dist/timings/spring/spring-utils.d.ts +20 -0
- package/dist/timings/spring/spring-utils.d.ts.map +1 -0
- package/dist/timings/spring/spring-utils.js +65 -0
- package/dist/timings/spring/spring-utils.js.map +1 -0
- package/dist/timings/spring-timing.d.ts +16 -0
- package/dist/timings/spring-timing.d.ts.map +1 -0
- package/dist/timings/spring-timing.js +28 -0
- package/dist/timings/spring-timing.js.map +1 -0
- package/dist/transition-series.d.ts +52 -0
- package/dist/transition-series.d.ts.map +1 -0
- package/dist/transition-series.js +217 -0
- package/dist/transition-series.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { interpolate } from "@smoove/core";
|
|
2
|
+
/**
|
|
3
|
+
* A transition whose progress moves linearly (optionally eased) from 0 to 1
|
|
4
|
+
* over `durationInFrames`. Mirrors Remotion's `linearTiming`.
|
|
5
|
+
*/
|
|
6
|
+
export function linearTiming(options) {
|
|
7
|
+
const { durationInFrames, easing } = options;
|
|
8
|
+
if (!Number.isInteger(durationInFrames) || durationInFrames <= 0) {
|
|
9
|
+
throw new Error("linearTiming: durationInFrames must be a positive integer");
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
getDurationInFrames: () => durationInFrames,
|
|
13
|
+
getProgress: (frame) => interpolate(frame, [0, durationInFrames], [0, 1], {
|
|
14
|
+
easing,
|
|
15
|
+
extrapolateLeft: "clamp",
|
|
16
|
+
extrapolateRight: "clamp",
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=linear-timing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-timing.js","sourceRoot":"","sources":["../../src/timings/linear-timing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAS3C;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B;IACvD,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,IAAI,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO;QACL,mBAAmB,EAAE,GAAG,EAAE,CAAC,gBAAgB;QAC3C,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CACrB,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;YAChD,MAAM;YACN,eAAe,EAAE,OAAO;YACxB,gBAAgB,EAAE,OAAO;SAC1B,CAAC;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type SpringConfig } from "./spring-utils.js";
|
|
2
|
+
export { measureSpring } from "./measure-spring.js";
|
|
3
|
+
export { defaultSpringConfig, type SpringConfig } from "./spring-utils.js";
|
|
4
|
+
/**
|
|
5
|
+
* Sample a physics spring at `frame`. Returns a value animating `from → to`.
|
|
6
|
+
* Ported from Remotion's `spring()`. When `durationInFrames` or `reverse` is
|
|
7
|
+
* set, time is remapped against the spring's natural settle time.
|
|
8
|
+
*/
|
|
9
|
+
export declare function spring({ frame, fps, config, from, to, durationInFrames, durationRestThreshold, reverse, }: {
|
|
10
|
+
frame: number;
|
|
11
|
+
fps: number;
|
|
12
|
+
config?: Partial<SpringConfig>;
|
|
13
|
+
from?: number;
|
|
14
|
+
to?: number;
|
|
15
|
+
durationInFrames?: number;
|
|
16
|
+
durationRestThreshold?: number;
|
|
17
|
+
reverse?: boolean;
|
|
18
|
+
}): number;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/timings/spring/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,GAAG,EACH,MAAW,EACX,IAAQ,EACR,EAAM,EACN,gBAAgB,EAChB,qBAAqB,EACrB,OAAe,GAChB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAqBT"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { interpolate } from "@smoove/core";
|
|
2
|
+
import { measureSpring } from "./measure-spring.js";
|
|
3
|
+
import { springCalculation } from "./spring-utils.js";
|
|
4
|
+
export { measureSpring } from "./measure-spring.js";
|
|
5
|
+
export { defaultSpringConfig } from "./spring-utils.js";
|
|
6
|
+
/**
|
|
7
|
+
* Sample a physics spring at `frame`. Returns a value animating `from → to`.
|
|
8
|
+
* Ported from Remotion's `spring()`. When `durationInFrames` or `reverse` is
|
|
9
|
+
* set, time is remapped against the spring's natural settle time.
|
|
10
|
+
*/
|
|
11
|
+
export function spring({ frame, fps, config = {}, from = 0, to = 1, durationInFrames, durationRestThreshold, reverse = false, }) {
|
|
12
|
+
const needsNatural = reverse || durationInFrames !== undefined;
|
|
13
|
+
const naturalDuration = needsNatural
|
|
14
|
+
? measureSpring({ fps, config, threshold: durationRestThreshold })
|
|
15
|
+
: undefined;
|
|
16
|
+
let frameToUse = frame;
|
|
17
|
+
if (reverse) {
|
|
18
|
+
const duration = durationInFrames ?? naturalDuration;
|
|
19
|
+
frameToUse = duration - frame;
|
|
20
|
+
}
|
|
21
|
+
if (durationInFrames !== undefined && naturalDuration !== undefined && naturalDuration !== 0) {
|
|
22
|
+
const stretch = durationInFrames / naturalDuration;
|
|
23
|
+
frameToUse = frameToUse / stretch;
|
|
24
|
+
}
|
|
25
|
+
const { position } = springCalculation({ fps, frame: frameToUse, config });
|
|
26
|
+
if (from === 0 && to === 1)
|
|
27
|
+
return position;
|
|
28
|
+
return interpolate(position, [0, 1], [from, to]);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/timings/spring/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAqB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAqB,MAAM,mBAAmB,CAAC;AAE3E;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,EACrB,KAAK,EACL,GAAG,EACH,MAAM,GAAG,EAAE,EACX,IAAI,GAAG,CAAC,EACR,EAAE,GAAG,CAAC,EACN,gBAAgB,EAChB,qBAAqB,EACrB,OAAO,GAAG,KAAK,GAUhB;IACC,MAAM,YAAY,GAAG,OAAO,IAAI,gBAAgB,KAAK,SAAS,CAAC;IAC/D,MAAM,eAAe,GAAG,YAAY;QAClC,CAAC,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC;QAClE,CAAC,CAAC,SAAS,CAAC;IAEd,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,gBAAgB,IAAK,eAA0B,CAAC;QACjE,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;IAChC,CAAC;IAED,IAAI,gBAAgB,KAAK,SAAS,IAAI,eAAe,KAAK,SAAS,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QAC7F,MAAM,OAAO,GAAG,gBAAgB,GAAG,eAAe,CAAC;QACnD,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;IACpC,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;IAE3E,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type SpringConfig } from "./spring-utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* The natural settle time of a spring, in frames: the first frame where the
|
|
4
|
+
* spring is within `threshold` of its target and stays there for 20 frames.
|
|
5
|
+
* Ported from Remotion's `measureSpring`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function measureSpring({ fps, config, threshold, }: {
|
|
8
|
+
fps: number;
|
|
9
|
+
config?: Partial<SpringConfig>;
|
|
10
|
+
threshold?: number;
|
|
11
|
+
}): number;
|
|
12
|
+
//# sourceMappingURL=measure-spring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure-spring.d.ts","sourceRoot":"","sources":["../../../src/timings/spring/measure-spring.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,mBAAmB,CAAC;AAEzE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,GAAG,EACH,MAAW,EACX,SAAiB,GAClB,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CA6BT"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { springCalculation } from "./spring-utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* The natural settle time of a spring, in frames: the first frame where the
|
|
4
|
+
* spring is within `threshold` of its target and stays there for 20 frames.
|
|
5
|
+
* Ported from Remotion's `measureSpring`.
|
|
6
|
+
*/
|
|
7
|
+
export function measureSpring({ fps, config = {}, threshold = 0.005, }) {
|
|
8
|
+
if (threshold === 0)
|
|
9
|
+
return Number.POSITIVE_INFINITY;
|
|
10
|
+
if (threshold === 1)
|
|
11
|
+
return 0;
|
|
12
|
+
if (!Number.isFinite(threshold) || threshold < 0) {
|
|
13
|
+
throw new TypeError(`springTiming: durationRestThreshold must be >= 0 (got ${threshold})`);
|
|
14
|
+
}
|
|
15
|
+
const calc = (frame) => springCalculation({ fps, frame, config });
|
|
16
|
+
let frame = 0;
|
|
17
|
+
let finished = false;
|
|
18
|
+
let restFrame = 0;
|
|
19
|
+
const cap = 100_000; // safety bound
|
|
20
|
+
while (!finished && frame < cap) {
|
|
21
|
+
const { position } = calc(frame);
|
|
22
|
+
if (Math.abs(position - 1) < threshold) {
|
|
23
|
+
if (restFrame === 0)
|
|
24
|
+
restFrame = frame;
|
|
25
|
+
if (frame - restFrame >= 20) {
|
|
26
|
+
finished = true;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
restFrame = 0;
|
|
32
|
+
}
|
|
33
|
+
frame++;
|
|
34
|
+
}
|
|
35
|
+
return restFrame;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=measure-spring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure-spring.js","sourceRoot":"","sources":["../../../src/timings/spring/measure-spring.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEzE;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,GAAG,EACH,MAAM,GAAG,EAAE,EACX,SAAS,GAAG,KAAK,GAKlB;IACC,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,iBAAiB,CAAC;IACrD,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,SAAS,CAAC,yDAAyD,SAAS,GAAG,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAE1E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,eAAe;IAEpC,OAAO,CAAC,QAAQ,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;QAChC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC;YACvC,IAAI,SAAS,KAAK,CAAC;gBAAE,SAAS,GAAG,KAAK,CAAC;YACvC,IAAI,KAAK,GAAG,SAAS,IAAI,EAAE,EAAE,CAAC;gBAC5B,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM;YACR,CAAC;QACH,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,CAAC,CAAC;QAChB,CAAC;QACD,KAAK,EAAE,CAAC;IACV,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type SpringConfig = {
|
|
2
|
+
damping: number;
|
|
3
|
+
mass: number;
|
|
4
|
+
stiffness: number;
|
|
5
|
+
overshootClamping: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare const defaultSpringConfig: SpringConfig;
|
|
8
|
+
type AdvanceResult = {
|
|
9
|
+
position: number;
|
|
10
|
+
velocity: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function springCalculation({ fps, frame, config, from, to, }: {
|
|
13
|
+
fps: number;
|
|
14
|
+
frame: number;
|
|
15
|
+
config?: Partial<SpringConfig>;
|
|
16
|
+
from?: number;
|
|
17
|
+
to?: number;
|
|
18
|
+
}): AdvanceResult;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=spring-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring-utils.d.ts","sourceRoot":"","sources":["../../../src/timings/spring/spring-utils.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,YAKjC,CAAC;AAUF,KAAK,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,wBAAgB,iBAAiB,CAAC,EAChC,GAAG,EACH,KAAK,EACL,MAAW,EACX,IAAQ,EACR,EAAM,GACP,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,aAAa,CA4BhB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// TODO: promote to @smoove/core (a general-purpose spring() solver).
|
|
2
|
+
// Self-contained physics spring, ported from Remotion's packages/core/src/spring.
|
|
3
|
+
// Analytic solution to the damped harmonic oscillator — pure & deterministic.
|
|
4
|
+
export const defaultSpringConfig = {
|
|
5
|
+
damping: 10,
|
|
6
|
+
mass: 1,
|
|
7
|
+
stiffness: 100,
|
|
8
|
+
overshootClamping: false,
|
|
9
|
+
};
|
|
10
|
+
export function springCalculation({ fps, frame, config = {}, from = 0, to = 1, }) {
|
|
11
|
+
const cfg = { ...defaultSpringConfig, ...config };
|
|
12
|
+
if (cfg.damping <= 0) {
|
|
13
|
+
throw new Error(`springTiming: config.damping must be > 0 (got ${cfg.damping})`);
|
|
14
|
+
}
|
|
15
|
+
if (cfg.mass <= 0) {
|
|
16
|
+
throw new Error(`springTiming: config.mass must be > 0 (got ${cfg.mass})`);
|
|
17
|
+
}
|
|
18
|
+
if (cfg.stiffness <= 0) {
|
|
19
|
+
throw new Error(`springTiming: config.stiffness must be > 0 (got ${cfg.stiffness})`);
|
|
20
|
+
}
|
|
21
|
+
let value = from;
|
|
22
|
+
let velocity = 0;
|
|
23
|
+
const frameClamped = Math.max(0, frame);
|
|
24
|
+
const wholeFrames = Math.floor(frameClamped);
|
|
25
|
+
for (let f = 0; f <= wholeFrames; f++) {
|
|
26
|
+
const isLast = f === wholeFrames;
|
|
27
|
+
const proportion = isLast ? frameClamped - wholeFrames : 1;
|
|
28
|
+
if (f === 0 && proportion === 0)
|
|
29
|
+
continue;
|
|
30
|
+
const timestamp = (proportion / fps) * 1000;
|
|
31
|
+
const result = advance({ fromValue: value, toValue: to, velocity, config: cfg, timestamp });
|
|
32
|
+
value = result.position;
|
|
33
|
+
velocity = result.velocity;
|
|
34
|
+
}
|
|
35
|
+
return { position: value, velocity };
|
|
36
|
+
}
|
|
37
|
+
function advance({ fromValue, toValue, velocity, config, timestamp }) {
|
|
38
|
+
const { damping: c, mass: m, stiffness: k } = config;
|
|
39
|
+
const t = Math.min(timestamp, 64) / 1000;
|
|
40
|
+
const v0 = -velocity;
|
|
41
|
+
const x0 = toValue - fromValue;
|
|
42
|
+
const zeta = c / (2 * Math.sqrt(k * m)); // damping ratio
|
|
43
|
+
const omega0 = Math.sqrt(k / m); // undamped angular frequency
|
|
44
|
+
const omega1 = omega0 * Math.sqrt(1.0 - zeta * zeta); // damped angular frequency
|
|
45
|
+
if (zeta < 1) {
|
|
46
|
+
// Under-damped.
|
|
47
|
+
const envelope = Math.exp(-zeta * omega0 * t);
|
|
48
|
+
const position = toValue -
|
|
49
|
+
envelope *
|
|
50
|
+
(((v0 + zeta * omega0 * x0) / omega1) * Math.sin(omega1 * t) + x0 * Math.cos(omega1 * t));
|
|
51
|
+
const velocityResult = zeta *
|
|
52
|
+
omega0 *
|
|
53
|
+
envelope *
|
|
54
|
+
((Math.sin(omega1 * t) * (v0 + zeta * omega0 * x0)) / omega1 + x0 * Math.cos(omega1 * t)) -
|
|
55
|
+
envelope *
|
|
56
|
+
(Math.cos(omega1 * t) * (v0 + zeta * omega0 * x0) - omega1 * x0 * Math.sin(omega1 * t));
|
|
57
|
+
return { position, velocity: velocityResult };
|
|
58
|
+
}
|
|
59
|
+
// Critically damped.
|
|
60
|
+
const envelope = Math.exp(-omega0 * t);
|
|
61
|
+
const position = toValue - envelope * (x0 + (v0 + omega0 * x0) * t);
|
|
62
|
+
const velocityResult = envelope * (v0 * (t * omega0 - 1) + t * x0 * omega0 * omega0);
|
|
63
|
+
return { position, velocity: velocityResult };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=spring-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring-utils.js","sourceRoot":"","sources":["../../../src/timings/spring/spring-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Timing } from "../types.js";
|
|
2
|
+
import { type SpringConfig } from "./spring/index.js";
|
|
3
|
+
export type SpringTimingOptions = {
|
|
4
|
+
config?: Partial<SpringConfig>;
|
|
5
|
+
/** Forced length in frames. When omitted, the spring's natural settle time is used. */
|
|
6
|
+
durationInFrames?: number;
|
|
7
|
+
durationRestThreshold?: number;
|
|
8
|
+
reverse?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A transition whose progress follows a physics spring. Mirrors Remotion's
|
|
12
|
+
* `springTiming`. The spring needs an `fps` to integrate — it is taken from the
|
|
13
|
+
* `Composition` via `getProgress`/`getDurationInFrames`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function springTiming(options?: SpringTimingOptions): Timing;
|
|
16
|
+
//# sourceMappingURL=spring-timing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring-timing.d.ts","sourceRoot":"","sources":["../../src/timings/spring-timing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAiB,KAAK,YAAY,EAAU,MAAM,mBAAmB,CAAC;AAE7E,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAwBtE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { measureSpring, spring } from "./spring/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* A transition whose progress follows a physics spring. Mirrors Remotion's
|
|
4
|
+
* `springTiming`. The spring needs an `fps` to integrate — it is taken from the
|
|
5
|
+
* `Composition` via `getProgress`/`getDurationInFrames`.
|
|
6
|
+
*/
|
|
7
|
+
export function springTiming(options = {}) {
|
|
8
|
+
const { config, durationInFrames, durationRestThreshold, reverse = false } = options;
|
|
9
|
+
if (durationInFrames !== undefined &&
|
|
10
|
+
(!Number.isInteger(durationInFrames) || durationInFrames <= 0)) {
|
|
11
|
+
throw new Error("springTiming: durationInFrames must be a positive integer");
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
getDurationInFrames: (fps) => durationInFrames ??
|
|
15
|
+
Math.ceil(measureSpring({ fps, config, threshold: durationRestThreshold })),
|
|
16
|
+
getProgress: (frame, fps) => spring({
|
|
17
|
+
fps,
|
|
18
|
+
frame,
|
|
19
|
+
config,
|
|
20
|
+
from: reverse ? 1 : 0,
|
|
21
|
+
to: reverse ? 0 : 1,
|
|
22
|
+
durationInFrames,
|
|
23
|
+
durationRestThreshold,
|
|
24
|
+
reverse,
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=spring-timing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spring-timing.js","sourceRoot":"","sources":["../../src/timings/spring-timing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAqB,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAU7E;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,UAA+B,EAAE;IAC5D,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACrF,IACE,gBAAgB,KAAK,SAAS;QAC9B,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,IAAI,CAAC,CAAC,EAC9D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO;QACL,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE,CAC3B,gBAAgB;YAChB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,CAAC;QAC7E,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAC1B,MAAM,CAAC;YACL,GAAG;YACH,KAAK;YACL,MAAM;YACN,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrB,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnB,gBAAgB;YAChB,qBAAqB;YACrB,OAAO;SACR,CAAC;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Composition, Sequence, type SequenceProvider } from "@smoove/core";
|
|
2
|
+
import type { Presentation, Timing } from "./types.js";
|
|
3
|
+
export type TransitionSeriesOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* The Composition the series will be added to. Needed up front because spring
|
|
6
|
+
* timings resolve their length from `fps`, and presentations are sized from
|
|
7
|
+
* the stage `width`/`height`. (Diverges from Remotion, which reads these from
|
|
8
|
+
* React context.)
|
|
9
|
+
*/
|
|
10
|
+
composition: Composition;
|
|
11
|
+
/** Frame the series starts at. Default `0`. */
|
|
12
|
+
from?: number;
|
|
13
|
+
};
|
|
14
|
+
export type TransitionSeriesSceneOptions = {
|
|
15
|
+
durationInFrames: number;
|
|
16
|
+
};
|
|
17
|
+
export type TransitionSeriesTransitionOptions = {
|
|
18
|
+
presentation: Presentation;
|
|
19
|
+
timing: Timing;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Sequential sequencer where adjacent scenes overlap by a transition's
|
|
23
|
+
* `durationInFrames`. Built on the same offset engine as `Series` — a
|
|
24
|
+
* transition is just a sequential step with a negative (overlap) delta. Mirrors
|
|
25
|
+
* Remotion's `<TransitionSeries>`.
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* const series = new TransitionSeries({ composition });
|
|
29
|
+
* series.scene({ durationInFrames: 60 }, (seq) => seq.add(sceneA));
|
|
30
|
+
* series.transition({ presentation: fade(), timing: linearTiming({ durationInFrames: 15 }) });
|
|
31
|
+
* series.scene({ durationInFrames: 90 }, (seq) => seq.add(sceneB));
|
|
32
|
+
* composition.add(series);
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class TransitionSeries implements SequenceProvider {
|
|
36
|
+
readonly from: number;
|
|
37
|
+
private readonly composition;
|
|
38
|
+
private readonly _items;
|
|
39
|
+
constructor(opts: TransitionSeriesOptions);
|
|
40
|
+
scene(opts: TransitionSeriesSceneOptions, build: (seq: Sequence) => void): this;
|
|
41
|
+
transition(opts: TransitionSeriesTransitionOptions): this;
|
|
42
|
+
/** Σ scene durations − Σ transition durations. */
|
|
43
|
+
get durationInFrames(): number;
|
|
44
|
+
/**
|
|
45
|
+
* Build every scene `Sequence` (with overlaps resolved) plus a GL overlay
|
|
46
|
+
* `Sequence` for each Tier B transition. Add them all to the composition.
|
|
47
|
+
*/
|
|
48
|
+
sequences(): Sequence[];
|
|
49
|
+
/** Swap a GL presentation for `fade()` when no WebGL context is available. */
|
|
50
|
+
private _resolve;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=transition-series.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transition-series.d.ts","sourceRoot":"","sources":["../src/transition-series.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGhB,QAAQ,EACR,KAAK,gBAAgB,EACtB,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;;;OAKG;IACH,WAAW,EAAE,WAAW,CAAC;IACzB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE,MAAM,MAAM,iCAAiC,GAAG;IAC9C,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAyBF;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,IAAI,EAAE,uBAAuB;IASzC,KAAK,CAAC,IAAI,EAAE,4BAA4B,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI;IAQ/E,UAAU,CAAC,IAAI,EAAE,iCAAiC,GAAG,IAAI;IAgBzD,kDAAkD;IAClD,IAAI,gBAAgB,IAAI,MAAM,CAQ7B;IAED;;;OAGG;IACH,SAAS,IAAI,QAAQ,EAAE;IAgKvB,8EAA8E;IAC9E,OAAO,CAAC,QAAQ;CAYjB"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { computeOffsets, Sequence, } from "@smoove/core";
|
|
2
|
+
import Konva from "konva";
|
|
3
|
+
import { getCompositor } from "./gl/compositor.js";
|
|
4
|
+
import { fade } from "./presentations/fade.js";
|
|
5
|
+
let warnedNoWebGl = false;
|
|
6
|
+
/** Reset a layer's transform to identity (used between/around transitions). */
|
|
7
|
+
function resetLayer(layer) {
|
|
8
|
+
layer.opacity(1);
|
|
9
|
+
layer.position({ x: 0, y: 0 });
|
|
10
|
+
layer.scale({ x: 1, y: 1 });
|
|
11
|
+
layer.rotation(0);
|
|
12
|
+
if (layer.getAttr("clipFunc"))
|
|
13
|
+
layer.setAttr("clipFunc", undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Sequential sequencer where adjacent scenes overlap by a transition's
|
|
17
|
+
* `durationInFrames`. Built on the same offset engine as `Series` — a
|
|
18
|
+
* transition is just a sequential step with a negative (overlap) delta. Mirrors
|
|
19
|
+
* Remotion's `<TransitionSeries>`.
|
|
20
|
+
*
|
|
21
|
+
* ```ts
|
|
22
|
+
* const series = new TransitionSeries({ composition });
|
|
23
|
+
* series.scene({ durationInFrames: 60 }, (seq) => seq.add(sceneA));
|
|
24
|
+
* series.transition({ presentation: fade(), timing: linearTiming({ durationInFrames: 15 }) });
|
|
25
|
+
* series.scene({ durationInFrames: 90 }, (seq) => seq.add(sceneB));
|
|
26
|
+
* composition.add(series);
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export class TransitionSeries {
|
|
30
|
+
from;
|
|
31
|
+
composition;
|
|
32
|
+
_items = [];
|
|
33
|
+
constructor(opts) {
|
|
34
|
+
const from = opts.from ?? 0;
|
|
35
|
+
if (!Number.isInteger(from) || from < 0) {
|
|
36
|
+
throw new Error("TransitionSeries: from must be a non-negative integer");
|
|
37
|
+
}
|
|
38
|
+
this.composition = opts.composition;
|
|
39
|
+
this.from = from;
|
|
40
|
+
}
|
|
41
|
+
scene(opts, build) {
|
|
42
|
+
if (!Number.isInteger(opts.durationInFrames) || opts.durationInFrames <= 0) {
|
|
43
|
+
throw new Error("TransitionSeries: scene durationInFrames must be a positive integer");
|
|
44
|
+
}
|
|
45
|
+
this._items.push({ kind: "scene", durationInFrames: opts.durationInFrames, build });
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
transition(opts) {
|
|
49
|
+
const last = this._items[this._items.length - 1];
|
|
50
|
+
if (!last) {
|
|
51
|
+
throw new Error("TransitionSeries: a transition must not be the first item — add a scene first");
|
|
52
|
+
}
|
|
53
|
+
if (last.kind === "transition") {
|
|
54
|
+
throw new Error("TransitionSeries: two transitions must not be adjacent — add a scene between them");
|
|
55
|
+
}
|
|
56
|
+
this._items.push({ kind: "transition", presentation: opts.presentation, timing: opts.timing });
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
/** Σ scene durations − Σ transition durations. */
|
|
60
|
+
get durationInFrames() {
|
|
61
|
+
const fps = this.composition.fps;
|
|
62
|
+
let total = 0;
|
|
63
|
+
for (const item of this._items) {
|
|
64
|
+
if (item.kind === "scene")
|
|
65
|
+
total += item.durationInFrames;
|
|
66
|
+
else
|
|
67
|
+
total -= item.timing.getDurationInFrames(fps);
|
|
68
|
+
}
|
|
69
|
+
return total;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Build every scene `Sequence` (with overlaps resolved) plus a GL overlay
|
|
73
|
+
* `Sequence` for each Tier B transition. Add them all to the composition.
|
|
74
|
+
*/
|
|
75
|
+
sequences() {
|
|
76
|
+
if (this._items.length === 0) {
|
|
77
|
+
throw new Error("TransitionSeries: add at least one scene before reading sequences");
|
|
78
|
+
}
|
|
79
|
+
if (this._items[this._items.length - 1]?.kind === "transition") {
|
|
80
|
+
throw new Error("TransitionSeries: a transition must not be the last item — end with a scene");
|
|
81
|
+
}
|
|
82
|
+
const fps = this.composition.fps;
|
|
83
|
+
const dims = {
|
|
84
|
+
width: this.composition.width(),
|
|
85
|
+
height: this.composition.height(),
|
|
86
|
+
};
|
|
87
|
+
const compositor = getCompositor();
|
|
88
|
+
const records = [];
|
|
89
|
+
for (let i = 0; i < this._items.length; i++) {
|
|
90
|
+
const item = this._items[i];
|
|
91
|
+
if (item?.kind !== "scene")
|
|
92
|
+
continue;
|
|
93
|
+
const prev = this._items[i - 1];
|
|
94
|
+
const next = this._items[i + 1];
|
|
95
|
+
const record = {
|
|
96
|
+
durationInFrames: item.durationInFrames,
|
|
97
|
+
build: item.build,
|
|
98
|
+
};
|
|
99
|
+
if (prev?.kind === "transition") {
|
|
100
|
+
const duration = prev.timing.getDurationInFrames(fps);
|
|
101
|
+
record.incoming = { presentation: prev.presentation, timing: prev.timing, duration };
|
|
102
|
+
}
|
|
103
|
+
if (next?.kind === "transition") {
|
|
104
|
+
const duration = next.timing.getDurationInFrames(fps);
|
|
105
|
+
record.outgoing = { presentation: next.presentation, timing: next.timing, duration };
|
|
106
|
+
}
|
|
107
|
+
records.push(record);
|
|
108
|
+
}
|
|
109
|
+
// Validate transition duration ≤ each neighbour scene's duration.
|
|
110
|
+
for (const record of records) {
|
|
111
|
+
if (record.incoming && record.incoming.duration > record.durationInFrames) {
|
|
112
|
+
throw new Error(`TransitionSeries: a transition (${record.incoming.duration} frames) must not be longer than the previous scene (${record.durationInFrames} frames)`);
|
|
113
|
+
}
|
|
114
|
+
if (record.outgoing && record.outgoing.duration > record.durationInFrames) {
|
|
115
|
+
throw new Error(`TransitionSeries: a transition (${record.outgoing.duration} frames) must not be longer than the next scene (${record.durationInFrames} frames)`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Resolve each scene's `from`: an incoming transition overlaps by its duration.
|
|
119
|
+
const offsetScenes = records.map((r) => ({
|
|
120
|
+
durationInFrames: r.durationInFrames,
|
|
121
|
+
offset: r.incoming ? -r.incoming.duration : 0,
|
|
122
|
+
}));
|
|
123
|
+
const { placed } = computeOffsets(offsetScenes, this.from);
|
|
124
|
+
const sceneSeqs = [];
|
|
125
|
+
const overlaySeqs = [];
|
|
126
|
+
records.forEach((record, i) => {
|
|
127
|
+
const place = placed[i];
|
|
128
|
+
if (!place)
|
|
129
|
+
return;
|
|
130
|
+
const seq = new Sequence({ from: place.from, durationInFrames: place.durationInFrames });
|
|
131
|
+
record.build(seq);
|
|
132
|
+
sceneSeqs.push(seq);
|
|
133
|
+
// Resolve presentations, falling back to fade when GL is unavailable.
|
|
134
|
+
const incoming = record.incoming
|
|
135
|
+
? {
|
|
136
|
+
...record.incoming,
|
|
137
|
+
presentation: this._resolve(record.incoming.presentation, compositor),
|
|
138
|
+
}
|
|
139
|
+
: undefined;
|
|
140
|
+
const outgoing = record.outgoing
|
|
141
|
+
? {
|
|
142
|
+
...record.outgoing,
|
|
143
|
+
presentation: this._resolve(record.outgoing.presentation, compositor),
|
|
144
|
+
}
|
|
145
|
+
: undefined;
|
|
146
|
+
const dur = place.durationInFrames;
|
|
147
|
+
if (incoming || outgoing) {
|
|
148
|
+
seq.register((local) => {
|
|
149
|
+
if (incoming && local < incoming.duration && !incoming.presentation.gl) {
|
|
150
|
+
const p = incoming.timing.getProgress(local, fps);
|
|
151
|
+
incoming.presentation.enter?.(seq, p, dims);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (outgoing && local >= dur - outgoing.duration && !outgoing.presentation.gl) {
|
|
155
|
+
const p = outgoing.timing.getProgress(local - (dur - outgoing.duration), fps);
|
|
156
|
+
outgoing.presentation.exit?.(seq, p, dims);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
resetLayer(seq);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Tier B: an overlay sequence drives the GL compositor over the overlap.
|
|
163
|
+
if (incoming?.presentation.gl && compositor) {
|
|
164
|
+
const outgoingSeq = sceneSeqs[i - 1];
|
|
165
|
+
const gl = incoming.presentation.gl;
|
|
166
|
+
const timing = incoming.timing;
|
|
167
|
+
const d = incoming.duration;
|
|
168
|
+
if (outgoingSeq) {
|
|
169
|
+
const overlay = new Sequence({ from: place.from, durationInFrames: d });
|
|
170
|
+
const image = new Konva.Image({
|
|
171
|
+
x: 0,
|
|
172
|
+
y: 0,
|
|
173
|
+
width: dims.width,
|
|
174
|
+
height: dims.height,
|
|
175
|
+
image: undefined,
|
|
176
|
+
listening: false,
|
|
177
|
+
});
|
|
178
|
+
overlay.add(image);
|
|
179
|
+
overlay.register((local) => {
|
|
180
|
+
const p = timing.getProgress(local, fps);
|
|
181
|
+
const incomingCanvas = seq.toCanvas({
|
|
182
|
+
x: 0,
|
|
183
|
+
y: 0,
|
|
184
|
+
width: dims.width,
|
|
185
|
+
height: dims.height,
|
|
186
|
+
pixelRatio: 1,
|
|
187
|
+
});
|
|
188
|
+
const outgoingCanvas = outgoingSeq.toCanvas({
|
|
189
|
+
x: 0,
|
|
190
|
+
y: 0,
|
|
191
|
+
width: dims.width,
|
|
192
|
+
height: dims.height,
|
|
193
|
+
pixelRatio: 1,
|
|
194
|
+
});
|
|
195
|
+
const out = compositor.render(gl.fragment, incomingCanvas, outgoingCanvas, p, gl.uniforms?.(p, dims) ?? {}, dims.width, dims.height);
|
|
196
|
+
image.image(out);
|
|
197
|
+
});
|
|
198
|
+
overlaySeqs.push(overlay);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
// Overlays added last so they z-order above the scene layers they blend.
|
|
203
|
+
return [...sceneSeqs, ...overlaySeqs];
|
|
204
|
+
}
|
|
205
|
+
/** Swap a GL presentation for `fade()` when no WebGL context is available. */
|
|
206
|
+
_resolve(presentation, compositor) {
|
|
207
|
+
if (presentation.gl && !compositor) {
|
|
208
|
+
if (!warnedNoWebGl) {
|
|
209
|
+
warnedNoWebGl = true;
|
|
210
|
+
console.warn("@smoove/transitions: WebGL2 unavailable — shader transitions fall back to fade().");
|
|
211
|
+
}
|
|
212
|
+
return fade();
|
|
213
|
+
}
|
|
214
|
+
return presentation;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=transition-series.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transition-series.js","sourceRoot":"","sources":["../src/transition-series.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type Konva from "konva";
|
|
2
|
+
/** Scene dimensions handed to a presentation — the Composition stage size. */
|
|
3
|
+
export type PresentationDims = {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Extra (per-effect) uniforms a GL presentation uploads each frame, keyed by
|
|
9
|
+
* GLSL uniform name. A `number` → `uniform1f`; a `number[]` of length 2/3/4 →
|
|
10
|
+
* `uniform2f`/`uniform3f`/`uniform4f`.
|
|
11
|
+
*/
|
|
12
|
+
export type GlUniforms = Record<string, number | number[]>;
|
|
13
|
+
/**
|
|
14
|
+
* How a transition renders. A geometric (Tier A) presentation implements
|
|
15
|
+
* `enter`/`exit`, mutating the incoming/outgoing `Konva.Layer` directly. A
|
|
16
|
+
* shader (Tier B) presentation instead provides `gl` — a fragment shader the
|
|
17
|
+
* shared WebGL compositor runs over both captured layers.
|
|
18
|
+
*/
|
|
19
|
+
export type Presentation = {
|
|
20
|
+
/** Apply the incoming layer's state at `progress` (0 → fully out, 1 → in). */
|
|
21
|
+
enter?(layer: Konva.Layer, progress: number, dims: PresentationDims): void;
|
|
22
|
+
/** Apply the outgoing layer's state at `progress` (0 → fully in, 1 → out). */
|
|
23
|
+
exit?(layer: Konva.Layer, progress: number, dims: PresentationDims): void;
|
|
24
|
+
/** GLSL fragment shader + uniform wiring for a Tier B (shader) transition. */
|
|
25
|
+
gl?: {
|
|
26
|
+
fragment: string;
|
|
27
|
+
/** Per-effect uniforms (beyond `u_time`/`u_prev`/`u_next`) for this frame. */
|
|
28
|
+
uniforms?(progress: number, dims: PresentationDims): GlUniforms;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Maps a transition's local frame onto a `[0, 1]` progress and reports its
|
|
33
|
+
* length in frames. Pure/deterministic so transitions render identically
|
|
34
|
+
* offline.
|
|
35
|
+
*/
|
|
36
|
+
export type Timing = {
|
|
37
|
+
getDurationInFrames(fps: number): number;
|
|
38
|
+
getProgress(localFrame: number, fps: number): number;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,8EAA8E;AAC9E,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjE;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,8EAA8E;IAC9E,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3E,8EAA8E;IAC9E,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC1E,8EAA8E;IAC9E,EAAE,CAAC,EAAE;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB,8EAA8E;QAC9E,QAAQ,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,UAAU,CAAC;KACjE,CAAC;CACH,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACzC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACtD,CAAC"}
|
package/dist/types.js
ADDED