@framevideo/shader-transitions 0.0.3

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.
@@ -0,0 +1,107 @@
1
+ interface ShaderDef {
2
+ frag: string;
3
+ }
4
+ declare const shaders: Record<string, ShaderDef>;
5
+ type ShaderName = keyof typeof shaders;
6
+ declare const SHADER_NAMES: ShaderName[];
7
+
8
+ interface GsapTimeline {
9
+ paused: () => boolean;
10
+ play: (from?: number, suppressEvents?: boolean) => GsapTimeline;
11
+ pause: (atTime?: number, suppressEvents?: boolean) => GsapTimeline;
12
+ time: {
13
+ (): number;
14
+ (value: number, suppressEvents?: boolean): GsapTimeline;
15
+ };
16
+ seek?: (position: number | string, suppressEvents?: boolean) => GsapTimeline;
17
+ call: (fn: () => void, args: null, position: number) => GsapTimeline;
18
+ to: (target: Record<string, unknown>, vars: Record<string, unknown>, position: number) => GsapTimeline;
19
+ set: (target: string, vars: Record<string, unknown>, position?: number) => GsapTimeline;
20
+ from: (target: string, vars: Record<string, unknown>, position?: number) => GsapTimeline;
21
+ fromTo: (target: string, from: Record<string, unknown>, to: Record<string, unknown>, position?: number) => GsapTimeline;
22
+ [key: string]: unknown;
23
+ }
24
+ interface TransitionConfig {
25
+ time: number;
26
+ /** Omit to use a CSS crossfade instead of a WebGL shader. */
27
+ shader?: ShaderName;
28
+ duration?: number;
29
+ ease?: string;
30
+ }
31
+ interface HyperShaderConfig {
32
+ bgColor: string;
33
+ accentColor?: string;
34
+ scenes: string[];
35
+ transitions: TransitionConfig[];
36
+ timeline?: GsapTimeline;
37
+ compositionId?: string;
38
+ previewCaptureFps?: number;
39
+ }
40
+ declare function init(config: HyperShaderConfig): GsapTimeline;
41
+
42
+ declare function isHtmlInCanvasCaptureSupported(): boolean;
43
+
44
+ interface AccentColors {
45
+ accent: [number, number, number];
46
+ dark: [number, number, number];
47
+ bright: [number, number, number];
48
+ }
49
+
50
+ /**
51
+ * engineModePageComposite — page-side WebGL compositor for engine render mode.
52
+ *
53
+ * Opt-in via `window.__FV_PAGE_SIDE_COMPOSITING__ = true` (set by the producer
54
+ * when `EngineConfig.enablePageSideCompositing` is true). When the flag is
55
+ * off, hyper-shader's engine-mode path stays on the opacity-flip-only timeline
56
+ * and the producer's fv#677 Node-side layered pipeline runs the shader blend.
57
+ *
58
+ * Two-phase capture protocol:
59
+ *
60
+ * Phase 1 (seek wrapper, runs inside page.evaluate):
61
+ * - Runs original GSAP seek to position the timeline
62
+ * - If inside a transition window, clones FROM/TO scene elements into
63
+ * layoutsubtree staging canvases
64
+ * - Sets window.__fv_page_composite_pending with transition metadata
65
+ * - Returns immediately (seek resolves)
66
+ *
67
+ * Paint force (engine-side, frameCapture.ts):
68
+ * - Engine detects the pending flag and fires a micro Page.captureScreenshot
69
+ * to force the browser compositor to paint the staging canvas clones
70
+ *
71
+ * Phase 2 (engine calls window.__fv_page_composite_resolve):
72
+ * - drawElementImage reads the now-valid paint records from the clones
73
+ * - Uploads textures to WebGL, runs the shader, shows the GL overlay
74
+ * - Cleans up staging canvases
75
+ *
76
+ * This gives native-fidelity capture (identical to preview-path
77
+ * drawElementImage) without depending on requestAnimationFrame for paint.
78
+ */
79
+
80
+ interface PageCompositeTransitionConfig {
81
+ time: number;
82
+ /**
83
+ * Shader id. Undefined entries are CSS crossfades — the page-side
84
+ * compositor skips them, and the GSAP timeline in `initEngineMode`
85
+ * schedules an actual opacity-crossfade tween for those entries so the
86
+ * single page screenshot contains a correct blended frame. The entry
87
+ * stays in the array to preserve `transitions[i]` ↔ `scenes[i]`/
88
+ * `scenes[i+1]` index alignment for the surrounding shader entries.
89
+ */
90
+ shader?: ShaderName;
91
+ duration?: number;
92
+ }
93
+ interface PageCompositorInstallOptions {
94
+ scenes: string[];
95
+ transitions: PageCompositeTransitionConfig[];
96
+ bgColor: string;
97
+ accentColors: AccentColors;
98
+ width: number;
99
+ height: number;
100
+ defaultDuration: number;
101
+ }
102
+ declare const PAGE_COMPOSITOR_CANVAS_ID = "__fv-page-side-compositor";
103
+ declare const PAGE_COMPOSITOR_BUILD_CANARY = "__fv_page_compositor_v1__";
104
+ declare function isPageSideCompositingSupported(): boolean;
105
+ declare function installPageSideCompositor(options: PageCompositorInstallOptions): boolean;
106
+
107
+ export { type HyperShaderConfig, PAGE_COMPOSITOR_BUILD_CANARY, PAGE_COMPOSITOR_CANVAS_ID, SHADER_NAMES, type ShaderName, type TransitionConfig, init, installPageSideCompositor, isHtmlInCanvasCaptureSupported, isPageSideCompositingSupported };
@@ -0,0 +1,107 @@
1
+ interface ShaderDef {
2
+ frag: string;
3
+ }
4
+ declare const shaders: Record<string, ShaderDef>;
5
+ type ShaderName = keyof typeof shaders;
6
+ declare const SHADER_NAMES: ShaderName[];
7
+
8
+ interface GsapTimeline {
9
+ paused: () => boolean;
10
+ play: (from?: number, suppressEvents?: boolean) => GsapTimeline;
11
+ pause: (atTime?: number, suppressEvents?: boolean) => GsapTimeline;
12
+ time: {
13
+ (): number;
14
+ (value: number, suppressEvents?: boolean): GsapTimeline;
15
+ };
16
+ seek?: (position: number | string, suppressEvents?: boolean) => GsapTimeline;
17
+ call: (fn: () => void, args: null, position: number) => GsapTimeline;
18
+ to: (target: Record<string, unknown>, vars: Record<string, unknown>, position: number) => GsapTimeline;
19
+ set: (target: string, vars: Record<string, unknown>, position?: number) => GsapTimeline;
20
+ from: (target: string, vars: Record<string, unknown>, position?: number) => GsapTimeline;
21
+ fromTo: (target: string, from: Record<string, unknown>, to: Record<string, unknown>, position?: number) => GsapTimeline;
22
+ [key: string]: unknown;
23
+ }
24
+ interface TransitionConfig {
25
+ time: number;
26
+ /** Omit to use a CSS crossfade instead of a WebGL shader. */
27
+ shader?: ShaderName;
28
+ duration?: number;
29
+ ease?: string;
30
+ }
31
+ interface HyperShaderConfig {
32
+ bgColor: string;
33
+ accentColor?: string;
34
+ scenes: string[];
35
+ transitions: TransitionConfig[];
36
+ timeline?: GsapTimeline;
37
+ compositionId?: string;
38
+ previewCaptureFps?: number;
39
+ }
40
+ declare function init(config: HyperShaderConfig): GsapTimeline;
41
+
42
+ declare function isHtmlInCanvasCaptureSupported(): boolean;
43
+
44
+ interface AccentColors {
45
+ accent: [number, number, number];
46
+ dark: [number, number, number];
47
+ bright: [number, number, number];
48
+ }
49
+
50
+ /**
51
+ * engineModePageComposite — page-side WebGL compositor for engine render mode.
52
+ *
53
+ * Opt-in via `window.__FV_PAGE_SIDE_COMPOSITING__ = true` (set by the producer
54
+ * when `EngineConfig.enablePageSideCompositing` is true). When the flag is
55
+ * off, hyper-shader's engine-mode path stays on the opacity-flip-only timeline
56
+ * and the producer's fv#677 Node-side layered pipeline runs the shader blend.
57
+ *
58
+ * Two-phase capture protocol:
59
+ *
60
+ * Phase 1 (seek wrapper, runs inside page.evaluate):
61
+ * - Runs original GSAP seek to position the timeline
62
+ * - If inside a transition window, clones FROM/TO scene elements into
63
+ * layoutsubtree staging canvases
64
+ * - Sets window.__fv_page_composite_pending with transition metadata
65
+ * - Returns immediately (seek resolves)
66
+ *
67
+ * Paint force (engine-side, frameCapture.ts):
68
+ * - Engine detects the pending flag and fires a micro Page.captureScreenshot
69
+ * to force the browser compositor to paint the staging canvas clones
70
+ *
71
+ * Phase 2 (engine calls window.__fv_page_composite_resolve):
72
+ * - drawElementImage reads the now-valid paint records from the clones
73
+ * - Uploads textures to WebGL, runs the shader, shows the GL overlay
74
+ * - Cleans up staging canvases
75
+ *
76
+ * This gives native-fidelity capture (identical to preview-path
77
+ * drawElementImage) without depending on requestAnimationFrame for paint.
78
+ */
79
+
80
+ interface PageCompositeTransitionConfig {
81
+ time: number;
82
+ /**
83
+ * Shader id. Undefined entries are CSS crossfades — the page-side
84
+ * compositor skips them, and the GSAP timeline in `initEngineMode`
85
+ * schedules an actual opacity-crossfade tween for those entries so the
86
+ * single page screenshot contains a correct blended frame. The entry
87
+ * stays in the array to preserve `transitions[i]` ↔ `scenes[i]`/
88
+ * `scenes[i+1]` index alignment for the surrounding shader entries.
89
+ */
90
+ shader?: ShaderName;
91
+ duration?: number;
92
+ }
93
+ interface PageCompositorInstallOptions {
94
+ scenes: string[];
95
+ transitions: PageCompositeTransitionConfig[];
96
+ bgColor: string;
97
+ accentColors: AccentColors;
98
+ width: number;
99
+ height: number;
100
+ defaultDuration: number;
101
+ }
102
+ declare const PAGE_COMPOSITOR_CANVAS_ID = "__fv-page-side-compositor";
103
+ declare const PAGE_COMPOSITOR_BUILD_CANARY = "__fv_page_compositor_v1__";
104
+ declare function isPageSideCompositingSupported(): boolean;
105
+ declare function installPageSideCompositor(options: PageCompositorInstallOptions): boolean;
106
+
107
+ export { type HyperShaderConfig, PAGE_COMPOSITOR_BUILD_CANARY, PAGE_COMPOSITOR_CANVAS_ID, SHADER_NAMES, type ShaderName, type TransitionConfig, init, installPageSideCompositor, isHtmlInCanvasCaptureSupported, isPageSideCompositingSupported };