(config: HyperShaderConfig)
| 807 | } |
| 808 | |
| 809 | export function init(config: HyperShaderConfig): GsapTimeline { |
| 810 | const { bgColor, scenes, transitions } = config; |
| 811 | |
| 812 | if (scenes.length !== transitions.length + 1) { |
| 813 | throw new Error( |
| 814 | `[HyperShader] init(): expected scenes.length === transitions.length + 1, got scenes=${scenes.length}, transitions=${transitions.length}`, |
| 815 | ); |
| 816 | } |
| 817 | |
| 818 | // Verify each scene id resolves to an element with the `.scene` class. |
| 819 | // Capture and compositing later assume both — without this guard the |
| 820 | // texture map gets stale ids and transitions silently no-op. |
| 821 | if (typeof document !== "undefined") { |
| 822 | const missing: string[] = []; |
| 823 | const notScene: string[] = []; |
| 824 | for (const id of scenes) { |
| 825 | const el = document.getElementById(id); |
| 826 | if (!el) { |
| 827 | missing.push(id); |
| 828 | } else if (!el.classList.contains("scene")) { |
| 829 | notScene.push(id); |
| 830 | } |
| 831 | } |
| 832 | if (missing.length > 0) { |
| 833 | throw new Error(`[HyperShader] init(): scene ids not found in DOM: ${missing.join(", ")}`); |
| 834 | } |
| 835 | if (notScene.length > 0) { |
| 836 | throw new Error( |
| 837 | `[HyperShader] init(): elements found but missing .scene class: ${notScene.join(", ")}`, |
| 838 | ); |
| 839 | } |
| 840 | } |
| 841 | |
| 842 | // Locally redeclared (not imported) because @hyperframes/shader-transitions |
| 843 | // ships as a standalone CDN bundle and must not depend on @hyperframes/engine. |
| 844 | // Keep this in sync with HfTransitionMeta in packages/engine/src/types.ts. |
| 845 | interface HfTransitionMeta { |
| 846 | time: number; |
| 847 | duration: number; |
| 848 | shader?: string; // undefined = CSS crossfade (no WebGL required) |
| 849 | ease: string; |
| 850 | fromScene: string; |
| 851 | toScene: string; |
| 852 | } |
| 853 | type HfWindowWrite = { __hf?: { transitions?: HfTransitionMeta[] } }; |
| 854 | if (typeof window !== "undefined") { |
| 855 | const hfWin = window as unknown as HfWindowWrite; |
| 856 | if (hfWin.__hf) { |
| 857 | hfWin.__hf.transitions = transitions.map((t: TransitionConfig, i: number) => ({ |
| 858 | time: t.time, |
| 859 | duration: t.duration ?? DEFAULT_DURATION, |
| 860 | shader: t.shader, |
| 861 | ease: t.ease ?? DEFAULT_EASE, |
| 862 | fromScene: scenes[i] ?? "", |
| 863 | toScene: scenes[i + 1] ?? "", |
| 864 | })); |
| 865 | } |
| 866 | } |
nothing calls this directly
no test coverage detected