react-scroll-media 1.0.3 → 1.0.4
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/README.md +26 -4
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +37 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
- **Manifest** — Load sequences from a JSON manifest
|
|
44
44
|
|
|
45
45
|
### 🧠 **Smart Memory Management**
|
|
46
|
-
- **Lazy Mode** — Keeps only ±
|
|
46
|
+
- **Lazy Mode** — Keeps only ±10 frames (configurable) in memory for huge sequences (800+ frames)
|
|
47
47
|
- **Eager Mode** — Preloads everything for maximum smoothness on smaller sequences
|
|
48
48
|
- **Decoding** — Uses `img.decode()` to prevent main-thread jank during painting
|
|
49
49
|
|
|
@@ -249,6 +249,22 @@ const MyComponent = () => {
|
|
|
249
249
|
|
|
250
250
|
---
|
|
251
251
|
|
|
252
|
+
## 🎨 Image Fit Modes
|
|
253
|
+
|
|
254
|
+
The `fit` prop controls how images scale within the viewport, using the standard CSS `object-fit` property.
|
|
255
|
+
|
|
256
|
+
| Mode | Description | Best Use Case |
|
|
257
|
+
|------|-------------|---------------|
|
|
258
|
+
| `cover` (Default) | **Fills the screen**, cropping edges if aspect ratios differ. | Full-screen background sequences. |
|
|
259
|
+
| `contain` | **Shows the full image**. Letterboxing (bars) may appear. | Product showcases where no part of the image should be cut off. |
|
|
260
|
+
| `fill` | **Stretches** to fill dimensions. Ignores aspect ratio. | Abstract patterns where distortion is acceptable. |
|
|
261
|
+
| `none` | **Original size**. No scaling. | Pixel-perfect displays when the wrapper matches image size. |
|
|
262
|
+
| `scale-down` | **Smallest of `none` or `contain`**. | Responsive layouts where images shouldn't upscale beyond native resolution. |
|
|
263
|
+
|
|
264
|
+
<br />
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
252
268
|
## ⚙️ Configuration
|
|
253
269
|
|
|
254
270
|
### `ScrollSequence` Props
|
|
@@ -300,6 +316,12 @@ const MyComponent = () => {
|
|
|
300
316
|
<td>ARIA label for the canvas. Example: <code>"360 degree view of the product"</code>.</td>
|
|
301
317
|
</tr>
|
|
302
318
|
<tr>
|
|
319
|
+
<td><code>fit</code></td>
|
|
320
|
+
<td><code>"cover" | "contain" | "fill" | "none" | "scale-down"</code></td>
|
|
321
|
+
<td><code>"cover"</code></td>
|
|
322
|
+
<td>Determines how the image is resized to fit its container.</td>
|
|
323
|
+
</tr>
|
|
324
|
+
<tr>
|
|
303
325
|
<td><code>debug</code></td>
|
|
304
326
|
<td><code>boolean</code></td>
|
|
305
327
|
<td><code>false</code></td>
|
|
@@ -324,10 +346,10 @@ const MyComponent = () => {
|
|
|
324
346
|
|
|
325
347
|
| Metric | Size |
|
|
326
348
|
|--------|------|
|
|
327
|
-
| **Minified** | ~
|
|
328
|
-
| **Gzipped** | ~
|
|
349
|
+
| **Minified** | ~23.72 kB |
|
|
350
|
+
| **Gzipped** | ~7.11 kB |
|
|
329
351
|
|
|
330
|
-
✨ **Zero dependencies
|
|
352
|
+
✨ **Zero dependencies**. Uses native Canvas API, no heavyweight libraries.
|
|
331
353
|
|
|
332
354
|
<br />
|
|
333
355
|
|
package/dist/index.d.mts
CHANGED
|
@@ -45,6 +45,11 @@ interface ScrollSequenceProps {
|
|
|
45
45
|
children?: React.ReactNode;
|
|
46
46
|
/** Component to render while the sequence is loading. */
|
|
47
47
|
fallback?: React.ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Object-fit property for the canvas.
|
|
50
|
+
* Defaults to 'cover'.
|
|
51
|
+
*/
|
|
52
|
+
fit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
48
53
|
/** Accessibility label for the canvas (role="img"). Defaults to "Scroll sequence". */
|
|
49
54
|
accessibilityLabel?: string;
|
|
50
55
|
/** Callback fired when an error occurs (e.g. image load failure). */
|
|
@@ -92,8 +97,10 @@ interface ScrollTimelineProviderProps {
|
|
|
92
97
|
scrollLength?: string;
|
|
93
98
|
className?: string;
|
|
94
99
|
style?: React__default.CSSProperties;
|
|
100
|
+
/** Optional ref for the container element. */
|
|
101
|
+
containerRef?: React__default.RefObject<HTMLDivElement>;
|
|
95
102
|
}
|
|
96
|
-
declare function ScrollTimelineProvider({ children, scrollLength, className, style, }: ScrollTimelineProviderProps): react_jsx_runtime.JSX.Element;
|
|
103
|
+
declare function ScrollTimelineProvider({ children, scrollLength, className, style, containerRef: externalRef, }: ScrollTimelineProviderProps): react_jsx_runtime.JSX.Element;
|
|
97
104
|
|
|
98
105
|
interface ScrollTextProps {
|
|
99
106
|
children: React__default.ReactNode;
|
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,11 @@ interface ScrollSequenceProps {
|
|
|
45
45
|
children?: React.ReactNode;
|
|
46
46
|
/** Component to render while the sequence is loading. */
|
|
47
47
|
fallback?: React.ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Object-fit property for the canvas.
|
|
50
|
+
* Defaults to 'cover'.
|
|
51
|
+
*/
|
|
52
|
+
fit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
48
53
|
/** Accessibility label for the canvas (role="img"). Defaults to "Scroll sequence". */
|
|
49
54
|
accessibilityLabel?: string;
|
|
50
55
|
/** Callback fired when an error occurs (e.g. image load failure). */
|
|
@@ -92,8 +97,10 @@ interface ScrollTimelineProviderProps {
|
|
|
92
97
|
scrollLength?: string;
|
|
93
98
|
className?: string;
|
|
94
99
|
style?: React__default.CSSProperties;
|
|
100
|
+
/** Optional ref for the container element. */
|
|
101
|
+
containerRef?: React__default.RefObject<HTMLDivElement>;
|
|
95
102
|
}
|
|
96
|
-
declare function ScrollTimelineProvider({ children, scrollLength, className, style, }: ScrollTimelineProviderProps): react_jsx_runtime.JSX.Element;
|
|
103
|
+
declare function ScrollTimelineProvider({ children, scrollLength, className, style, containerRef: externalRef, }: ScrollTimelineProviderProps): react_jsx_runtime.JSX.Element;
|
|
97
104
|
|
|
98
105
|
interface ScrollTextProps {
|
|
99
106
|
children: React__default.ReactNode;
|
package/dist/index.js
CHANGED
|
@@ -572,9 +572,11 @@ function ScrollTimelineProvider({
|
|
|
572
572
|
children,
|
|
573
573
|
scrollLength = "300vh",
|
|
574
574
|
className = "",
|
|
575
|
-
style = {}
|
|
575
|
+
style = {},
|
|
576
|
+
containerRef: externalRef
|
|
576
577
|
}) {
|
|
577
|
-
const
|
|
578
|
+
const internalRef = (0, import_react3.useRef)(null);
|
|
579
|
+
const containerRef = externalRef || internalRef;
|
|
578
580
|
const [timeline, setTimeline] = (0, import_react3.useState)(null);
|
|
579
581
|
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react3.default.useLayoutEffect : import_react3.default.useEffect;
|
|
580
582
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -620,6 +622,8 @@ var InnerSequence = ({
|
|
|
620
622
|
memoryStrategy,
|
|
621
623
|
lazyBuffer,
|
|
622
624
|
accessibilityLabel = "Scroll sequence",
|
|
625
|
+
fit = "cover",
|
|
626
|
+
// Default to cover
|
|
623
627
|
fallback,
|
|
624
628
|
onError
|
|
625
629
|
}) => {
|
|
@@ -635,7 +639,8 @@ var InnerSequence = ({
|
|
|
635
639
|
display: "block",
|
|
636
640
|
width: "100%",
|
|
637
641
|
height: "100%",
|
|
638
|
-
objectFit:
|
|
642
|
+
objectFit: fit,
|
|
643
|
+
// Use the prop
|
|
639
644
|
opacity: isLoaded ? 1 : 0,
|
|
640
645
|
transition: "opacity 0.2s ease-in"
|
|
641
646
|
};
|
|
@@ -677,30 +682,38 @@ var ScrollSequence = import_react4.default.forwardRef(
|
|
|
677
682
|
memoryStrategy = "eager",
|
|
678
683
|
lazyBuffer = 10,
|
|
679
684
|
fallback,
|
|
685
|
+
fit = "cover",
|
|
686
|
+
// Default here too
|
|
680
687
|
accessibilityLabel,
|
|
681
|
-
onError
|
|
688
|
+
onError,
|
|
689
|
+
children
|
|
690
|
+
// Extract children
|
|
682
691
|
} = props;
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
692
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
693
|
+
ScrollTimelineProvider,
|
|
694
|
+
{
|
|
695
|
+
scrollLength,
|
|
696
|
+
className,
|
|
697
|
+
style: { position: "relative" },
|
|
698
|
+
containerRef: ref,
|
|
699
|
+
children: [
|
|
700
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
701
|
+
InnerSequence,
|
|
702
|
+
{
|
|
703
|
+
source,
|
|
704
|
+
debug,
|
|
705
|
+
memoryStrategy,
|
|
706
|
+
lazyBuffer,
|
|
707
|
+
fallback,
|
|
708
|
+
accessibilityLabel,
|
|
709
|
+
onError,
|
|
710
|
+
fit
|
|
711
|
+
}
|
|
712
|
+
),
|
|
713
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "absolute", inset: 0, zIndex: 10, pointerEvents: "none" }, children })
|
|
714
|
+
]
|
|
686
715
|
}
|
|
687
|
-
|
|
688
|
-
}, []);
|
|
689
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className, style: { width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(ScrollTimelineProvider, { scrollLength, children: [
|
|
690
|
-
prefersReducedMotion && fallback ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "sticky", top: 0, height: "100vh", width: "100%" }, children: fallback }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
691
|
-
InnerSequence,
|
|
692
|
-
{
|
|
693
|
-
source,
|
|
694
|
-
debug,
|
|
695
|
-
memoryStrategy,
|
|
696
|
-
lazyBuffer,
|
|
697
|
-
fallback,
|
|
698
|
-
accessibilityLabel,
|
|
699
|
-
onError
|
|
700
|
-
}
|
|
701
|
-
),
|
|
702
|
-
props.children
|
|
703
|
-
] }) });
|
|
716
|
+
);
|
|
704
717
|
}
|
|
705
718
|
);
|
|
706
719
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/react/ScrollSequence.tsx","../src/react/useScrollSequence.ts","../src/controllers/imageController.ts","../src/sequence/sequenceResolver.ts","../src/core/clamp.ts","../src/react/scrollTimelineContext.ts","../src/react/useScrollTimeline.ts","../src/react/ScrollTimelineProvider.tsx","../src/core/loopManager.ts","../src/constants.ts","../src/core/scrollTimeline.ts","../src/react/ScrollText.tsx","../src/react/ScrollWordReveal.tsx"],"sourcesContent":["/**\n * react-scroll-media\n * Production-ready scroll-driven image sequence rendering component\n */\n\n// Public exports\n// Public exports\nexport { ScrollSequence } from './react/ScrollSequence';\nexport { useScrollSequence } from './react/useScrollSequence';\nexport { ScrollTimelineProvider } from './react/ScrollTimelineProvider';\nexport { ScrollText } from './react/ScrollText';\nexport { ScrollWordReveal } from './react/ScrollWordReveal';\nexport { useScrollTimeline } from './react/useScrollTimeline';\n\n// Types\nexport type { ScrollSequenceProps, ResolvedSequence, ScrollProgress } from './types';\n\n// Core utilities (advanced users)\nexport { ScrollTimeline } from './core/scrollTimeline';\nexport { clamp } from './core/clamp';\n\n// Sequence utilities (advanced users)\nexport { resolveSequence } from './sequence/sequenceResolver';\n\n// Controllers (advanced users)\nexport { ImageController } from './controllers/imageController';\nexport type { ImageControllerConfig } from './controllers/imageController';\n","import React, { useRef } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { useScrollSequence } from './useScrollSequence';\nimport { ScrollTimelineProvider } from './ScrollTimelineProvider';\n\ninterface InnerSequenceProps {\n source: ScrollSequenceProps['source'];\n debug: boolean;\n memoryStrategy: ScrollSequenceProps['memoryStrategy'];\n lazyBuffer?: number;\n accessibilityLabel?: string;\n fallback?: React.ReactNode;\n onError?: (error: Error) => void;\n}\n\nconst InnerSequence: React.FC<InnerSequenceProps> = ({ \n source, \n debug, \n memoryStrategy,\n lazyBuffer,\n accessibilityLabel = \"Scroll sequence\",\n fallback,\n onError\n}) => {\n const debugRef = useRef<HTMLDivElement>(null);\n const { canvasRef, isLoaded } = useScrollSequence({\n source,\n debugRef,\n memoryStrategy,\n lazyBuffer,\n onError\n });\n \n // Fallback logic could be handled here or by parent.\n // If we handle it here, we overlay it?\n // Actually, canvas opacity handles the fade-in.\n // Use fallback if provided and not loaded.\n\n const canvasStyle: React.CSSProperties = {\n display: 'block',\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n opacity: isLoaded ? 1 : 0,\n transition: 'opacity 0.2s ease-in',\n };\n \n const debugStyle: React.CSSProperties = {\n position: 'absolute',\n top: '10px',\n left: '10px',\n background: 'rgba(0, 0, 0, 0.7)',\n color: '#00ff00',\n padding: '8px',\n borderRadius: '4px',\n fontFamily: 'monospace',\n fontSize: '12px',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n zIndex: 9999,\n };\n\n return (\n <>\n {/* Render fallback behind canvas, or replace? \n If replace, we might loose the canvas ref init?\n Better to render both and cross-fade or just hide fallback when loaded.\n */}\n {!isLoaded && fallback && (\n <div style={{ position: 'absolute', inset: 0, zIndex: 1 }}>\n {fallback}\n </div>\n )}\n \n <canvas \n ref={canvasRef} \n style={canvasStyle} \n role=\"img\"\n aria-label={accessibilityLabel}\n />\n {debug && <div ref={debugRef} style={debugStyle}>Waiting for scroll...</div>}\n </>\n );\n};\n\nexport const ScrollSequence = React.forwardRef<HTMLDivElement, ScrollSequenceProps>(\n (props, ref) => {\n const {\n source,\n scrollLength = '300vh',\n className = '',\n debug = false,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n fallback,\n accessibilityLabel,\n onError,\n } = props;\n\n // Check for reduced motion\n const prefersReducedMotion = React.useMemo(() => {\n if (typeof window !== 'undefined') {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n }\n return false;\n }, []);\n\n // Use ScrollSequence now acts as the convenient \"Bundle\"\n // It provides the Timeline context and renders the Canvas consumer.\n return (\n <div ref={ref} className={className} style={{ width: '100%' }}>\n <ScrollTimelineProvider scrollLength={scrollLength}>\n {prefersReducedMotion && fallback ? (\n <div style={{ position: 'sticky', top: 0, height: '100vh', width: '100%' }}>\n {fallback}\n </div>\n ) : (\n <InnerSequence \n source={source} \n debug={debug} \n memoryStrategy={memoryStrategy}\n lazyBuffer={lazyBuffer} \n fallback={fallback}\n accessibilityLabel={accessibilityLabel}\n onError={onError}\n />\n )}\n {props.children}\n </ScrollTimelineProvider>\n </div>\n );\n }\n);\n","import { useRef, useEffect, useState } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { ImageController } from '../controllers/imageController';\nimport { resolveSequence } from '../sequence/sequenceResolver';\nimport { clamp } from '../core/clamp';\nimport { useScrollTimeline } from './useScrollTimeline';\n\ninterface UseScrollSequenceParams {\n source: ScrollSequenceProps['source'];\n debugRef?: React.MutableRefObject<HTMLDivElement | null>;\n memoryStrategy?: 'eager' | 'lazy';\n lazyBuffer?: number;\n onError?: (error: Error) => void;\n}\n\n/**\n * Hook to manage image sequence in a timeline context.\n * MUST be used inside ScrollTimelineProvider.\n */\nexport function useScrollSequence({\n source,\n debugRef,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n onError,\n}: UseScrollSequenceParams) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const controllerRef = useRef<ImageController | null>(null);\n \n // Use the shared timeline\n const { subscribe } = useScrollTimeline();\n\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let active = true;\n let currentController: ImageController | null = null;\n let unsubscribeTimeline: (() => void) | null = null;\n\n const init = async () => {\n setIsLoaded(false);\n setError(null);\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n try {\n // 1. Resolve Sequence\n // Guard: source change handled by effect dep, but verify environment?\n if (typeof window === 'undefined') return;\n\n const sequence = await resolveSequence(source);\n if (!active) return;\n\n if (sequence.frames.length === 0) {\n return;\n }\n\n // 2. Setup Dimensions (Initial)\n if (typeof window !== 'undefined') {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n }\n\n // 3. Initialize Controller\n currentController = new ImageController({\n canvas,\n frames: sequence.frames,\n strategy: memoryStrategy,\n bufferSize: lazyBuffer\n });\n controllerRef.current = currentController;\n\n // 4. Subscribe to Timeline\n unsubscribeTimeline = subscribe((progress) => {\n if (!currentController) return;\n const clamped = clamp(progress);\n currentController.update(clamped);\n\n // Debug Overlay\n if (debugRef?.current) {\n const frameIndex = Math.floor(clamped * (sequence.frames.length - 1));\n debugRef.current.innerText = `Progress: ${clamped.toFixed(2)}\\nFrame: ${frameIndex + 1} / ${sequence.frames.length}`;\n }\n });\n\n if (active) setIsLoaded(true);\n\n } catch (err) {\n if (active) {\n const e = err instanceof Error ? err : new Error('Unknown initialization error');\n setError(e);\n if (onError) onError(e);\n }\n }\n };\n\n init();\n\n return () => {\n active = false;\n currentController?.destroy();\n controllerRef.current = null;\n if (unsubscribeTimeline) unsubscribeTimeline();\n };\n }, [source, memoryStrategy, lazyBuffer, subscribe]); // Re-run if source or timeline changes\n\n return {\n canvasRef,\n isLoaded,\n error\n };\n}\n","/**\n * ImageController\n * Manages canvas rendering, image loading, and frame-by-frame drawing.\n * Handles preloading and caching to minimize redraws.\n */\n\nexport interface ImageControllerConfig {\n /** HTMLCanvasElement to draw on */\n canvas: HTMLCanvasElement;\n\n /** Array of sorted frame URLs */\n frames: string[];\n\n /** Memory management strategy */\n strategy?: 'eager' | 'lazy';\n\n /** Lazy load buffer size (default 10) */\n bufferSize?: number;\n}\n\nexport class ImageController {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private frames: string[];\n private imageCache = new Map<string, HTMLImageElement>();\n private loadingPromises = new Map<string, Promise<HTMLImageElement>>();\n private currentFrameIndex = -1;\n private strategy: 'eager' | 'lazy';\n private bufferSize: number;\n\n /**\n * Create a new ImageController instance.\n *\n * @param config - Configuration object\n * @throws If canvas doesn't support 2D context\n */\n private isDestroyed = false;\n\n constructor(config: ImageControllerConfig) {\n this.canvas = config.canvas;\n this.frames = config.frames;\n this.strategy = config.strategy || 'eager';\n this.bufferSize = config.bufferSize || 10;\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context from canvas');\n }\n this.ctx = ctx;\n\n // Initial load\n if (this.strategy === 'eager') {\n this.preloadAll();\n } else {\n this.ensureFrameWindow(0);\n }\n }\n\n // ... preloadAll omitted for brevity if unchanged, but let's include for completeness if needed.\n // Actually, we need to add guards to preloadFrame, so let's check it.\n \n private preloadAll(): void {\n this.frames.forEach((_, index) => this.preloadFrame(index));\n }\n\n private ensureFrameWindow(currentIndex: number): void {\n if (this.isDestroyed) return;\n\n const radius = this.bufferSize;\n const start = Math.max(0, currentIndex - radius);\n const end = Math.min(this.frames.length - 1, currentIndex + radius);\n \n const needed = new Set<string>();\n for (let i = start; i <= end; i++) {\n needed.add(this.frames[i]);\n }\n\n // Cleanup unused frames (LRU-ish but simple Window-based)\n for (const [src] of this.imageCache) {\n if (!needed.has(src)) {\n this.imageCache.delete(src);\n // We should also cancel promises if possible, but we can't cancel a fetch/image load easily.\n // We just delete the tracking so we don't cache it when it lands.\n this.loadingPromises.delete(src);\n }\n }\n\n // Load needed\n for (let i = start; i <= end; i++) {\n void this.preloadFrame(i);\n }\n }\n\n async preloadFrame(index: number): Promise<void> {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n\n if (this.imageCache.has(src)) return;\n\n // Deduplication: Reuse existing promise if allowed\n if (!this.loadingPromises.has(src)) {\n this.loadingPromises.set(src, this.loadImage(src));\n }\n\n try {\n await this.loadingPromises.get(src);\n } catch {\n // Failed\n if (!this.isDestroyed) {\n // Silent failure\n }\n }\n }\n\n private loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n \n img.onload = () => {\n if (this.isDestroyed) return;\n \n // Critical: decode() to prevent main-thread jank during draw\n img.decode()\n .then(() => {\n if (this.isDestroyed) return;\n this.imageCache.set(src, img);\n resolve(img);\n })\n .catch(() => {\n if (this.isDestroyed) return;\n // Even if decode fails, the image might be usable\n this.imageCache.set(src, img);\n resolve(img);\n });\n };\n\n img.onerror = () => {\n if (this.isDestroyed) return;\n reject(new Error(`Failed to load image: ${src}`));\n };\n\n img.src = src;\n });\n }\n\n update(progress: number): void {\n if (this.isDestroyed || this.frames.length === 0) return;\n\n const frameIndex = Math.floor(progress * (this.frames.length - 1));\n\n if (this.strategy === 'lazy') {\n this.ensureFrameWindow(frameIndex);\n }\n\n if (frameIndex === this.currentFrameIndex) return;\n\n this.currentFrameIndex = frameIndex;\n this.drawFrame(frameIndex);\n }\n\n private drawFrame(index: number): void {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n const img = this.imageCache.get(src);\n\n if (!img) {\n // Frame not ready. Optional: Show loading spinner or keep previous frame?\n // For now, keep previous (natural behavior of canvas).\n // Or check promise\n const promise = this.loadingPromises.get(src);\n if (promise) {\n promise.then(() => {\n if (this.currentFrameIndex === index) {\n this.drawFrame(index);\n }\n }).catch(() => {}); // catch ignore\n }\n return;\n }\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n const scale = Math.min(\n this.canvas.width / img.width,\n this.canvas.height / img.height\n );\n\n const scaledWidth = img.width * scale;\n const scaledHeight = img.height * scale;\n const x = (this.canvas.width - scaledWidth) / 2;\n const y = (this.canvas.height - scaledHeight) / 2;\n\n this.ctx.drawImage(img, x, y, scaledWidth, scaledHeight);\n }\n\n setCanvasSize(width: number, height: number): void {\n if (this.isDestroyed) return;\n this.canvas.width = width;\n this.canvas.height = height;\n if (this.currentFrameIndex >= 0) {\n this.drawFrame(this.currentFrameIndex);\n }\n }\n\n destroy(): void {\n this.isDestroyed = true;\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.imageCache.clear();\n this.loadingPromises.clear();\n }\n}\n","/**\n * SequenceResolver\n * Handles intelligent frame resolution from multiple input sources:\n * - Manual frame list (frames[])\n * - Pattern generation (pattern, start, end, pad)\n * - Remote manifest (manifest URL)\n */\n\nimport type { ScrollSequenceProps, ResolvedSequence } from '../types';\n\n// Declare process for TS (avoiding @types/node dependency for just this)\ndeclare const process: { env: { NODE_ENV: string } };\n\n/**\n * Resolves frame sequence from props.\n * Prioritizes: frames > pattern > manifest\n */\n/**\n * Resolves frame sequence from props.\n * Handles 'manual', 'pattern', and 'manifest' sources.\n */\nexport async function resolveSequence(source: ScrollSequenceProps['source']): Promise<ResolvedSequence> {\n switch (source.type) {\n case 'manual':\n return processManualFrames(source.frames);\n \n case 'pattern':\n return processPatternMode(source.url, source.start ?? 1, source.end, source.pad);\n \n case 'manifest':\n return processManifestMode(source.url);\n \n default:\n return { frames: [], frameCount: 0 };\n }\n}\n\n/**\n * Mode A: Process manually provided frames\n */\nfunction processManualFrames(frames: string[]): ResolvedSequence {\n // Sort frames numerically by extracting numbers from filenames\n // Uses stable sort to preserve order for frames with no numbers or equal numbers\n const sorted = [...frames].sort((a, b) => {\n const numA = extractNumber(a);\n const numB = extractNumber(b);\n return numA - numB;\n });\n\n return {\n frames: sorted,\n frameCount: sorted.length\n };\n}\n\n/**\n * Mode B: Generate frames from pattern\n */\nfunction processPatternMode(pattern: string, start: number, end: number, pad?: number): ResolvedSequence {\n const frames: string[] = [];\n\n for (let i = start; i <= end; i++) {\n let indexStr = i.toString();\n if (pad) {\n indexStr = indexStr.padStart(pad, '0');\n }\n frames.push(pattern.replace('{index}', indexStr));\n }\n\n return {\n frames,\n frameCount: frames.length\n };\n}\n\n/**\n * Mode C: Fetch and process manifest\n */\nconst manifestCache = new Map<string, Promise<ResolvedSequence>>();\n\nasync function processManifestMode(url: string): Promise<ResolvedSequence> {\n if (manifestCache.has(url)) {\n return manifestCache.get(url)!;\n }\n\n const promise = (async () => {\n try {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: ${res.statusText}`);\n }\n \n const data = await res.json();\n \n // Check for \"frames\" array in manifest\n if (data.frames && Array.isArray(data.frames)) {\n return processManualFrames(data.frames);\n }\n \n // Check for pattern config in manifest\n if (data.pattern && typeof data.end === 'number') {\n const start = data.start ?? 1;\n const pad = data.pad;\n return processPatternMode(data.pattern, start, data.end, pad);\n }\n \n return { frames: [], frameCount: 0 };\n \n } catch (err) {\n // Remove from cache on error so retry is possible\n manifestCache.delete(url);\n throw err;\n }\n })();\n\n manifestCache.set(url, promise);\n return promise;\n}\n\n// --- Helpers ---\n\n/**\n * Extract the first number found in a filename.\n * Returns -1 if no number is found, to differentiate from 0.\n */\nfunction extractNumber(filename: string): number {\n const match = filename.match(/\\d+/);\n return match ? parseInt(match[0], 10) : -1;\n}\n\n","/**\n * Clamps a value between a minimum and maximum.\n * Default range is [0, 1], suitable for progress values.\n *\n * @param value - The value to clamp\n * @param min - Minimum value (default: 0)\n * @param max - Maximum value (default: 1)\n * @returns The clamped value\n */\nexport function clamp(value: number, min: number = 0, max: number = 1): number {\n return Math.max(min, Math.min(max, value));\n}\n","import { createContext, useContext } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\n\nexport interface ScrollTimelineContextValue {\n timeline: ScrollTimeline | null;\n // Expose current progress? No, that causes re-renders. Use subscription.\n}\n\nexport const ScrollTimelineContext = createContext<ScrollTimelineContextValue>({\n timeline: null,\n});\n\nexport function useTimelineContext() {\n return useContext(ScrollTimelineContext);\n}\n","import { ScrollTimeline, TimelineCallback } from '../core/scrollTimeline';\nimport { useTimelineContext } from './scrollTimelineContext';\n\nexport interface UseScrollTimelineResult {\n /** \n * Manual subscription to the timeline. \n * Useful for low-level DOM updates (refs) without re-rendering.\n */\n subscribe: (callback: TimelineCallback) => () => void;\n \n /** The raw timeline instance (for advanced usage) */\n timeline: ScrollTimeline | null; \n}\n\nexport function useScrollTimeline(): UseScrollTimelineResult {\n const { timeline } = useTimelineContext();\n\n const subscribe = (callback: TimelineCallback) => {\n if (!timeline) return () => {};\n return timeline.subscribe(callback);\n };\n\n return { subscribe, timeline };\n}\n","import React, { useRef, useState } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\nimport { ScrollTimelineContext } from './scrollTimelineContext';\n\nexport interface ScrollTimelineProviderProps {\n children: React.ReactNode;\n \n /** CSS height for the scroll container (e.g., \"300vh\"). */\n scrollLength?: string;\n \n className?: string;\n style?: React.CSSProperties;\n}\n\nexport function ScrollTimelineProvider({\n children,\n scrollLength = '300vh',\n className = '',\n style = {},\n}: ScrollTimelineProviderProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [timeline, setTimeline] = useState<ScrollTimeline | null>(null);\n\n // Use layout effect to ensure timeline exists before children effects run\n // SSR safe fallback: use useEffect on server\n const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\n useIsomorphicLayoutEffect(() => {\n if (typeof window === 'undefined') return;\n if (!containerRef.current) return;\n\n // Future-proof: factory could be passed via props\n const instance = new ScrollTimeline(containerRef.current);\n \n // We do NOT call start() anymore, it starts on subscription\n // instance.start(); \n \n setTimeline(instance);\n\n return () => {\n instance.destroy();\n setTimeline(null);\n };\n }, []); // Dependencies? strict empty for one-time setup\n\n const containerStyle: React.CSSProperties = {\n height: scrollLength,\n position: 'relative',\n width: '100%',\n ...style,\n };\n\n const stickyWrapperStyle: React.CSSProperties = {\n position: 'sticky',\n top: 0,\n height: '100vh',\n width: '100%',\n overflow: 'hidden',\n };\n\n // Memoize context value to prevent unnecessary re-renders of consumers\n // when Parent component renders but timeline instance hasn't changed.\n const contextValue = React.useMemo(() => ({ timeline }), [timeline]);\n\n return (\n <ScrollTimelineContext.Provider value={contextValue}>\n <div \n ref={containerRef} \n className={className} \n style={containerStyle}\n >\n <div style={stickyWrapperStyle}>\n {children}\n </div>\n </div>\n </ScrollTimelineContext.Provider>\n );\n}\n","/**\n * ScrollLoopManager\n * \n * Singleton class to manage a single requestAnimationFrame loop\n * for all ScrollTimeline instances. This prevents multiple RAF\n * callbacks from piling up and degrading performance.\n */\n\ntype LoopCallback = () => void;\n\nexport class ScrollLoopManager {\n private static instance: ScrollLoopManager;\n private callbacks = new Set<LoopCallback>();\n private rafId: number | null = null;\n private isActive = false;\n\n private constructor() {}\n\n public static getInstance(): ScrollLoopManager {\n if (!ScrollLoopManager.instance) {\n ScrollLoopManager.instance = new ScrollLoopManager();\n }\n return ScrollLoopManager.instance;\n }\n\n /**\n * Register a callback to be called on every animation frame.\n */\n public register(callback: LoopCallback): void {\n if (this.callbacks.has(callback)) return;\n \n this.callbacks.add(callback);\n \n // Start loop if this is the first subscriber\n if (this.callbacks.size === 1) {\n this.start();\n }\n }\n\n /**\n * Unregister a callback.\n */\n public unregister(callback: LoopCallback): void {\n this.callbacks.delete(callback);\n\n // Stop loop if no subscribers left\n if (this.callbacks.size === 0) {\n this.stop();\n }\n }\n\n private start(): void {\n if (this.isActive) return;\n this.isActive = true;\n \n // Ensure we are in a browser environment\n if (typeof window !== 'undefined') {\n this.tick();\n }\n }\n\n private stop(): void {\n this.isActive = false;\n if (this.rafId !== null && typeof window !== 'undefined') {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private tick = (): void => {\n if (!this.isActive) return;\n\n // Execute all registered callbacks\n this.callbacks.forEach(cb => {\n try {\n cb();\n } catch (e) {\n // Silent catch to prevent loop crash\n }\n });\n\n this.rafId = requestAnimationFrame(this.tick);\n };\n}\n","/**\n * Global Constants for React Scroll Media\n */\n\n// Scroll Logic\nexport const SCROLL_THRESHOLD = 0.0001; // Minimum progress change to trigger update\nexport const DEFAULT_SCROLL_LENGTH = '300vh';\n\n// Memory Management\nexport const DEFAULT_LAZY_BUFFER = 10;\nexport const MAX_CACHE_SIZE = 50; // Fallback max size if not dynamic\n\n// Sequences\nexport const DEFAULT_PAD_LENGTH = 0; // Default padding for image numbering\n\n// Styles & Layout\nexport const DEFAULT_FALLBACK_COLOR = '#ccc';\n","import { ScrollLoopManager } from './loopManager';\nimport { SCROLL_THRESHOLD } from '../constants';\n\nexport type TimelineCallback = (progress: number) => void;\n\nexport class ScrollTimeline {\n private container: Element;\n private subscribers = new Set<TimelineCallback>();\n private currentProgress = 0;\n \n // Caching for performance\n private cachedRect: DOMRect | null = null;\n private cachedScrollParent: Element | Window | null = null;\n private cachedScrollParentRect: DOMRect | null = null;\n private cachedViewportHeight = 0;\n private cachedOffsetTop = 0;\n private isLayoutDirty = true;\n private resizeObserver: ResizeObserver | null = null;\n\n public readonly id = typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n constructor(container: Element) {\n this.container = container;\n \n if (typeof window !== 'undefined') {\n // Invalidate cache on resize\n this.resizeObserver = new ResizeObserver(() => {\n this.isLayoutDirty = true;\n });\n this.resizeObserver.observe(this.container);\n if (document.body) {\n this.resizeObserver.observe(document.body);\n }\n \n // Also listen to global resize\n window.addEventListener('resize', this.onWindowResize);\n }\n }\n\n private onWindowResize = () => {\n this.isLayoutDirty = true;\n };\n\n /**\n * Subscribe to progress updates.\n * Returns an unsubscribe function.\n */\n subscribe(callback: TimelineCallback): () => void {\n this.subscribers.add(callback);\n \n // Immediately call with current progress for initialization\n try {\n callback(this.currentProgress);\n } catch (e) {\n // Silent\n }\n\n // Register with unique LoopManager if we have subscribers\n if (this.subscribers.size === 1) {\n ScrollLoopManager.getInstance().register(this.tick);\n }\n \n return () => {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n };\n }\n\n unsubscribe(callback: TimelineCallback): void {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n }\n\n /**\n * Start is now handled by LoopManager via subscriptions\n * Deprecated but kept for API stability if needed.\n */\n start(): void {\n // No-op, managed by subscriptions\n }\n\n stop(): void {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n\n private tick = (): void => {\n // Calculate Progress\n const progress = this.calculateProgress();\n\n // Notify if changed significantly (using threshold constant)\n if (Math.abs(progress - this.currentProgress) > SCROLL_THRESHOLD) {\n this.currentProgress = progress;\n this.notify();\n }\n };\n\n private notify() {\n this.subscribers.forEach((cb) => {\n try {\n cb(this.currentProgress);\n } catch (e) {\n // Silent\n }\n });\n }\n\n private updateCache() {\n if (!this.isLayoutDirty && this.cachedRect) return;\n\n this.cachedRect = this.container.getBoundingClientRect();\n \n if (!this.cachedScrollParent) {\n this.cachedScrollParent = this.getScrollParent(this.container);\n }\n\n if (this.cachedScrollParent instanceof Element) {\n this.cachedScrollParentRect = this.cachedScrollParent.getBoundingClientRect();\n this.cachedViewportHeight = this.cachedScrollParentRect.height;\n this.cachedOffsetTop = this.cachedScrollParentRect.top;\n } else if (typeof window !== 'undefined') {\n this.cachedViewportHeight = window.innerHeight;\n this.cachedOffsetTop = 0;\n }\n\n this.isLayoutDirty = false;\n }\n\n private calculateProgress(): number {\n if (this.isLayoutDirty || !this.cachedRect) {\n this.updateCache();\n }\n\n const currentRect = this.container.getBoundingClientRect();\n const scrollDist = (this.cachedRect?.height || currentRect.height) - this.cachedViewportHeight;\n\n // Guard: Zero Height / Division by Zero\n if (scrollDist <= 0) return 1;\n\n const relativeTop = currentRect.top - this.cachedOffsetTop;\n const rawProgress = -relativeTop / scrollDist;\n \n const clamped = Math.min(Math.max(rawProgress, 0), 1);\n \n // Round to 6 decimals to prevent micro-drift\n return Math.round(clamped * 1000000) / 1000000;\n }\n\n private getScrollParent(node: Element): Element | Window {\n if (typeof window === 'undefined') return node; \n\n let current = node.parentElement;\n while (current) {\n const style = getComputedStyle(current);\n if (['auto', 'scroll'].includes(style.overflowY)) {\n return current;\n }\n current = current.parentElement;\n }\n return window;\n }\n\n destroy() {\n this.subscribers.clear();\n ScrollLoopManager.getInstance().unregister(this.tick);\n \n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n if (typeof window !== 'undefined') {\n window.removeEventListener('resize', this.onWindowResize);\n }\n }\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollTextProps {\n children: React.ReactNode;\n /** Progress start (0-1) where ENTRANCE animation begins */\n start?: number;\n /** Progress end (0-1) where ENTRANCE animation ends */\n end?: number;\n \n /** Progress start (0-1) where EXIT animation begins. If omitted, element stays visible. */\n exitStart?: number;\n /** Progress end (0-1) where EXIT animation ends */\n exitEnd?: number;\n\n /** Initial opacity */\n initialOpacity?: number;\n /** Target opacity (when entered) */\n targetOpacity?: number;\n /** Final opacity (after exit) */\n finalOpacity?: number;\n\n /** Y-axis translation range in pixels (e.g., 50 means move down 50px) */\n translateY?: number;\n \n style?: React.CSSProperties;\n className?: string;\n}\n\nexport function ScrollText({\n children,\n start = 0,\n end = 0.2,\n exitStart,\n exitEnd,\n initialOpacity = 0,\n targetOpacity = 1,\n finalOpacity = 0,\n translateY = 50,\n style,\n className,\n}: ScrollTextProps) {\n const ref = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n useEffect(() => {\n // Subscribe to updates\n if (typeof window === 'undefined') return;\n\n const unsubscribe = subscribe((progress) => {\n if (!ref.current) return;\n\n // Check for reduced motion preference\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n // If reduced motion is preferred, disable translation (keep opacity fade)\n const effectiveTranslateY = prefersReducedMotion ? 0 : translateY;\n\n let opacity = initialOpacity;\n let currentY = effectiveTranslateY;\n\n // 1. Entrance Phase\n if (progress < start) {\n opacity = initialOpacity;\n currentY = effectiveTranslateY;\n } else if (progress >= start && progress <= end) {\n const local = (progress - start) / (end - start);\n opacity = initialOpacity + (targetOpacity - initialOpacity) * local;\n currentY = effectiveTranslateY * (1 - local);\n } \n // 2. Hold Phase\n else if (!exitStart || progress < exitStart) {\n opacity = targetOpacity;\n currentY = 0;\n }\n // 3. Exit Phase\n else if (exitStart && exitEnd && progress >= exitStart && progress <= exitEnd) {\n const local = (progress - exitStart) / (exitEnd - exitStart);\n opacity = targetOpacity + (finalOpacity - targetOpacity) * local;\n // Move from 0 -> -translateY (or 0 if reduced motion)\n currentY = -effectiveTranslateY * local; \n }\n // 4. Final Phase\n else {\n opacity = finalOpacity;\n currentY = -effectiveTranslateY;\n }\n\n // Apply styles\n ref.current.style.opacity = opacity.toFixed(3);\n ref.current.style.transform = `translateY(${currentY}px)`;\n });\n\n return unsubscribe;\n }, [subscribe, start, end, exitStart, exitEnd, initialOpacity, targetOpacity, finalOpacity, translateY]);\n\n return (\n <div \n ref={ref} \n className={className}\n style={{\n opacity: initialOpacity, \n transform: `translateY(${translateY}px)`,\n transition: 'none', // Critical: no CSS transition fighting JS\n willChange: 'opacity, transform',\n ...style\n }}\n >\n {children}\n </div>\n );\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollWordRevealProps {\n text: string;\n /** Progress start (0-1) */\n start?: number;\n /** Progress end (0-1) */\n end?: number;\n className?: string;\n style?: React.CSSProperties;\n /** Stagger delay factor (not used in pure scroll map, simpler logic: map word index to sub-progress) */\n}\n\nexport function ScrollWordReveal({\n text,\n start = 0,\n end = 1,\n className,\n style\n}: ScrollWordRevealProps) {\n // We cannot create refs in loop dynamically in top level easily without array.\n // Better to have one parent ref and querySelectorAll children, OR use callback refs.\n const containerRef = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n // Split words\n const words = text.split(/\\s+/);\n\n useEffect(() => {\n const unsubscribe = subscribe((globalProgress) => {\n if (!containerRef.current) return;\n const spans = containerRef.current.children;\n \n // Map global progress to local range [start, end]\n let localProgress = 0;\n if (globalProgress <= start) localProgress = 0;\n else if (globalProgress >= end) localProgress = 1;\n else localProgress = (globalProgress - start) / (end - start);\n\n // Calculate which word should be visible\n const totalWords = spans.length;\n const progressPerWord = 1 / totalWords;\n\n for (let i = 0; i < totalWords; i++) {\n const span = spans[i] as HTMLElement;\n \n // Each word fades in during its \"slot\"\n // Word 0: 0 -> 0.1\n // Word 1: 0.1 -> 0.2\n const wordStart = i * progressPerWord;\n const wordEnd = (i + 1) * progressPerWord;\n \n let wordOpacity = 0;\n if (localProgress >= wordEnd) {\n wordOpacity = 1;\n } else if (localProgress <= wordStart) {\n wordOpacity = 0.1; // faint visibility initially? or 0\n } else {\n // Interpolate\n wordOpacity = 0.1 + 0.9 * ((localProgress - wordStart) / (wordEnd - wordStart));\n }\n \n span.style.opacity = wordOpacity.toFixed(2);\n // Optional: translate Y too?\n const translate = (1 - wordOpacity) * 10;\n span.style.transform = `translateY(${translate}px)`;\n }\n });\n\n return unsubscribe;\n }, [subscribe, start, end]);\n\n return (\n <div ref={containerRef} className={className} style={{ ...style, display: 'flex', flexWrap: 'wrap', gap: '0.25em' }}>\n {words.map((word, i) => (\n <span \n key={i} \n style={{ \n opacity: 0.1, \n transform: 'translateY(10px)',\n transition: 'none',\n willChange: 'opacity, transform'\n }}\n >\n {word}\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","React","import_jsx_runtime","React","import_react","import_jsx_runtime","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/react/ScrollSequence.tsx","../src/react/useScrollSequence.ts","../src/controllers/imageController.ts","../src/sequence/sequenceResolver.ts","../src/core/clamp.ts","../src/react/scrollTimelineContext.ts","../src/react/useScrollTimeline.ts","../src/react/ScrollTimelineProvider.tsx","../src/core/loopManager.ts","../src/constants.ts","../src/core/scrollTimeline.ts","../src/react/ScrollText.tsx","../src/react/ScrollWordReveal.tsx"],"sourcesContent":["/**\n * react-scroll-media\n * Production-ready scroll-driven image sequence rendering component\n */\n\n// Public exports\n// Public exports\nexport { ScrollSequence } from './react/ScrollSequence';\nexport { useScrollSequence } from './react/useScrollSequence';\nexport { ScrollTimelineProvider } from './react/ScrollTimelineProvider';\nexport { ScrollText } from './react/ScrollText';\nexport { ScrollWordReveal } from './react/ScrollWordReveal';\nexport { useScrollTimeline } from './react/useScrollTimeline';\n\n// Types\nexport type { ScrollSequenceProps, ResolvedSequence, ScrollProgress } from './types';\n\n// Core utilities (advanced users)\nexport { ScrollTimeline } from './core/scrollTimeline';\nexport { clamp } from './core/clamp';\n\n// Sequence utilities (advanced users)\nexport { resolveSequence } from './sequence/sequenceResolver';\n\n// Controllers (advanced users)\nexport { ImageController } from './controllers/imageController';\nexport type { ImageControllerConfig } from './controllers/imageController';\n","import React, { useRef } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { useScrollSequence } from './useScrollSequence';\nimport { ScrollTimelineProvider } from './ScrollTimelineProvider';\n\n\ninterface InnerSequenceProps {\n source: ScrollSequenceProps['source'];\n debug: boolean;\n memoryStrategy: ScrollSequenceProps['memoryStrategy'];\n lazyBuffer?: number;\n accessibilityLabel?: string;\n fit?: React.CSSProperties['objectFit']; // Add fit prop here\n fallback?: React.ReactNode;\n onError?: (error: Error) => void;\n}\n\nconst InnerSequence: React.FC<InnerSequenceProps> = ({\n source,\n debug,\n memoryStrategy,\n lazyBuffer,\n accessibilityLabel = \"Scroll sequence\",\n fit = 'cover', // Default to cover\n fallback,\n onError\n}) => {\n const debugRef = useRef<HTMLDivElement>(null);\n const { canvasRef, isLoaded } = useScrollSequence({\n source,\n debugRef,\n memoryStrategy,\n lazyBuffer,\n onError\n });\n\n // Fallback logic could be handled here or by parent.\n // If we handle it here, we overlay it?\n // Actually, canvas opacity handles the fade-in.\n // Use fallback if provided and not loaded.\n\n const canvasStyle: React.CSSProperties = {\n display: 'block',\n width: '100%',\n height: '100%',\n objectFit: fit, // Use the prop\n opacity: isLoaded ? 1 : 0,\n transition: 'opacity 0.2s ease-in',\n };\n\n const debugStyle: React.CSSProperties = {\n position: 'absolute',\n top: '10px',\n left: '10px',\n background: 'rgba(0, 0, 0, 0.7)',\n color: '#00ff00',\n padding: '8px',\n borderRadius: '4px',\n fontFamily: 'monospace',\n fontSize: '12px',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n zIndex: 9999,\n };\n\n return (\n <>\n {/* Render fallback behind canvas, or replace? \n If replace, we might loose the canvas ref init?\n Better to render both and cross-fade or just hide fallback when loaded.\n */}\n {!isLoaded && fallback && (\n <div style={{ position: 'absolute', inset: 0, zIndex: 1 }}>\n {fallback}\n </div>\n )}\n\n <canvas\n ref={canvasRef}\n style={canvasStyle}\n role=\"img\"\n aria-label={accessibilityLabel}\n />\n {debug && <div ref={debugRef} style={debugStyle}>Waiting for scroll...</div>}\n </>\n );\n};\n\nexport const ScrollSequence = React.forwardRef<HTMLDivElement, ScrollSequenceProps>(\n (props, ref) => {\n const {\n source,\n scrollLength = '300vh',\n className = '',\n debug = false,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n fallback,\n fit = 'cover', // Default here too\n accessibilityLabel,\n onError,\n children // Extract children\n } = props;\n\n // Check for reduced motion\n // ... logic for reduced motion could be here or inside hook\n\n return (\n <ScrollTimelineProvider\n scrollLength={scrollLength}\n className={className}\n style={{ position: 'relative' }} // Ensure container is relative\n containerRef={ref as React.RefObject<HTMLDivElement>}\n >\n <InnerSequence\n source={source}\n debug={debug}\n memoryStrategy={memoryStrategy}\n lazyBuffer={lazyBuffer}\n fallback={fallback}\n accessibilityLabel={accessibilityLabel}\n onError={onError}\n fit={fit as any} // Pass fit prop\n />\n {/* Render children ON TOP of canvas */}\n <div style={{ position: 'absolute', inset: 0, zIndex: 10, pointerEvents: 'none' }}>\n {children}\n </div>\n </ScrollTimelineProvider>\n );\n }\n);\n","import { useRef, useEffect, useState } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { ImageController } from '../controllers/imageController';\nimport { resolveSequence } from '../sequence/sequenceResolver';\nimport { clamp } from '../core/clamp';\nimport { useScrollTimeline } from './useScrollTimeline';\n\ninterface UseScrollSequenceParams {\n source: ScrollSequenceProps['source'];\n debugRef?: React.MutableRefObject<HTMLDivElement | null>;\n memoryStrategy?: 'eager' | 'lazy';\n lazyBuffer?: number;\n onError?: (error: Error) => void;\n}\n\n/**\n * Hook to manage image sequence in a timeline context.\n * MUST be used inside ScrollTimelineProvider.\n */\nexport function useScrollSequence({\n source,\n debugRef,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n onError,\n}: UseScrollSequenceParams) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const controllerRef = useRef<ImageController | null>(null);\n \n // Use the shared timeline\n const { subscribe } = useScrollTimeline();\n\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let active = true;\n let currentController: ImageController | null = null;\n let unsubscribeTimeline: (() => void) | null = null;\n\n const init = async () => {\n setIsLoaded(false);\n setError(null);\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n try {\n // 1. Resolve Sequence\n // Guard: source change handled by effect dep, but verify environment?\n if (typeof window === 'undefined') return;\n\n const sequence = await resolveSequence(source);\n if (!active) return;\n\n if (sequence.frames.length === 0) {\n return;\n }\n\n // 2. Setup Dimensions (Initial)\n if (typeof window !== 'undefined') {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n }\n\n // 3. Initialize Controller\n currentController = new ImageController({\n canvas,\n frames: sequence.frames,\n strategy: memoryStrategy,\n bufferSize: lazyBuffer\n });\n controllerRef.current = currentController;\n\n // 4. Subscribe to Timeline\n unsubscribeTimeline = subscribe((progress) => {\n if (!currentController) return;\n const clamped = clamp(progress);\n currentController.update(clamped);\n\n // Debug Overlay\n if (debugRef?.current) {\n const frameIndex = Math.floor(clamped * (sequence.frames.length - 1));\n debugRef.current.innerText = `Progress: ${clamped.toFixed(2)}\\nFrame: ${frameIndex + 1} / ${sequence.frames.length}`;\n }\n });\n\n if (active) setIsLoaded(true);\n\n } catch (err) {\n if (active) {\n const e = err instanceof Error ? err : new Error('Unknown initialization error');\n setError(e);\n if (onError) onError(e);\n }\n }\n };\n\n init();\n\n return () => {\n active = false;\n currentController?.destroy();\n controllerRef.current = null;\n if (unsubscribeTimeline) unsubscribeTimeline();\n };\n }, [source, memoryStrategy, lazyBuffer, subscribe]); // Re-run if source or timeline changes\n\n return {\n canvasRef,\n isLoaded,\n error\n };\n}\n","/**\n * ImageController\n * Manages canvas rendering, image loading, and frame-by-frame drawing.\n * Handles preloading and caching to minimize redraws.\n */\n\nexport interface ImageControllerConfig {\n /** HTMLCanvasElement to draw on */\n canvas: HTMLCanvasElement;\n\n /** Array of sorted frame URLs */\n frames: string[];\n\n /** Memory management strategy */\n strategy?: 'eager' | 'lazy';\n\n /** Lazy load buffer size (default 10) */\n bufferSize?: number;\n}\n\nexport class ImageController {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private frames: string[];\n private imageCache = new Map<string, HTMLImageElement>();\n private loadingPromises = new Map<string, Promise<HTMLImageElement>>();\n private currentFrameIndex = -1;\n private strategy: 'eager' | 'lazy';\n private bufferSize: number;\n\n /**\n * Create a new ImageController instance.\n *\n * @param config - Configuration object\n * @throws If canvas doesn't support 2D context\n */\n private isDestroyed = false;\n\n constructor(config: ImageControllerConfig) {\n this.canvas = config.canvas;\n this.frames = config.frames;\n this.strategy = config.strategy || 'eager';\n this.bufferSize = config.bufferSize || 10;\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context from canvas');\n }\n this.ctx = ctx;\n\n // Initial load\n if (this.strategy === 'eager') {\n this.preloadAll();\n } else {\n this.ensureFrameWindow(0);\n }\n }\n\n // ... preloadAll omitted for brevity if unchanged, but let's include for completeness if needed.\n // Actually, we need to add guards to preloadFrame, so let's check it.\n \n private preloadAll(): void {\n this.frames.forEach((_, index) => this.preloadFrame(index));\n }\n\n private ensureFrameWindow(currentIndex: number): void {\n if (this.isDestroyed) return;\n\n const radius = this.bufferSize;\n const start = Math.max(0, currentIndex - radius);\n const end = Math.min(this.frames.length - 1, currentIndex + radius);\n \n const needed = new Set<string>();\n for (let i = start; i <= end; i++) {\n needed.add(this.frames[i]);\n }\n\n // Cleanup unused frames (LRU-ish but simple Window-based)\n for (const [src] of this.imageCache) {\n if (!needed.has(src)) {\n this.imageCache.delete(src);\n // We should also cancel promises if possible, but we can't cancel a fetch/image load easily.\n // We just delete the tracking so we don't cache it when it lands.\n this.loadingPromises.delete(src);\n }\n }\n\n // Load needed\n for (let i = start; i <= end; i++) {\n void this.preloadFrame(i);\n }\n }\n\n async preloadFrame(index: number): Promise<void> {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n\n if (this.imageCache.has(src)) return;\n\n // Deduplication: Reuse existing promise if allowed\n if (!this.loadingPromises.has(src)) {\n this.loadingPromises.set(src, this.loadImage(src));\n }\n\n try {\n await this.loadingPromises.get(src);\n } catch {\n // Failed\n if (!this.isDestroyed) {\n // Silent failure\n }\n }\n }\n\n private loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n \n img.onload = () => {\n if (this.isDestroyed) return;\n \n // Critical: decode() to prevent main-thread jank during draw\n img.decode()\n .then(() => {\n if (this.isDestroyed) return;\n this.imageCache.set(src, img);\n resolve(img);\n })\n .catch(() => {\n if (this.isDestroyed) return;\n // Even if decode fails, the image might be usable\n this.imageCache.set(src, img);\n resolve(img);\n });\n };\n\n img.onerror = () => {\n if (this.isDestroyed) return;\n reject(new Error(`Failed to load image: ${src}`));\n };\n\n img.src = src;\n });\n }\n\n update(progress: number): void {\n if (this.isDestroyed || this.frames.length === 0) return;\n\n const frameIndex = Math.floor(progress * (this.frames.length - 1));\n\n if (this.strategy === 'lazy') {\n this.ensureFrameWindow(frameIndex);\n }\n\n if (frameIndex === this.currentFrameIndex) return;\n\n this.currentFrameIndex = frameIndex;\n this.drawFrame(frameIndex);\n }\n\n private drawFrame(index: number): void {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n const img = this.imageCache.get(src);\n\n if (!img) {\n // Frame not ready. Optional: Show loading spinner or keep previous frame?\n // For now, keep previous (natural behavior of canvas).\n // Or check promise\n const promise = this.loadingPromises.get(src);\n if (promise) {\n promise.then(() => {\n if (this.currentFrameIndex === index) {\n this.drawFrame(index);\n }\n }).catch(() => {}); // catch ignore\n }\n return;\n }\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n const scale = Math.min(\n this.canvas.width / img.width,\n this.canvas.height / img.height\n );\n\n const scaledWidth = img.width * scale;\n const scaledHeight = img.height * scale;\n const x = (this.canvas.width - scaledWidth) / 2;\n const y = (this.canvas.height - scaledHeight) / 2;\n\n this.ctx.drawImage(img, x, y, scaledWidth, scaledHeight);\n }\n\n setCanvasSize(width: number, height: number): void {\n if (this.isDestroyed) return;\n this.canvas.width = width;\n this.canvas.height = height;\n if (this.currentFrameIndex >= 0) {\n this.drawFrame(this.currentFrameIndex);\n }\n }\n\n destroy(): void {\n this.isDestroyed = true;\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.imageCache.clear();\n this.loadingPromises.clear();\n }\n}\n","/**\n * SequenceResolver\n * Handles intelligent frame resolution from multiple input sources:\n * - Manual frame list (frames[])\n * - Pattern generation (pattern, start, end, pad)\n * - Remote manifest (manifest URL)\n */\n\nimport type { ScrollSequenceProps, ResolvedSequence } from '../types';\n\n// Declare process for TS (avoiding @types/node dependency for just this)\ndeclare const process: { env: { NODE_ENV: string } };\n\n/**\n * Resolves frame sequence from props.\n * Prioritizes: frames > pattern > manifest\n */\n/**\n * Resolves frame sequence from props.\n * Handles 'manual', 'pattern', and 'manifest' sources.\n */\nexport async function resolveSequence(source: ScrollSequenceProps['source']): Promise<ResolvedSequence> {\n switch (source.type) {\n case 'manual':\n return processManualFrames(source.frames);\n \n case 'pattern':\n return processPatternMode(source.url, source.start ?? 1, source.end, source.pad);\n \n case 'manifest':\n return processManifestMode(source.url);\n \n default:\n return { frames: [], frameCount: 0 };\n }\n}\n\n/**\n * Mode A: Process manually provided frames\n */\nfunction processManualFrames(frames: string[]): ResolvedSequence {\n // Sort frames numerically by extracting numbers from filenames\n // Uses stable sort to preserve order for frames with no numbers or equal numbers\n const sorted = [...frames].sort((a, b) => {\n const numA = extractNumber(a);\n const numB = extractNumber(b);\n return numA - numB;\n });\n\n return {\n frames: sorted,\n frameCount: sorted.length\n };\n}\n\n/**\n * Mode B: Generate frames from pattern\n */\nfunction processPatternMode(pattern: string, start: number, end: number, pad?: number): ResolvedSequence {\n const frames: string[] = [];\n\n for (let i = start; i <= end; i++) {\n let indexStr = i.toString();\n if (pad) {\n indexStr = indexStr.padStart(pad, '0');\n }\n frames.push(pattern.replace('{index}', indexStr));\n }\n\n return {\n frames,\n frameCount: frames.length\n };\n}\n\n/**\n * Mode C: Fetch and process manifest\n */\nconst manifestCache = new Map<string, Promise<ResolvedSequence>>();\n\nasync function processManifestMode(url: string): Promise<ResolvedSequence> {\n if (manifestCache.has(url)) {\n return manifestCache.get(url)!;\n }\n\n const promise = (async () => {\n try {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: ${res.statusText}`);\n }\n \n const data = await res.json();\n \n // Check for \"frames\" array in manifest\n if (data.frames && Array.isArray(data.frames)) {\n return processManualFrames(data.frames);\n }\n \n // Check for pattern config in manifest\n if (data.pattern && typeof data.end === 'number') {\n const start = data.start ?? 1;\n const pad = data.pad;\n return processPatternMode(data.pattern, start, data.end, pad);\n }\n \n return { frames: [], frameCount: 0 };\n \n } catch (err) {\n // Remove from cache on error so retry is possible\n manifestCache.delete(url);\n throw err;\n }\n })();\n\n manifestCache.set(url, promise);\n return promise;\n}\n\n// --- Helpers ---\n\n/**\n * Extract the first number found in a filename.\n * Returns -1 if no number is found, to differentiate from 0.\n */\nfunction extractNumber(filename: string): number {\n const match = filename.match(/\\d+/);\n return match ? parseInt(match[0], 10) : -1;\n}\n\n","/**\n * Clamps a value between a minimum and maximum.\n * Default range is [0, 1], suitable for progress values.\n *\n * @param value - The value to clamp\n * @param min - Minimum value (default: 0)\n * @param max - Maximum value (default: 1)\n * @returns The clamped value\n */\nexport function clamp(value: number, min: number = 0, max: number = 1): number {\n return Math.max(min, Math.min(max, value));\n}\n","import { createContext, useContext } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\n\nexport interface ScrollTimelineContextValue {\n timeline: ScrollTimeline | null;\n // Expose current progress? No, that causes re-renders. Use subscription.\n}\n\nexport const ScrollTimelineContext = createContext<ScrollTimelineContextValue>({\n timeline: null,\n});\n\nexport function useTimelineContext() {\n return useContext(ScrollTimelineContext);\n}\n","import { ScrollTimeline, TimelineCallback } from '../core/scrollTimeline';\nimport { useTimelineContext } from './scrollTimelineContext';\n\nexport interface UseScrollTimelineResult {\n /** \n * Manual subscription to the timeline. \n * Useful for low-level DOM updates (refs) without re-rendering.\n */\n subscribe: (callback: TimelineCallback) => () => void;\n \n /** The raw timeline instance (for advanced usage) */\n timeline: ScrollTimeline | null; \n}\n\nexport function useScrollTimeline(): UseScrollTimelineResult {\n const { timeline } = useTimelineContext();\n\n const subscribe = (callback: TimelineCallback) => {\n if (!timeline) return () => {};\n return timeline.subscribe(callback);\n };\n\n return { subscribe, timeline };\n}\n","import React, { useRef, useState } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\nimport { ScrollTimelineContext } from './scrollTimelineContext';\n\nexport interface ScrollTimelineProviderProps {\n children: React.ReactNode;\n\n /** CSS height for the scroll container (e.g., \"300vh\"). */\n scrollLength?: string;\n\n\n className?: string;\n style?: React.CSSProperties;\n /** Optional ref for the container element. */\n containerRef?: React.RefObject<HTMLDivElement>;\n}\n\nexport function ScrollTimelineProvider({\n children,\n scrollLength = '300vh',\n className = '',\n style = {},\n containerRef: externalRef,\n}: ScrollTimelineProviderProps) {\n const internalRef = useRef<HTMLDivElement>(null);\n const containerRef = externalRef || internalRef;\n const [timeline, setTimeline] = useState<ScrollTimeline | null>(null);\n\n // Use layout effect to ensure timeline exists before children effects run\n // SSR safe fallback: use useEffect on server\n const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\n useIsomorphicLayoutEffect(() => {\n if (typeof window === 'undefined') return;\n if (!containerRef.current) return;\n\n // Future-proof: factory could be passed via props\n const instance = new ScrollTimeline(containerRef.current);\n\n // We do NOT call start() anymore, it starts on subscription\n // instance.start(); \n\n setTimeline(instance);\n\n return () => {\n instance.destroy();\n setTimeline(null);\n };\n }, []); // Dependencies? strict empty for one-time setup\n\n const containerStyle: React.CSSProperties = {\n height: scrollLength,\n position: 'relative',\n width: '100%',\n ...style,\n };\n\n const stickyWrapperStyle: React.CSSProperties = {\n position: 'sticky',\n top: 0,\n height: '100vh',\n width: '100%',\n overflow: 'hidden',\n };\n\n // Memoize context value to prevent unnecessary re-renders of consumers\n // when Parent component renders but timeline instance hasn't changed.\n const contextValue = React.useMemo(() => ({ timeline }), [timeline]);\n\n return (\n <ScrollTimelineContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n className={className}\n style={containerStyle}\n >\n <div style={stickyWrapperStyle}>\n {children}\n </div>\n </div>\n </ScrollTimelineContext.Provider>\n );\n}\n","/**\n * ScrollLoopManager\n * \n * Singleton class to manage a single requestAnimationFrame loop\n * for all ScrollTimeline instances. This prevents multiple RAF\n * callbacks from piling up and degrading performance.\n */\n\ntype LoopCallback = () => void;\n\nexport class ScrollLoopManager {\n private static instance: ScrollLoopManager;\n private callbacks = new Set<LoopCallback>();\n private rafId: number | null = null;\n private isActive = false;\n\n private constructor() {}\n\n public static getInstance(): ScrollLoopManager {\n if (!ScrollLoopManager.instance) {\n ScrollLoopManager.instance = new ScrollLoopManager();\n }\n return ScrollLoopManager.instance;\n }\n\n /**\n * Register a callback to be called on every animation frame.\n */\n public register(callback: LoopCallback): void {\n if (this.callbacks.has(callback)) return;\n \n this.callbacks.add(callback);\n \n // Start loop if this is the first subscriber\n if (this.callbacks.size === 1) {\n this.start();\n }\n }\n\n /**\n * Unregister a callback.\n */\n public unregister(callback: LoopCallback): void {\n this.callbacks.delete(callback);\n\n // Stop loop if no subscribers left\n if (this.callbacks.size === 0) {\n this.stop();\n }\n }\n\n private start(): void {\n if (this.isActive) return;\n this.isActive = true;\n \n // Ensure we are in a browser environment\n if (typeof window !== 'undefined') {\n this.tick();\n }\n }\n\n private stop(): void {\n this.isActive = false;\n if (this.rafId !== null && typeof window !== 'undefined') {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private tick = (): void => {\n if (!this.isActive) return;\n\n // Execute all registered callbacks\n this.callbacks.forEach(cb => {\n try {\n cb();\n } catch (e) {\n // Silent catch to prevent loop crash\n }\n });\n\n this.rafId = requestAnimationFrame(this.tick);\n };\n}\n","/**\n * Global Constants for React Scroll Media\n */\n\n// Scroll Logic\nexport const SCROLL_THRESHOLD = 0.0001; // Minimum progress change to trigger update\nexport const DEFAULT_SCROLL_LENGTH = '300vh';\n\n// Memory Management\nexport const DEFAULT_LAZY_BUFFER = 10;\nexport const MAX_CACHE_SIZE = 50; // Fallback max size if not dynamic\n\n// Sequences\nexport const DEFAULT_PAD_LENGTH = 0; // Default padding for image numbering\n\n// Styles & Layout\nexport const DEFAULT_FALLBACK_COLOR = '#ccc';\n","import { ScrollLoopManager } from './loopManager';\nimport { SCROLL_THRESHOLD } from '../constants';\n\nexport type TimelineCallback = (progress: number) => void;\n\nexport class ScrollTimeline {\n private container: Element;\n private subscribers = new Set<TimelineCallback>();\n private currentProgress = 0;\n \n // Caching for performance\n private cachedRect: DOMRect | null = null;\n private cachedScrollParent: Element | Window | null = null;\n private cachedScrollParentRect: DOMRect | null = null;\n private cachedViewportHeight = 0;\n private cachedOffsetTop = 0;\n private isLayoutDirty = true;\n private resizeObserver: ResizeObserver | null = null;\n\n public readonly id = typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n constructor(container: Element) {\n this.container = container;\n \n if (typeof window !== 'undefined') {\n // Invalidate cache on resize\n this.resizeObserver = new ResizeObserver(() => {\n this.isLayoutDirty = true;\n });\n this.resizeObserver.observe(this.container);\n if (document.body) {\n this.resizeObserver.observe(document.body);\n }\n \n // Also listen to global resize\n window.addEventListener('resize', this.onWindowResize);\n }\n }\n\n private onWindowResize = () => {\n this.isLayoutDirty = true;\n };\n\n /**\n * Subscribe to progress updates.\n * Returns an unsubscribe function.\n */\n subscribe(callback: TimelineCallback): () => void {\n this.subscribers.add(callback);\n \n // Immediately call with current progress for initialization\n try {\n callback(this.currentProgress);\n } catch (e) {\n // Silent\n }\n\n // Register with unique LoopManager if we have subscribers\n if (this.subscribers.size === 1) {\n ScrollLoopManager.getInstance().register(this.tick);\n }\n \n return () => {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n };\n }\n\n unsubscribe(callback: TimelineCallback): void {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n }\n\n /**\n * Start is now handled by LoopManager via subscriptions\n * Deprecated but kept for API stability if needed.\n */\n start(): void {\n // No-op, managed by subscriptions\n }\n\n stop(): void {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n\n private tick = (): void => {\n // Calculate Progress\n const progress = this.calculateProgress();\n\n // Notify if changed significantly (using threshold constant)\n if (Math.abs(progress - this.currentProgress) > SCROLL_THRESHOLD) {\n this.currentProgress = progress;\n this.notify();\n }\n };\n\n private notify() {\n this.subscribers.forEach((cb) => {\n try {\n cb(this.currentProgress);\n } catch (e) {\n // Silent\n }\n });\n }\n\n private updateCache() {\n if (!this.isLayoutDirty && this.cachedRect) return;\n\n this.cachedRect = this.container.getBoundingClientRect();\n \n if (!this.cachedScrollParent) {\n this.cachedScrollParent = this.getScrollParent(this.container);\n }\n\n if (this.cachedScrollParent instanceof Element) {\n this.cachedScrollParentRect = this.cachedScrollParent.getBoundingClientRect();\n this.cachedViewportHeight = this.cachedScrollParentRect.height;\n this.cachedOffsetTop = this.cachedScrollParentRect.top;\n } else if (typeof window !== 'undefined') {\n this.cachedViewportHeight = window.innerHeight;\n this.cachedOffsetTop = 0;\n }\n\n this.isLayoutDirty = false;\n }\n\n private calculateProgress(): number {\n if (this.isLayoutDirty || !this.cachedRect) {\n this.updateCache();\n }\n\n const currentRect = this.container.getBoundingClientRect();\n const scrollDist = (this.cachedRect?.height || currentRect.height) - this.cachedViewportHeight;\n\n // Guard: Zero Height / Division by Zero\n if (scrollDist <= 0) return 1;\n\n const relativeTop = currentRect.top - this.cachedOffsetTop;\n const rawProgress = -relativeTop / scrollDist;\n \n const clamped = Math.min(Math.max(rawProgress, 0), 1);\n \n // Round to 6 decimals to prevent micro-drift\n return Math.round(clamped * 1000000) / 1000000;\n }\n\n private getScrollParent(node: Element): Element | Window {\n if (typeof window === 'undefined') return node; \n\n let current = node.parentElement;\n while (current) {\n const style = getComputedStyle(current);\n if (['auto', 'scroll'].includes(style.overflowY)) {\n return current;\n }\n current = current.parentElement;\n }\n return window;\n }\n\n destroy() {\n this.subscribers.clear();\n ScrollLoopManager.getInstance().unregister(this.tick);\n \n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n if (typeof window !== 'undefined') {\n window.removeEventListener('resize', this.onWindowResize);\n }\n }\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollTextProps {\n children: React.ReactNode;\n /** Progress start (0-1) where ENTRANCE animation begins */\n start?: number;\n /** Progress end (0-1) where ENTRANCE animation ends */\n end?: number;\n \n /** Progress start (0-1) where EXIT animation begins. If omitted, element stays visible. */\n exitStart?: number;\n /** Progress end (0-1) where EXIT animation ends */\n exitEnd?: number;\n\n /** Initial opacity */\n initialOpacity?: number;\n /** Target opacity (when entered) */\n targetOpacity?: number;\n /** Final opacity (after exit) */\n finalOpacity?: number;\n\n /** Y-axis translation range in pixels (e.g., 50 means move down 50px) */\n translateY?: number;\n \n style?: React.CSSProperties;\n className?: string;\n}\n\nexport function ScrollText({\n children,\n start = 0,\n end = 0.2,\n exitStart,\n exitEnd,\n initialOpacity = 0,\n targetOpacity = 1,\n finalOpacity = 0,\n translateY = 50,\n style,\n className,\n}: ScrollTextProps) {\n const ref = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n useEffect(() => {\n // Subscribe to updates\n if (typeof window === 'undefined') return;\n\n const unsubscribe = subscribe((progress) => {\n if (!ref.current) return;\n\n // Check for reduced motion preference\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n // If reduced motion is preferred, disable translation (keep opacity fade)\n const effectiveTranslateY = prefersReducedMotion ? 0 : translateY;\n\n let opacity = initialOpacity;\n let currentY = effectiveTranslateY;\n\n // 1. Entrance Phase\n if (progress < start) {\n opacity = initialOpacity;\n currentY = effectiveTranslateY;\n } else if (progress >= start && progress <= end) {\n const local = (progress - start) / (end - start);\n opacity = initialOpacity + (targetOpacity - initialOpacity) * local;\n currentY = effectiveTranslateY * (1 - local);\n } \n // 2. Hold Phase\n else if (!exitStart || progress < exitStart) {\n opacity = targetOpacity;\n currentY = 0;\n }\n // 3. Exit Phase\n else if (exitStart && exitEnd && progress >= exitStart && progress <= exitEnd) {\n const local = (progress - exitStart) / (exitEnd - exitStart);\n opacity = targetOpacity + (finalOpacity - targetOpacity) * local;\n // Move from 0 -> -translateY (or 0 if reduced motion)\n currentY = -effectiveTranslateY * local; \n }\n // 4. Final Phase\n else {\n opacity = finalOpacity;\n currentY = -effectiveTranslateY;\n }\n\n // Apply styles\n ref.current.style.opacity = opacity.toFixed(3);\n ref.current.style.transform = `translateY(${currentY}px)`;\n });\n\n return unsubscribe;\n }, [subscribe, start, end, exitStart, exitEnd, initialOpacity, targetOpacity, finalOpacity, translateY]);\n\n return (\n <div \n ref={ref} \n className={className}\n style={{\n opacity: initialOpacity, \n transform: `translateY(${translateY}px)`,\n transition: 'none', // Critical: no CSS transition fighting JS\n willChange: 'opacity, transform',\n ...style\n }}\n >\n {children}\n </div>\n );\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollWordRevealProps {\n text: string;\n /** Progress start (0-1) */\n start?: number;\n /** Progress end (0-1) */\n end?: number;\n className?: string;\n style?: React.CSSProperties;\n /** Stagger delay factor (not used in pure scroll map, simpler logic: map word index to sub-progress) */\n}\n\nexport function ScrollWordReveal({\n text,\n start = 0,\n end = 1,\n className,\n style\n}: ScrollWordRevealProps) {\n // We cannot create refs in loop dynamically in top level easily without array.\n // Better to have one parent ref and querySelectorAll children, OR use callback refs.\n const containerRef = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n // Split words\n const words = text.split(/\\s+/);\n\n useEffect(() => {\n const unsubscribe = subscribe((globalProgress) => {\n if (!containerRef.current) return;\n const spans = containerRef.current.children;\n \n // Map global progress to local range [start, end]\n let localProgress = 0;\n if (globalProgress <= start) localProgress = 0;\n else if (globalProgress >= end) localProgress = 1;\n else localProgress = (globalProgress - start) / (end - start);\n\n // Calculate which word should be visible\n const totalWords = spans.length;\n const progressPerWord = 1 / totalWords;\n\n for (let i = 0; i < totalWords; i++) {\n const span = spans[i] as HTMLElement;\n \n // Each word fades in during its \"slot\"\n // Word 0: 0 -> 0.1\n // Word 1: 0.1 -> 0.2\n const wordStart = i * progressPerWord;\n const wordEnd = (i + 1) * progressPerWord;\n \n let wordOpacity = 0;\n if (localProgress >= wordEnd) {\n wordOpacity = 1;\n } else if (localProgress <= wordStart) {\n wordOpacity = 0.1; // faint visibility initially? or 0\n } else {\n // Interpolate\n wordOpacity = 0.1 + 0.9 * ((localProgress - wordStart) / (wordEnd - wordStart));\n }\n \n span.style.opacity = wordOpacity.toFixed(2);\n // Optional: translate Y too?\n const translate = (1 - wordOpacity) * 10;\n span.style.transform = `translateY(${translate}px)`;\n }\n });\n\n return unsubscribe;\n }, [subscribe, start, end]);\n\n return (\n <div ref={containerRef} className={className} style={{ ...style, display: 'flex', flexWrap: 'wrap', gap: '0.25em' }}>\n {words.map((word, i) => (\n <span \n key={i} \n style={{ \n opacity: 0.1, \n transform: 'translateY(10px)',\n transition: 'none',\n willChange: 'opacity, transform'\n }}\n >\n {word}\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["import_react","import_react","import_react","React","import_jsx_runtime","React","import_react","import_jsx_runtime","import_react","import_jsx_runtime"]}
|
package/dist/index.mjs
CHANGED
|
@@ -529,9 +529,11 @@ function ScrollTimelineProvider({
|
|
|
529
529
|
children,
|
|
530
530
|
scrollLength = "300vh",
|
|
531
531
|
className = "",
|
|
532
|
-
style = {}
|
|
532
|
+
style = {},
|
|
533
|
+
containerRef: externalRef
|
|
533
534
|
}) {
|
|
534
|
-
const
|
|
535
|
+
const internalRef = useRef2(null);
|
|
536
|
+
const containerRef = externalRef || internalRef;
|
|
535
537
|
const [timeline, setTimeline] = useState2(null);
|
|
536
538
|
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
|
|
537
539
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -577,6 +579,8 @@ var InnerSequence = ({
|
|
|
577
579
|
memoryStrategy,
|
|
578
580
|
lazyBuffer,
|
|
579
581
|
accessibilityLabel = "Scroll sequence",
|
|
582
|
+
fit = "cover",
|
|
583
|
+
// Default to cover
|
|
580
584
|
fallback,
|
|
581
585
|
onError
|
|
582
586
|
}) => {
|
|
@@ -592,7 +596,8 @@ var InnerSequence = ({
|
|
|
592
596
|
display: "block",
|
|
593
597
|
width: "100%",
|
|
594
598
|
height: "100%",
|
|
595
|
-
objectFit:
|
|
599
|
+
objectFit: fit,
|
|
600
|
+
// Use the prop
|
|
596
601
|
opacity: isLoaded ? 1 : 0,
|
|
597
602
|
transition: "opacity 0.2s ease-in"
|
|
598
603
|
};
|
|
@@ -634,30 +639,38 @@ var ScrollSequence = React2.forwardRef(
|
|
|
634
639
|
memoryStrategy = "eager",
|
|
635
640
|
lazyBuffer = 10,
|
|
636
641
|
fallback,
|
|
642
|
+
fit = "cover",
|
|
643
|
+
// Default here too
|
|
637
644
|
accessibilityLabel,
|
|
638
|
-
onError
|
|
645
|
+
onError,
|
|
646
|
+
children
|
|
647
|
+
// Extract children
|
|
639
648
|
} = props;
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
649
|
+
return /* @__PURE__ */ jsxs(
|
|
650
|
+
ScrollTimelineProvider,
|
|
651
|
+
{
|
|
652
|
+
scrollLength,
|
|
653
|
+
className,
|
|
654
|
+
style: { position: "relative" },
|
|
655
|
+
containerRef: ref,
|
|
656
|
+
children: [
|
|
657
|
+
/* @__PURE__ */ jsx2(
|
|
658
|
+
InnerSequence,
|
|
659
|
+
{
|
|
660
|
+
source,
|
|
661
|
+
debug,
|
|
662
|
+
memoryStrategy,
|
|
663
|
+
lazyBuffer,
|
|
664
|
+
fallback,
|
|
665
|
+
accessibilityLabel,
|
|
666
|
+
onError,
|
|
667
|
+
fit
|
|
668
|
+
}
|
|
669
|
+
),
|
|
670
|
+
/* @__PURE__ */ jsx2("div", { style: { position: "absolute", inset: 0, zIndex: 10, pointerEvents: "none" }, children })
|
|
671
|
+
]
|
|
643
672
|
}
|
|
644
|
-
|
|
645
|
-
}, []);
|
|
646
|
-
return /* @__PURE__ */ jsx2("div", { ref, className, style: { width: "100%" }, children: /* @__PURE__ */ jsxs(ScrollTimelineProvider, { scrollLength, children: [
|
|
647
|
-
prefersReducedMotion && fallback ? /* @__PURE__ */ jsx2("div", { style: { position: "sticky", top: 0, height: "100vh", width: "100%" }, children: fallback }) : /* @__PURE__ */ jsx2(
|
|
648
|
-
InnerSequence,
|
|
649
|
-
{
|
|
650
|
-
source,
|
|
651
|
-
debug,
|
|
652
|
-
memoryStrategy,
|
|
653
|
-
lazyBuffer,
|
|
654
|
-
fallback,
|
|
655
|
-
accessibilityLabel,
|
|
656
|
-
onError
|
|
657
|
-
}
|
|
658
|
-
),
|
|
659
|
-
props.children
|
|
660
|
-
] }) });
|
|
673
|
+
);
|
|
661
674
|
}
|
|
662
675
|
);
|
|
663
676
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/ScrollSequence.tsx","../src/react/useScrollSequence.ts","../src/controllers/imageController.ts","../src/sequence/sequenceResolver.ts","../src/core/clamp.ts","../src/react/scrollTimelineContext.ts","../src/react/useScrollTimeline.ts","../src/react/ScrollTimelineProvider.tsx","../src/core/loopManager.ts","../src/constants.ts","../src/core/scrollTimeline.ts","../src/react/ScrollText.tsx","../src/react/ScrollWordReveal.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { useScrollSequence } from './useScrollSequence';\nimport { ScrollTimelineProvider } from './ScrollTimelineProvider';\n\ninterface InnerSequenceProps {\n source: ScrollSequenceProps['source'];\n debug: boolean;\n memoryStrategy: ScrollSequenceProps['memoryStrategy'];\n lazyBuffer?: number;\n accessibilityLabel?: string;\n fallback?: React.ReactNode;\n onError?: (error: Error) => void;\n}\n\nconst InnerSequence: React.FC<InnerSequenceProps> = ({ \n source, \n debug, \n memoryStrategy,\n lazyBuffer,\n accessibilityLabel = \"Scroll sequence\",\n fallback,\n onError\n}) => {\n const debugRef = useRef<HTMLDivElement>(null);\n const { canvasRef, isLoaded } = useScrollSequence({\n source,\n debugRef,\n memoryStrategy,\n lazyBuffer,\n onError\n });\n \n // Fallback logic could be handled here or by parent.\n // If we handle it here, we overlay it?\n // Actually, canvas opacity handles the fade-in.\n // Use fallback if provided and not loaded.\n\n const canvasStyle: React.CSSProperties = {\n display: 'block',\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n opacity: isLoaded ? 1 : 0,\n transition: 'opacity 0.2s ease-in',\n };\n \n const debugStyle: React.CSSProperties = {\n position: 'absolute',\n top: '10px',\n left: '10px',\n background: 'rgba(0, 0, 0, 0.7)',\n color: '#00ff00',\n padding: '8px',\n borderRadius: '4px',\n fontFamily: 'monospace',\n fontSize: '12px',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n zIndex: 9999,\n };\n\n return (\n <>\n {/* Render fallback behind canvas, or replace? \n If replace, we might loose the canvas ref init?\n Better to render both and cross-fade or just hide fallback when loaded.\n */}\n {!isLoaded && fallback && (\n <div style={{ position: 'absolute', inset: 0, zIndex: 1 }}>\n {fallback}\n </div>\n )}\n \n <canvas \n ref={canvasRef} \n style={canvasStyle} \n role=\"img\"\n aria-label={accessibilityLabel}\n />\n {debug && <div ref={debugRef} style={debugStyle}>Waiting for scroll...</div>}\n </>\n );\n};\n\nexport const ScrollSequence = React.forwardRef<HTMLDivElement, ScrollSequenceProps>(\n (props, ref) => {\n const {\n source,\n scrollLength = '300vh',\n className = '',\n debug = false,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n fallback,\n accessibilityLabel,\n onError,\n } = props;\n\n // Check for reduced motion\n const prefersReducedMotion = React.useMemo(() => {\n if (typeof window !== 'undefined') {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n }\n return false;\n }, []);\n\n // Use ScrollSequence now acts as the convenient \"Bundle\"\n // It provides the Timeline context and renders the Canvas consumer.\n return (\n <div ref={ref} className={className} style={{ width: '100%' }}>\n <ScrollTimelineProvider scrollLength={scrollLength}>\n {prefersReducedMotion && fallback ? (\n <div style={{ position: 'sticky', top: 0, height: '100vh', width: '100%' }}>\n {fallback}\n </div>\n ) : (\n <InnerSequence \n source={source} \n debug={debug} \n memoryStrategy={memoryStrategy}\n lazyBuffer={lazyBuffer} \n fallback={fallback}\n accessibilityLabel={accessibilityLabel}\n onError={onError}\n />\n )}\n {props.children}\n </ScrollTimelineProvider>\n </div>\n );\n }\n);\n","import { useRef, useEffect, useState } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { ImageController } from '../controllers/imageController';\nimport { resolveSequence } from '../sequence/sequenceResolver';\nimport { clamp } from '../core/clamp';\nimport { useScrollTimeline } from './useScrollTimeline';\n\ninterface UseScrollSequenceParams {\n source: ScrollSequenceProps['source'];\n debugRef?: React.MutableRefObject<HTMLDivElement | null>;\n memoryStrategy?: 'eager' | 'lazy';\n lazyBuffer?: number;\n onError?: (error: Error) => void;\n}\n\n/**\n * Hook to manage image sequence in a timeline context.\n * MUST be used inside ScrollTimelineProvider.\n */\nexport function useScrollSequence({\n source,\n debugRef,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n onError,\n}: UseScrollSequenceParams) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const controllerRef = useRef<ImageController | null>(null);\n \n // Use the shared timeline\n const { subscribe } = useScrollTimeline();\n\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let active = true;\n let currentController: ImageController | null = null;\n let unsubscribeTimeline: (() => void) | null = null;\n\n const init = async () => {\n setIsLoaded(false);\n setError(null);\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n try {\n // 1. Resolve Sequence\n // Guard: source change handled by effect dep, but verify environment?\n if (typeof window === 'undefined') return;\n\n const sequence = await resolveSequence(source);\n if (!active) return;\n\n if (sequence.frames.length === 0) {\n return;\n }\n\n // 2. Setup Dimensions (Initial)\n if (typeof window !== 'undefined') {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n }\n\n // 3. Initialize Controller\n currentController = new ImageController({\n canvas,\n frames: sequence.frames,\n strategy: memoryStrategy,\n bufferSize: lazyBuffer\n });\n controllerRef.current = currentController;\n\n // 4. Subscribe to Timeline\n unsubscribeTimeline = subscribe((progress) => {\n if (!currentController) return;\n const clamped = clamp(progress);\n currentController.update(clamped);\n\n // Debug Overlay\n if (debugRef?.current) {\n const frameIndex = Math.floor(clamped * (sequence.frames.length - 1));\n debugRef.current.innerText = `Progress: ${clamped.toFixed(2)}\\nFrame: ${frameIndex + 1} / ${sequence.frames.length}`;\n }\n });\n\n if (active) setIsLoaded(true);\n\n } catch (err) {\n if (active) {\n const e = err instanceof Error ? err : new Error('Unknown initialization error');\n setError(e);\n if (onError) onError(e);\n }\n }\n };\n\n init();\n\n return () => {\n active = false;\n currentController?.destroy();\n controllerRef.current = null;\n if (unsubscribeTimeline) unsubscribeTimeline();\n };\n }, [source, memoryStrategy, lazyBuffer, subscribe]); // Re-run if source or timeline changes\n\n return {\n canvasRef,\n isLoaded,\n error\n };\n}\n","/**\n * ImageController\n * Manages canvas rendering, image loading, and frame-by-frame drawing.\n * Handles preloading and caching to minimize redraws.\n */\n\nexport interface ImageControllerConfig {\n /** HTMLCanvasElement to draw on */\n canvas: HTMLCanvasElement;\n\n /** Array of sorted frame URLs */\n frames: string[];\n\n /** Memory management strategy */\n strategy?: 'eager' | 'lazy';\n\n /** Lazy load buffer size (default 10) */\n bufferSize?: number;\n}\n\nexport class ImageController {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private frames: string[];\n private imageCache = new Map<string, HTMLImageElement>();\n private loadingPromises = new Map<string, Promise<HTMLImageElement>>();\n private currentFrameIndex = -1;\n private strategy: 'eager' | 'lazy';\n private bufferSize: number;\n\n /**\n * Create a new ImageController instance.\n *\n * @param config - Configuration object\n * @throws If canvas doesn't support 2D context\n */\n private isDestroyed = false;\n\n constructor(config: ImageControllerConfig) {\n this.canvas = config.canvas;\n this.frames = config.frames;\n this.strategy = config.strategy || 'eager';\n this.bufferSize = config.bufferSize || 10;\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context from canvas');\n }\n this.ctx = ctx;\n\n // Initial load\n if (this.strategy === 'eager') {\n this.preloadAll();\n } else {\n this.ensureFrameWindow(0);\n }\n }\n\n // ... preloadAll omitted for brevity if unchanged, but let's include for completeness if needed.\n // Actually, we need to add guards to preloadFrame, so let's check it.\n \n private preloadAll(): void {\n this.frames.forEach((_, index) => this.preloadFrame(index));\n }\n\n private ensureFrameWindow(currentIndex: number): void {\n if (this.isDestroyed) return;\n\n const radius = this.bufferSize;\n const start = Math.max(0, currentIndex - radius);\n const end = Math.min(this.frames.length - 1, currentIndex + radius);\n \n const needed = new Set<string>();\n for (let i = start; i <= end; i++) {\n needed.add(this.frames[i]);\n }\n\n // Cleanup unused frames (LRU-ish but simple Window-based)\n for (const [src] of this.imageCache) {\n if (!needed.has(src)) {\n this.imageCache.delete(src);\n // We should also cancel promises if possible, but we can't cancel a fetch/image load easily.\n // We just delete the tracking so we don't cache it when it lands.\n this.loadingPromises.delete(src);\n }\n }\n\n // Load needed\n for (let i = start; i <= end; i++) {\n void this.preloadFrame(i);\n }\n }\n\n async preloadFrame(index: number): Promise<void> {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n\n if (this.imageCache.has(src)) return;\n\n // Deduplication: Reuse existing promise if allowed\n if (!this.loadingPromises.has(src)) {\n this.loadingPromises.set(src, this.loadImage(src));\n }\n\n try {\n await this.loadingPromises.get(src);\n } catch {\n // Failed\n if (!this.isDestroyed) {\n // Silent failure\n }\n }\n }\n\n private loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n \n img.onload = () => {\n if (this.isDestroyed) return;\n \n // Critical: decode() to prevent main-thread jank during draw\n img.decode()\n .then(() => {\n if (this.isDestroyed) return;\n this.imageCache.set(src, img);\n resolve(img);\n })\n .catch(() => {\n if (this.isDestroyed) return;\n // Even if decode fails, the image might be usable\n this.imageCache.set(src, img);\n resolve(img);\n });\n };\n\n img.onerror = () => {\n if (this.isDestroyed) return;\n reject(new Error(`Failed to load image: ${src}`));\n };\n\n img.src = src;\n });\n }\n\n update(progress: number): void {\n if (this.isDestroyed || this.frames.length === 0) return;\n\n const frameIndex = Math.floor(progress * (this.frames.length - 1));\n\n if (this.strategy === 'lazy') {\n this.ensureFrameWindow(frameIndex);\n }\n\n if (frameIndex === this.currentFrameIndex) return;\n\n this.currentFrameIndex = frameIndex;\n this.drawFrame(frameIndex);\n }\n\n private drawFrame(index: number): void {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n const img = this.imageCache.get(src);\n\n if (!img) {\n // Frame not ready. Optional: Show loading spinner or keep previous frame?\n // For now, keep previous (natural behavior of canvas).\n // Or check promise\n const promise = this.loadingPromises.get(src);\n if (promise) {\n promise.then(() => {\n if (this.currentFrameIndex === index) {\n this.drawFrame(index);\n }\n }).catch(() => {}); // catch ignore\n }\n return;\n }\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n const scale = Math.min(\n this.canvas.width / img.width,\n this.canvas.height / img.height\n );\n\n const scaledWidth = img.width * scale;\n const scaledHeight = img.height * scale;\n const x = (this.canvas.width - scaledWidth) / 2;\n const y = (this.canvas.height - scaledHeight) / 2;\n\n this.ctx.drawImage(img, x, y, scaledWidth, scaledHeight);\n }\n\n setCanvasSize(width: number, height: number): void {\n if (this.isDestroyed) return;\n this.canvas.width = width;\n this.canvas.height = height;\n if (this.currentFrameIndex >= 0) {\n this.drawFrame(this.currentFrameIndex);\n }\n }\n\n destroy(): void {\n this.isDestroyed = true;\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.imageCache.clear();\n this.loadingPromises.clear();\n }\n}\n","/**\n * SequenceResolver\n * Handles intelligent frame resolution from multiple input sources:\n * - Manual frame list (frames[])\n * - Pattern generation (pattern, start, end, pad)\n * - Remote manifest (manifest URL)\n */\n\nimport type { ScrollSequenceProps, ResolvedSequence } from '../types';\n\n// Declare process for TS (avoiding @types/node dependency for just this)\ndeclare const process: { env: { NODE_ENV: string } };\n\n/**\n * Resolves frame sequence from props.\n * Prioritizes: frames > pattern > manifest\n */\n/**\n * Resolves frame sequence from props.\n * Handles 'manual', 'pattern', and 'manifest' sources.\n */\nexport async function resolveSequence(source: ScrollSequenceProps['source']): Promise<ResolvedSequence> {\n switch (source.type) {\n case 'manual':\n return processManualFrames(source.frames);\n \n case 'pattern':\n return processPatternMode(source.url, source.start ?? 1, source.end, source.pad);\n \n case 'manifest':\n return processManifestMode(source.url);\n \n default:\n return { frames: [], frameCount: 0 };\n }\n}\n\n/**\n * Mode A: Process manually provided frames\n */\nfunction processManualFrames(frames: string[]): ResolvedSequence {\n // Sort frames numerically by extracting numbers from filenames\n // Uses stable sort to preserve order for frames with no numbers or equal numbers\n const sorted = [...frames].sort((a, b) => {\n const numA = extractNumber(a);\n const numB = extractNumber(b);\n return numA - numB;\n });\n\n return {\n frames: sorted,\n frameCount: sorted.length\n };\n}\n\n/**\n * Mode B: Generate frames from pattern\n */\nfunction processPatternMode(pattern: string, start: number, end: number, pad?: number): ResolvedSequence {\n const frames: string[] = [];\n\n for (let i = start; i <= end; i++) {\n let indexStr = i.toString();\n if (pad) {\n indexStr = indexStr.padStart(pad, '0');\n }\n frames.push(pattern.replace('{index}', indexStr));\n }\n\n return {\n frames,\n frameCount: frames.length\n };\n}\n\n/**\n * Mode C: Fetch and process manifest\n */\nconst manifestCache = new Map<string, Promise<ResolvedSequence>>();\n\nasync function processManifestMode(url: string): Promise<ResolvedSequence> {\n if (manifestCache.has(url)) {\n return manifestCache.get(url)!;\n }\n\n const promise = (async () => {\n try {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: ${res.statusText}`);\n }\n \n const data = await res.json();\n \n // Check for \"frames\" array in manifest\n if (data.frames && Array.isArray(data.frames)) {\n return processManualFrames(data.frames);\n }\n \n // Check for pattern config in manifest\n if (data.pattern && typeof data.end === 'number') {\n const start = data.start ?? 1;\n const pad = data.pad;\n return processPatternMode(data.pattern, start, data.end, pad);\n }\n \n return { frames: [], frameCount: 0 };\n \n } catch (err) {\n // Remove from cache on error so retry is possible\n manifestCache.delete(url);\n throw err;\n }\n })();\n\n manifestCache.set(url, promise);\n return promise;\n}\n\n// --- Helpers ---\n\n/**\n * Extract the first number found in a filename.\n * Returns -1 if no number is found, to differentiate from 0.\n */\nfunction extractNumber(filename: string): number {\n const match = filename.match(/\\d+/);\n return match ? parseInt(match[0], 10) : -1;\n}\n\n","/**\n * Clamps a value between a minimum and maximum.\n * Default range is [0, 1], suitable for progress values.\n *\n * @param value - The value to clamp\n * @param min - Minimum value (default: 0)\n * @param max - Maximum value (default: 1)\n * @returns The clamped value\n */\nexport function clamp(value: number, min: number = 0, max: number = 1): number {\n return Math.max(min, Math.min(max, value));\n}\n","import { createContext, useContext } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\n\nexport interface ScrollTimelineContextValue {\n timeline: ScrollTimeline | null;\n // Expose current progress? No, that causes re-renders. Use subscription.\n}\n\nexport const ScrollTimelineContext = createContext<ScrollTimelineContextValue>({\n timeline: null,\n});\n\nexport function useTimelineContext() {\n return useContext(ScrollTimelineContext);\n}\n","import { ScrollTimeline, TimelineCallback } from '../core/scrollTimeline';\nimport { useTimelineContext } from './scrollTimelineContext';\n\nexport interface UseScrollTimelineResult {\n /** \n * Manual subscription to the timeline. \n * Useful for low-level DOM updates (refs) without re-rendering.\n */\n subscribe: (callback: TimelineCallback) => () => void;\n \n /** The raw timeline instance (for advanced usage) */\n timeline: ScrollTimeline | null; \n}\n\nexport function useScrollTimeline(): UseScrollTimelineResult {\n const { timeline } = useTimelineContext();\n\n const subscribe = (callback: TimelineCallback) => {\n if (!timeline) return () => {};\n return timeline.subscribe(callback);\n };\n\n return { subscribe, timeline };\n}\n","import React, { useRef, useState } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\nimport { ScrollTimelineContext } from './scrollTimelineContext';\n\nexport interface ScrollTimelineProviderProps {\n children: React.ReactNode;\n \n /** CSS height for the scroll container (e.g., \"300vh\"). */\n scrollLength?: string;\n \n className?: string;\n style?: React.CSSProperties;\n}\n\nexport function ScrollTimelineProvider({\n children,\n scrollLength = '300vh',\n className = '',\n style = {},\n}: ScrollTimelineProviderProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [timeline, setTimeline] = useState<ScrollTimeline | null>(null);\n\n // Use layout effect to ensure timeline exists before children effects run\n // SSR safe fallback: use useEffect on server\n const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\n useIsomorphicLayoutEffect(() => {\n if (typeof window === 'undefined') return;\n if (!containerRef.current) return;\n\n // Future-proof: factory could be passed via props\n const instance = new ScrollTimeline(containerRef.current);\n \n // We do NOT call start() anymore, it starts on subscription\n // instance.start(); \n \n setTimeline(instance);\n\n return () => {\n instance.destroy();\n setTimeline(null);\n };\n }, []); // Dependencies? strict empty for one-time setup\n\n const containerStyle: React.CSSProperties = {\n height: scrollLength,\n position: 'relative',\n width: '100%',\n ...style,\n };\n\n const stickyWrapperStyle: React.CSSProperties = {\n position: 'sticky',\n top: 0,\n height: '100vh',\n width: '100%',\n overflow: 'hidden',\n };\n\n // Memoize context value to prevent unnecessary re-renders of consumers\n // when Parent component renders but timeline instance hasn't changed.\n const contextValue = React.useMemo(() => ({ timeline }), [timeline]);\n\n return (\n <ScrollTimelineContext.Provider value={contextValue}>\n <div \n ref={containerRef} \n className={className} \n style={containerStyle}\n >\n <div style={stickyWrapperStyle}>\n {children}\n </div>\n </div>\n </ScrollTimelineContext.Provider>\n );\n}\n","/**\n * ScrollLoopManager\n * \n * Singleton class to manage a single requestAnimationFrame loop\n * for all ScrollTimeline instances. This prevents multiple RAF\n * callbacks from piling up and degrading performance.\n */\n\ntype LoopCallback = () => void;\n\nexport class ScrollLoopManager {\n private static instance: ScrollLoopManager;\n private callbacks = new Set<LoopCallback>();\n private rafId: number | null = null;\n private isActive = false;\n\n private constructor() {}\n\n public static getInstance(): ScrollLoopManager {\n if (!ScrollLoopManager.instance) {\n ScrollLoopManager.instance = new ScrollLoopManager();\n }\n return ScrollLoopManager.instance;\n }\n\n /**\n * Register a callback to be called on every animation frame.\n */\n public register(callback: LoopCallback): void {\n if (this.callbacks.has(callback)) return;\n \n this.callbacks.add(callback);\n \n // Start loop if this is the first subscriber\n if (this.callbacks.size === 1) {\n this.start();\n }\n }\n\n /**\n * Unregister a callback.\n */\n public unregister(callback: LoopCallback): void {\n this.callbacks.delete(callback);\n\n // Stop loop if no subscribers left\n if (this.callbacks.size === 0) {\n this.stop();\n }\n }\n\n private start(): void {\n if (this.isActive) return;\n this.isActive = true;\n \n // Ensure we are in a browser environment\n if (typeof window !== 'undefined') {\n this.tick();\n }\n }\n\n private stop(): void {\n this.isActive = false;\n if (this.rafId !== null && typeof window !== 'undefined') {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private tick = (): void => {\n if (!this.isActive) return;\n\n // Execute all registered callbacks\n this.callbacks.forEach(cb => {\n try {\n cb();\n } catch (e) {\n // Silent catch to prevent loop crash\n }\n });\n\n this.rafId = requestAnimationFrame(this.tick);\n };\n}\n","/**\n * Global Constants for React Scroll Media\n */\n\n// Scroll Logic\nexport const SCROLL_THRESHOLD = 0.0001; // Minimum progress change to trigger update\nexport const DEFAULT_SCROLL_LENGTH = '300vh';\n\n// Memory Management\nexport const DEFAULT_LAZY_BUFFER = 10;\nexport const MAX_CACHE_SIZE = 50; // Fallback max size if not dynamic\n\n// Sequences\nexport const DEFAULT_PAD_LENGTH = 0; // Default padding for image numbering\n\n// Styles & Layout\nexport const DEFAULT_FALLBACK_COLOR = '#ccc';\n","import { ScrollLoopManager } from './loopManager';\nimport { SCROLL_THRESHOLD } from '../constants';\n\nexport type TimelineCallback = (progress: number) => void;\n\nexport class ScrollTimeline {\n private container: Element;\n private subscribers = new Set<TimelineCallback>();\n private currentProgress = 0;\n \n // Caching for performance\n private cachedRect: DOMRect | null = null;\n private cachedScrollParent: Element | Window | null = null;\n private cachedScrollParentRect: DOMRect | null = null;\n private cachedViewportHeight = 0;\n private cachedOffsetTop = 0;\n private isLayoutDirty = true;\n private resizeObserver: ResizeObserver | null = null;\n\n public readonly id = typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n constructor(container: Element) {\n this.container = container;\n \n if (typeof window !== 'undefined') {\n // Invalidate cache on resize\n this.resizeObserver = new ResizeObserver(() => {\n this.isLayoutDirty = true;\n });\n this.resizeObserver.observe(this.container);\n if (document.body) {\n this.resizeObserver.observe(document.body);\n }\n \n // Also listen to global resize\n window.addEventListener('resize', this.onWindowResize);\n }\n }\n\n private onWindowResize = () => {\n this.isLayoutDirty = true;\n };\n\n /**\n * Subscribe to progress updates.\n * Returns an unsubscribe function.\n */\n subscribe(callback: TimelineCallback): () => void {\n this.subscribers.add(callback);\n \n // Immediately call with current progress for initialization\n try {\n callback(this.currentProgress);\n } catch (e) {\n // Silent\n }\n\n // Register with unique LoopManager if we have subscribers\n if (this.subscribers.size === 1) {\n ScrollLoopManager.getInstance().register(this.tick);\n }\n \n return () => {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n };\n }\n\n unsubscribe(callback: TimelineCallback): void {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n }\n\n /**\n * Start is now handled by LoopManager via subscriptions\n * Deprecated but kept for API stability if needed.\n */\n start(): void {\n // No-op, managed by subscriptions\n }\n\n stop(): void {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n\n private tick = (): void => {\n // Calculate Progress\n const progress = this.calculateProgress();\n\n // Notify if changed significantly (using threshold constant)\n if (Math.abs(progress - this.currentProgress) > SCROLL_THRESHOLD) {\n this.currentProgress = progress;\n this.notify();\n }\n };\n\n private notify() {\n this.subscribers.forEach((cb) => {\n try {\n cb(this.currentProgress);\n } catch (e) {\n // Silent\n }\n });\n }\n\n private updateCache() {\n if (!this.isLayoutDirty && this.cachedRect) return;\n\n this.cachedRect = this.container.getBoundingClientRect();\n \n if (!this.cachedScrollParent) {\n this.cachedScrollParent = this.getScrollParent(this.container);\n }\n\n if (this.cachedScrollParent instanceof Element) {\n this.cachedScrollParentRect = this.cachedScrollParent.getBoundingClientRect();\n this.cachedViewportHeight = this.cachedScrollParentRect.height;\n this.cachedOffsetTop = this.cachedScrollParentRect.top;\n } else if (typeof window !== 'undefined') {\n this.cachedViewportHeight = window.innerHeight;\n this.cachedOffsetTop = 0;\n }\n\n this.isLayoutDirty = false;\n }\n\n private calculateProgress(): number {\n if (this.isLayoutDirty || !this.cachedRect) {\n this.updateCache();\n }\n\n const currentRect = this.container.getBoundingClientRect();\n const scrollDist = (this.cachedRect?.height || currentRect.height) - this.cachedViewportHeight;\n\n // Guard: Zero Height / Division by Zero\n if (scrollDist <= 0) return 1;\n\n const relativeTop = currentRect.top - this.cachedOffsetTop;\n const rawProgress = -relativeTop / scrollDist;\n \n const clamped = Math.min(Math.max(rawProgress, 0), 1);\n \n // Round to 6 decimals to prevent micro-drift\n return Math.round(clamped * 1000000) / 1000000;\n }\n\n private getScrollParent(node: Element): Element | Window {\n if (typeof window === 'undefined') return node; \n\n let current = node.parentElement;\n while (current) {\n const style = getComputedStyle(current);\n if (['auto', 'scroll'].includes(style.overflowY)) {\n return current;\n }\n current = current.parentElement;\n }\n return window;\n }\n\n destroy() {\n this.subscribers.clear();\n ScrollLoopManager.getInstance().unregister(this.tick);\n \n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n if (typeof window !== 'undefined') {\n window.removeEventListener('resize', this.onWindowResize);\n }\n }\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollTextProps {\n children: React.ReactNode;\n /** Progress start (0-1) where ENTRANCE animation begins */\n start?: number;\n /** Progress end (0-1) where ENTRANCE animation ends */\n end?: number;\n \n /** Progress start (0-1) where EXIT animation begins. If omitted, element stays visible. */\n exitStart?: number;\n /** Progress end (0-1) where EXIT animation ends */\n exitEnd?: number;\n\n /** Initial opacity */\n initialOpacity?: number;\n /** Target opacity (when entered) */\n targetOpacity?: number;\n /** Final opacity (after exit) */\n finalOpacity?: number;\n\n /** Y-axis translation range in pixels (e.g., 50 means move down 50px) */\n translateY?: number;\n \n style?: React.CSSProperties;\n className?: string;\n}\n\nexport function ScrollText({\n children,\n start = 0,\n end = 0.2,\n exitStart,\n exitEnd,\n initialOpacity = 0,\n targetOpacity = 1,\n finalOpacity = 0,\n translateY = 50,\n style,\n className,\n}: ScrollTextProps) {\n const ref = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n useEffect(() => {\n // Subscribe to updates\n if (typeof window === 'undefined') return;\n\n const unsubscribe = subscribe((progress) => {\n if (!ref.current) return;\n\n // Check for reduced motion preference\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n // If reduced motion is preferred, disable translation (keep opacity fade)\n const effectiveTranslateY = prefersReducedMotion ? 0 : translateY;\n\n let opacity = initialOpacity;\n let currentY = effectiveTranslateY;\n\n // 1. Entrance Phase\n if (progress < start) {\n opacity = initialOpacity;\n currentY = effectiveTranslateY;\n } else if (progress >= start && progress <= end) {\n const local = (progress - start) / (end - start);\n opacity = initialOpacity + (targetOpacity - initialOpacity) * local;\n currentY = effectiveTranslateY * (1 - local);\n } \n // 2. Hold Phase\n else if (!exitStart || progress < exitStart) {\n opacity = targetOpacity;\n currentY = 0;\n }\n // 3. Exit Phase\n else if (exitStart && exitEnd && progress >= exitStart && progress <= exitEnd) {\n const local = (progress - exitStart) / (exitEnd - exitStart);\n opacity = targetOpacity + (finalOpacity - targetOpacity) * local;\n // Move from 0 -> -translateY (or 0 if reduced motion)\n currentY = -effectiveTranslateY * local; \n }\n // 4. Final Phase\n else {\n opacity = finalOpacity;\n currentY = -effectiveTranslateY;\n }\n\n // Apply styles\n ref.current.style.opacity = opacity.toFixed(3);\n ref.current.style.transform = `translateY(${currentY}px)`;\n });\n\n return unsubscribe;\n }, [subscribe, start, end, exitStart, exitEnd, initialOpacity, targetOpacity, finalOpacity, translateY]);\n\n return (\n <div \n ref={ref} \n className={className}\n style={{\n opacity: initialOpacity, \n transform: `translateY(${translateY}px)`,\n transition: 'none', // Critical: no CSS transition fighting JS\n willChange: 'opacity, transform',\n ...style\n }}\n >\n {children}\n </div>\n );\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollWordRevealProps {\n text: string;\n /** Progress start (0-1) */\n start?: number;\n /** Progress end (0-1) */\n end?: number;\n className?: string;\n style?: React.CSSProperties;\n /** Stagger delay factor (not used in pure scroll map, simpler logic: map word index to sub-progress) */\n}\n\nexport function ScrollWordReveal({\n text,\n start = 0,\n end = 1,\n className,\n style\n}: ScrollWordRevealProps) {\n // We cannot create refs in loop dynamically in top level easily without array.\n // Better to have one parent ref and querySelectorAll children, OR use callback refs.\n const containerRef = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n // Split words\n const words = text.split(/\\s+/);\n\n useEffect(() => {\n const unsubscribe = subscribe((globalProgress) => {\n if (!containerRef.current) return;\n const spans = containerRef.current.children;\n \n // Map global progress to local range [start, end]\n let localProgress = 0;\n if (globalProgress <= start) localProgress = 0;\n else if (globalProgress >= end) localProgress = 1;\n else localProgress = (globalProgress - start) / (end - start);\n\n // Calculate which word should be visible\n const totalWords = spans.length;\n const progressPerWord = 1 / totalWords;\n\n for (let i = 0; i < totalWords; i++) {\n const span = spans[i] as HTMLElement;\n \n // Each word fades in during its \"slot\"\n // Word 0: 0 -> 0.1\n // Word 1: 0.1 -> 0.2\n const wordStart = i * progressPerWord;\n const wordEnd = (i + 1) * progressPerWord;\n \n let wordOpacity = 0;\n if (localProgress >= wordEnd) {\n wordOpacity = 1;\n } else if (localProgress <= wordStart) {\n wordOpacity = 0.1; // faint visibility initially? or 0\n } else {\n // Interpolate\n wordOpacity = 0.1 + 0.9 * ((localProgress - wordStart) / (wordEnd - wordStart));\n }\n \n span.style.opacity = wordOpacity.toFixed(2);\n // Optional: translate Y too?\n const translate = (1 - wordOpacity) * 10;\n span.style.transform = `translateY(${translate}px)`;\n }\n });\n\n return unsubscribe;\n }, [subscribe, start, end]);\n\n return (\n <div ref={containerRef} className={className} style={{ ...style, display: 'flex', flexWrap: 'wrap', gap: '0.25em' }}>\n {words.map((word, i) => (\n <span \n key={i} \n style={{ \n opacity: 0.1, \n transform: 'translateY(10px)',\n transition: 'none',\n willChange: 'opacity, transform'\n }}\n >\n {word}\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["React","useRef","useRef","useState","useRef","useState","jsx","useRef","React","useRef","useEffect","jsx","useRef","useEffect","useRef","useEffect","jsx","useRef","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/react/ScrollSequence.tsx","../src/react/useScrollSequence.ts","../src/controllers/imageController.ts","../src/sequence/sequenceResolver.ts","../src/core/clamp.ts","../src/react/scrollTimelineContext.ts","../src/react/useScrollTimeline.ts","../src/react/ScrollTimelineProvider.tsx","../src/core/loopManager.ts","../src/constants.ts","../src/core/scrollTimeline.ts","../src/react/ScrollText.tsx","../src/react/ScrollWordReveal.tsx"],"sourcesContent":["import React, { useRef } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { useScrollSequence } from './useScrollSequence';\nimport { ScrollTimelineProvider } from './ScrollTimelineProvider';\n\n\ninterface InnerSequenceProps {\n source: ScrollSequenceProps['source'];\n debug: boolean;\n memoryStrategy: ScrollSequenceProps['memoryStrategy'];\n lazyBuffer?: number;\n accessibilityLabel?: string;\n fit?: React.CSSProperties['objectFit']; // Add fit prop here\n fallback?: React.ReactNode;\n onError?: (error: Error) => void;\n}\n\nconst InnerSequence: React.FC<InnerSequenceProps> = ({\n source,\n debug,\n memoryStrategy,\n lazyBuffer,\n accessibilityLabel = \"Scroll sequence\",\n fit = 'cover', // Default to cover\n fallback,\n onError\n}) => {\n const debugRef = useRef<HTMLDivElement>(null);\n const { canvasRef, isLoaded } = useScrollSequence({\n source,\n debugRef,\n memoryStrategy,\n lazyBuffer,\n onError\n });\n\n // Fallback logic could be handled here or by parent.\n // If we handle it here, we overlay it?\n // Actually, canvas opacity handles the fade-in.\n // Use fallback if provided and not loaded.\n\n const canvasStyle: React.CSSProperties = {\n display: 'block',\n width: '100%',\n height: '100%',\n objectFit: fit, // Use the prop\n opacity: isLoaded ? 1 : 0,\n transition: 'opacity 0.2s ease-in',\n };\n\n const debugStyle: React.CSSProperties = {\n position: 'absolute',\n top: '10px',\n left: '10px',\n background: 'rgba(0, 0, 0, 0.7)',\n color: '#00ff00',\n padding: '8px',\n borderRadius: '4px',\n fontFamily: 'monospace',\n fontSize: '12px',\n pointerEvents: 'none',\n whiteSpace: 'pre-wrap',\n zIndex: 9999,\n };\n\n return (\n <>\n {/* Render fallback behind canvas, or replace? \n If replace, we might loose the canvas ref init?\n Better to render both and cross-fade or just hide fallback when loaded.\n */}\n {!isLoaded && fallback && (\n <div style={{ position: 'absolute', inset: 0, zIndex: 1 }}>\n {fallback}\n </div>\n )}\n\n <canvas\n ref={canvasRef}\n style={canvasStyle}\n role=\"img\"\n aria-label={accessibilityLabel}\n />\n {debug && <div ref={debugRef} style={debugStyle}>Waiting for scroll...</div>}\n </>\n );\n};\n\nexport const ScrollSequence = React.forwardRef<HTMLDivElement, ScrollSequenceProps>(\n (props, ref) => {\n const {\n source,\n scrollLength = '300vh',\n className = '',\n debug = false,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n fallback,\n fit = 'cover', // Default here too\n accessibilityLabel,\n onError,\n children // Extract children\n } = props;\n\n // Check for reduced motion\n // ... logic for reduced motion could be here or inside hook\n\n return (\n <ScrollTimelineProvider\n scrollLength={scrollLength}\n className={className}\n style={{ position: 'relative' }} // Ensure container is relative\n containerRef={ref as React.RefObject<HTMLDivElement>}\n >\n <InnerSequence\n source={source}\n debug={debug}\n memoryStrategy={memoryStrategy}\n lazyBuffer={lazyBuffer}\n fallback={fallback}\n accessibilityLabel={accessibilityLabel}\n onError={onError}\n fit={fit as any} // Pass fit prop\n />\n {/* Render children ON TOP of canvas */}\n <div style={{ position: 'absolute', inset: 0, zIndex: 10, pointerEvents: 'none' }}>\n {children}\n </div>\n </ScrollTimelineProvider>\n );\n }\n);\n","import { useRef, useEffect, useState } from 'react';\nimport type { ScrollSequenceProps } from '../types';\nimport { ImageController } from '../controllers/imageController';\nimport { resolveSequence } from '../sequence/sequenceResolver';\nimport { clamp } from '../core/clamp';\nimport { useScrollTimeline } from './useScrollTimeline';\n\ninterface UseScrollSequenceParams {\n source: ScrollSequenceProps['source'];\n debugRef?: React.MutableRefObject<HTMLDivElement | null>;\n memoryStrategy?: 'eager' | 'lazy';\n lazyBuffer?: number;\n onError?: (error: Error) => void;\n}\n\n/**\n * Hook to manage image sequence in a timeline context.\n * MUST be used inside ScrollTimelineProvider.\n */\nexport function useScrollSequence({\n source,\n debugRef,\n memoryStrategy = 'eager',\n lazyBuffer = 10,\n onError,\n}: UseScrollSequenceParams) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const controllerRef = useRef<ImageController | null>(null);\n \n // Use the shared timeline\n const { subscribe } = useScrollTimeline();\n\n const [isLoaded, setIsLoaded] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let active = true;\n let currentController: ImageController | null = null;\n let unsubscribeTimeline: (() => void) | null = null;\n\n const init = async () => {\n setIsLoaded(false);\n setError(null);\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n try {\n // 1. Resolve Sequence\n // Guard: source change handled by effect dep, but verify environment?\n if (typeof window === 'undefined') return;\n\n const sequence = await resolveSequence(source);\n if (!active) return;\n\n if (sequence.frames.length === 0) {\n return;\n }\n\n // 2. Setup Dimensions (Initial)\n if (typeof window !== 'undefined') {\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n }\n\n // 3. Initialize Controller\n currentController = new ImageController({\n canvas,\n frames: sequence.frames,\n strategy: memoryStrategy,\n bufferSize: lazyBuffer\n });\n controllerRef.current = currentController;\n\n // 4. Subscribe to Timeline\n unsubscribeTimeline = subscribe((progress) => {\n if (!currentController) return;\n const clamped = clamp(progress);\n currentController.update(clamped);\n\n // Debug Overlay\n if (debugRef?.current) {\n const frameIndex = Math.floor(clamped * (sequence.frames.length - 1));\n debugRef.current.innerText = `Progress: ${clamped.toFixed(2)}\\nFrame: ${frameIndex + 1} / ${sequence.frames.length}`;\n }\n });\n\n if (active) setIsLoaded(true);\n\n } catch (err) {\n if (active) {\n const e = err instanceof Error ? err : new Error('Unknown initialization error');\n setError(e);\n if (onError) onError(e);\n }\n }\n };\n\n init();\n\n return () => {\n active = false;\n currentController?.destroy();\n controllerRef.current = null;\n if (unsubscribeTimeline) unsubscribeTimeline();\n };\n }, [source, memoryStrategy, lazyBuffer, subscribe]); // Re-run if source or timeline changes\n\n return {\n canvasRef,\n isLoaded,\n error\n };\n}\n","/**\n * ImageController\n * Manages canvas rendering, image loading, and frame-by-frame drawing.\n * Handles preloading and caching to minimize redraws.\n */\n\nexport interface ImageControllerConfig {\n /** HTMLCanvasElement to draw on */\n canvas: HTMLCanvasElement;\n\n /** Array of sorted frame URLs */\n frames: string[];\n\n /** Memory management strategy */\n strategy?: 'eager' | 'lazy';\n\n /** Lazy load buffer size (default 10) */\n bufferSize?: number;\n}\n\nexport class ImageController {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private frames: string[];\n private imageCache = new Map<string, HTMLImageElement>();\n private loadingPromises = new Map<string, Promise<HTMLImageElement>>();\n private currentFrameIndex = -1;\n private strategy: 'eager' | 'lazy';\n private bufferSize: number;\n\n /**\n * Create a new ImageController instance.\n *\n * @param config - Configuration object\n * @throws If canvas doesn't support 2D context\n */\n private isDestroyed = false;\n\n constructor(config: ImageControllerConfig) {\n this.canvas = config.canvas;\n this.frames = config.frames;\n this.strategy = config.strategy || 'eager';\n this.bufferSize = config.bufferSize || 10;\n\n const ctx = this.canvas.getContext('2d');\n if (!ctx) {\n throw new Error('Failed to get 2D context from canvas');\n }\n this.ctx = ctx;\n\n // Initial load\n if (this.strategy === 'eager') {\n this.preloadAll();\n } else {\n this.ensureFrameWindow(0);\n }\n }\n\n // ... preloadAll omitted for brevity if unchanged, but let's include for completeness if needed.\n // Actually, we need to add guards to preloadFrame, so let's check it.\n \n private preloadAll(): void {\n this.frames.forEach((_, index) => this.preloadFrame(index));\n }\n\n private ensureFrameWindow(currentIndex: number): void {\n if (this.isDestroyed) return;\n\n const radius = this.bufferSize;\n const start = Math.max(0, currentIndex - radius);\n const end = Math.min(this.frames.length - 1, currentIndex + radius);\n \n const needed = new Set<string>();\n for (let i = start; i <= end; i++) {\n needed.add(this.frames[i]);\n }\n\n // Cleanup unused frames (LRU-ish but simple Window-based)\n for (const [src] of this.imageCache) {\n if (!needed.has(src)) {\n this.imageCache.delete(src);\n // We should also cancel promises if possible, but we can't cancel a fetch/image load easily.\n // We just delete the tracking so we don't cache it when it lands.\n this.loadingPromises.delete(src);\n }\n }\n\n // Load needed\n for (let i = start; i <= end; i++) {\n void this.preloadFrame(i);\n }\n }\n\n async preloadFrame(index: number): Promise<void> {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n\n if (this.imageCache.has(src)) return;\n\n // Deduplication: Reuse existing promise if allowed\n if (!this.loadingPromises.has(src)) {\n this.loadingPromises.set(src, this.loadImage(src));\n }\n\n try {\n await this.loadingPromises.get(src);\n } catch {\n // Failed\n if (!this.isDestroyed) {\n // Silent failure\n }\n }\n }\n\n private loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n \n img.onload = () => {\n if (this.isDestroyed) return;\n \n // Critical: decode() to prevent main-thread jank during draw\n img.decode()\n .then(() => {\n if (this.isDestroyed) return;\n this.imageCache.set(src, img);\n resolve(img);\n })\n .catch(() => {\n if (this.isDestroyed) return;\n // Even if decode fails, the image might be usable\n this.imageCache.set(src, img);\n resolve(img);\n });\n };\n\n img.onerror = () => {\n if (this.isDestroyed) return;\n reject(new Error(`Failed to load image: ${src}`));\n };\n\n img.src = src;\n });\n }\n\n update(progress: number): void {\n if (this.isDestroyed || this.frames.length === 0) return;\n\n const frameIndex = Math.floor(progress * (this.frames.length - 1));\n\n if (this.strategy === 'lazy') {\n this.ensureFrameWindow(frameIndex);\n }\n\n if (frameIndex === this.currentFrameIndex) return;\n\n this.currentFrameIndex = frameIndex;\n this.drawFrame(frameIndex);\n }\n\n private drawFrame(index: number): void {\n if (this.isDestroyed || index < 0 || index >= this.frames.length) return;\n\n const src = this.frames[index];\n const img = this.imageCache.get(src);\n\n if (!img) {\n // Frame not ready. Optional: Show loading spinner or keep previous frame?\n // For now, keep previous (natural behavior of canvas).\n // Or check promise\n const promise = this.loadingPromises.get(src);\n if (promise) {\n promise.then(() => {\n if (this.currentFrameIndex === index) {\n this.drawFrame(index);\n }\n }).catch(() => {}); // catch ignore\n }\n return;\n }\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n const scale = Math.min(\n this.canvas.width / img.width,\n this.canvas.height / img.height\n );\n\n const scaledWidth = img.width * scale;\n const scaledHeight = img.height * scale;\n const x = (this.canvas.width - scaledWidth) / 2;\n const y = (this.canvas.height - scaledHeight) / 2;\n\n this.ctx.drawImage(img, x, y, scaledWidth, scaledHeight);\n }\n\n setCanvasSize(width: number, height: number): void {\n if (this.isDestroyed) return;\n this.canvas.width = width;\n this.canvas.height = height;\n if (this.currentFrameIndex >= 0) {\n this.drawFrame(this.currentFrameIndex);\n }\n }\n\n destroy(): void {\n this.isDestroyed = true;\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.imageCache.clear();\n this.loadingPromises.clear();\n }\n}\n","/**\n * SequenceResolver\n * Handles intelligent frame resolution from multiple input sources:\n * - Manual frame list (frames[])\n * - Pattern generation (pattern, start, end, pad)\n * - Remote manifest (manifest URL)\n */\n\nimport type { ScrollSequenceProps, ResolvedSequence } from '../types';\n\n// Declare process for TS (avoiding @types/node dependency for just this)\ndeclare const process: { env: { NODE_ENV: string } };\n\n/**\n * Resolves frame sequence from props.\n * Prioritizes: frames > pattern > manifest\n */\n/**\n * Resolves frame sequence from props.\n * Handles 'manual', 'pattern', and 'manifest' sources.\n */\nexport async function resolveSequence(source: ScrollSequenceProps['source']): Promise<ResolvedSequence> {\n switch (source.type) {\n case 'manual':\n return processManualFrames(source.frames);\n \n case 'pattern':\n return processPatternMode(source.url, source.start ?? 1, source.end, source.pad);\n \n case 'manifest':\n return processManifestMode(source.url);\n \n default:\n return { frames: [], frameCount: 0 };\n }\n}\n\n/**\n * Mode A: Process manually provided frames\n */\nfunction processManualFrames(frames: string[]): ResolvedSequence {\n // Sort frames numerically by extracting numbers from filenames\n // Uses stable sort to preserve order for frames with no numbers or equal numbers\n const sorted = [...frames].sort((a, b) => {\n const numA = extractNumber(a);\n const numB = extractNumber(b);\n return numA - numB;\n });\n\n return {\n frames: sorted,\n frameCount: sorted.length\n };\n}\n\n/**\n * Mode B: Generate frames from pattern\n */\nfunction processPatternMode(pattern: string, start: number, end: number, pad?: number): ResolvedSequence {\n const frames: string[] = [];\n\n for (let i = start; i <= end; i++) {\n let indexStr = i.toString();\n if (pad) {\n indexStr = indexStr.padStart(pad, '0');\n }\n frames.push(pattern.replace('{index}', indexStr));\n }\n\n return {\n frames,\n frameCount: frames.length\n };\n}\n\n/**\n * Mode C: Fetch and process manifest\n */\nconst manifestCache = new Map<string, Promise<ResolvedSequence>>();\n\nasync function processManifestMode(url: string): Promise<ResolvedSequence> {\n if (manifestCache.has(url)) {\n return manifestCache.get(url)!;\n }\n\n const promise = (async () => {\n try {\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch manifest: ${res.statusText}`);\n }\n \n const data = await res.json();\n \n // Check for \"frames\" array in manifest\n if (data.frames && Array.isArray(data.frames)) {\n return processManualFrames(data.frames);\n }\n \n // Check for pattern config in manifest\n if (data.pattern && typeof data.end === 'number') {\n const start = data.start ?? 1;\n const pad = data.pad;\n return processPatternMode(data.pattern, start, data.end, pad);\n }\n \n return { frames: [], frameCount: 0 };\n \n } catch (err) {\n // Remove from cache on error so retry is possible\n manifestCache.delete(url);\n throw err;\n }\n })();\n\n manifestCache.set(url, promise);\n return promise;\n}\n\n// --- Helpers ---\n\n/**\n * Extract the first number found in a filename.\n * Returns -1 if no number is found, to differentiate from 0.\n */\nfunction extractNumber(filename: string): number {\n const match = filename.match(/\\d+/);\n return match ? parseInt(match[0], 10) : -1;\n}\n\n","/**\n * Clamps a value between a minimum and maximum.\n * Default range is [0, 1], suitable for progress values.\n *\n * @param value - The value to clamp\n * @param min - Minimum value (default: 0)\n * @param max - Maximum value (default: 1)\n * @returns The clamped value\n */\nexport function clamp(value: number, min: number = 0, max: number = 1): number {\n return Math.max(min, Math.min(max, value));\n}\n","import { createContext, useContext } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\n\nexport interface ScrollTimelineContextValue {\n timeline: ScrollTimeline | null;\n // Expose current progress? No, that causes re-renders. Use subscription.\n}\n\nexport const ScrollTimelineContext = createContext<ScrollTimelineContextValue>({\n timeline: null,\n});\n\nexport function useTimelineContext() {\n return useContext(ScrollTimelineContext);\n}\n","import { ScrollTimeline, TimelineCallback } from '../core/scrollTimeline';\nimport { useTimelineContext } from './scrollTimelineContext';\n\nexport interface UseScrollTimelineResult {\n /** \n * Manual subscription to the timeline. \n * Useful for low-level DOM updates (refs) without re-rendering.\n */\n subscribe: (callback: TimelineCallback) => () => void;\n \n /** The raw timeline instance (for advanced usage) */\n timeline: ScrollTimeline | null; \n}\n\nexport function useScrollTimeline(): UseScrollTimelineResult {\n const { timeline } = useTimelineContext();\n\n const subscribe = (callback: TimelineCallback) => {\n if (!timeline) return () => {};\n return timeline.subscribe(callback);\n };\n\n return { subscribe, timeline };\n}\n","import React, { useRef, useState } from 'react';\nimport { ScrollTimeline } from '../core/scrollTimeline';\nimport { ScrollTimelineContext } from './scrollTimelineContext';\n\nexport interface ScrollTimelineProviderProps {\n children: React.ReactNode;\n\n /** CSS height for the scroll container (e.g., \"300vh\"). */\n scrollLength?: string;\n\n\n className?: string;\n style?: React.CSSProperties;\n /** Optional ref for the container element. */\n containerRef?: React.RefObject<HTMLDivElement>;\n}\n\nexport function ScrollTimelineProvider({\n children,\n scrollLength = '300vh',\n className = '',\n style = {},\n containerRef: externalRef,\n}: ScrollTimelineProviderProps) {\n const internalRef = useRef<HTMLDivElement>(null);\n const containerRef = externalRef || internalRef;\n const [timeline, setTimeline] = useState<ScrollTimeline | null>(null);\n\n // Use layout effect to ensure timeline exists before children effects run\n // SSR safe fallback: use useEffect on server\n const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;\n\n useIsomorphicLayoutEffect(() => {\n if (typeof window === 'undefined') return;\n if (!containerRef.current) return;\n\n // Future-proof: factory could be passed via props\n const instance = new ScrollTimeline(containerRef.current);\n\n // We do NOT call start() anymore, it starts on subscription\n // instance.start(); \n\n setTimeline(instance);\n\n return () => {\n instance.destroy();\n setTimeline(null);\n };\n }, []); // Dependencies? strict empty for one-time setup\n\n const containerStyle: React.CSSProperties = {\n height: scrollLength,\n position: 'relative',\n width: '100%',\n ...style,\n };\n\n const stickyWrapperStyle: React.CSSProperties = {\n position: 'sticky',\n top: 0,\n height: '100vh',\n width: '100%',\n overflow: 'hidden',\n };\n\n // Memoize context value to prevent unnecessary re-renders of consumers\n // when Parent component renders but timeline instance hasn't changed.\n const contextValue = React.useMemo(() => ({ timeline }), [timeline]);\n\n return (\n <ScrollTimelineContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n className={className}\n style={containerStyle}\n >\n <div style={stickyWrapperStyle}>\n {children}\n </div>\n </div>\n </ScrollTimelineContext.Provider>\n );\n}\n","/**\n * ScrollLoopManager\n * \n * Singleton class to manage a single requestAnimationFrame loop\n * for all ScrollTimeline instances. This prevents multiple RAF\n * callbacks from piling up and degrading performance.\n */\n\ntype LoopCallback = () => void;\n\nexport class ScrollLoopManager {\n private static instance: ScrollLoopManager;\n private callbacks = new Set<LoopCallback>();\n private rafId: number | null = null;\n private isActive = false;\n\n private constructor() {}\n\n public static getInstance(): ScrollLoopManager {\n if (!ScrollLoopManager.instance) {\n ScrollLoopManager.instance = new ScrollLoopManager();\n }\n return ScrollLoopManager.instance;\n }\n\n /**\n * Register a callback to be called on every animation frame.\n */\n public register(callback: LoopCallback): void {\n if (this.callbacks.has(callback)) return;\n \n this.callbacks.add(callback);\n \n // Start loop if this is the first subscriber\n if (this.callbacks.size === 1) {\n this.start();\n }\n }\n\n /**\n * Unregister a callback.\n */\n public unregister(callback: LoopCallback): void {\n this.callbacks.delete(callback);\n\n // Stop loop if no subscribers left\n if (this.callbacks.size === 0) {\n this.stop();\n }\n }\n\n private start(): void {\n if (this.isActive) return;\n this.isActive = true;\n \n // Ensure we are in a browser environment\n if (typeof window !== 'undefined') {\n this.tick();\n }\n }\n\n private stop(): void {\n this.isActive = false;\n if (this.rafId !== null && typeof window !== 'undefined') {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private tick = (): void => {\n if (!this.isActive) return;\n\n // Execute all registered callbacks\n this.callbacks.forEach(cb => {\n try {\n cb();\n } catch (e) {\n // Silent catch to prevent loop crash\n }\n });\n\n this.rafId = requestAnimationFrame(this.tick);\n };\n}\n","/**\n * Global Constants for React Scroll Media\n */\n\n// Scroll Logic\nexport const SCROLL_THRESHOLD = 0.0001; // Minimum progress change to trigger update\nexport const DEFAULT_SCROLL_LENGTH = '300vh';\n\n// Memory Management\nexport const DEFAULT_LAZY_BUFFER = 10;\nexport const MAX_CACHE_SIZE = 50; // Fallback max size if not dynamic\n\n// Sequences\nexport const DEFAULT_PAD_LENGTH = 0; // Default padding for image numbering\n\n// Styles & Layout\nexport const DEFAULT_FALLBACK_COLOR = '#ccc';\n","import { ScrollLoopManager } from './loopManager';\nimport { SCROLL_THRESHOLD } from '../constants';\n\nexport type TimelineCallback = (progress: number) => void;\n\nexport class ScrollTimeline {\n private container: Element;\n private subscribers = new Set<TimelineCallback>();\n private currentProgress = 0;\n \n // Caching for performance\n private cachedRect: DOMRect | null = null;\n private cachedScrollParent: Element | Window | null = null;\n private cachedScrollParentRect: DOMRect | null = null;\n private cachedViewportHeight = 0;\n private cachedOffsetTop = 0;\n private isLayoutDirty = true;\n private resizeObserver: ResizeObserver | null = null;\n\n public readonly id = typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).substring(2, 9);\n\n constructor(container: Element) {\n this.container = container;\n \n if (typeof window !== 'undefined') {\n // Invalidate cache on resize\n this.resizeObserver = new ResizeObserver(() => {\n this.isLayoutDirty = true;\n });\n this.resizeObserver.observe(this.container);\n if (document.body) {\n this.resizeObserver.observe(document.body);\n }\n \n // Also listen to global resize\n window.addEventListener('resize', this.onWindowResize);\n }\n }\n\n private onWindowResize = () => {\n this.isLayoutDirty = true;\n };\n\n /**\n * Subscribe to progress updates.\n * Returns an unsubscribe function.\n */\n subscribe(callback: TimelineCallback): () => void {\n this.subscribers.add(callback);\n \n // Immediately call with current progress for initialization\n try {\n callback(this.currentProgress);\n } catch (e) {\n // Silent\n }\n\n // Register with unique LoopManager if we have subscribers\n if (this.subscribers.size === 1) {\n ScrollLoopManager.getInstance().register(this.tick);\n }\n \n return () => {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n };\n }\n\n unsubscribe(callback: TimelineCallback): void {\n this.subscribers.delete(callback);\n if (this.subscribers.size === 0) {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n }\n\n /**\n * Start is now handled by LoopManager via subscriptions\n * Deprecated but kept for API stability if needed.\n */\n start(): void {\n // No-op, managed by subscriptions\n }\n\n stop(): void {\n ScrollLoopManager.getInstance().unregister(this.tick);\n }\n\n private tick = (): void => {\n // Calculate Progress\n const progress = this.calculateProgress();\n\n // Notify if changed significantly (using threshold constant)\n if (Math.abs(progress - this.currentProgress) > SCROLL_THRESHOLD) {\n this.currentProgress = progress;\n this.notify();\n }\n };\n\n private notify() {\n this.subscribers.forEach((cb) => {\n try {\n cb(this.currentProgress);\n } catch (e) {\n // Silent\n }\n });\n }\n\n private updateCache() {\n if (!this.isLayoutDirty && this.cachedRect) return;\n\n this.cachedRect = this.container.getBoundingClientRect();\n \n if (!this.cachedScrollParent) {\n this.cachedScrollParent = this.getScrollParent(this.container);\n }\n\n if (this.cachedScrollParent instanceof Element) {\n this.cachedScrollParentRect = this.cachedScrollParent.getBoundingClientRect();\n this.cachedViewportHeight = this.cachedScrollParentRect.height;\n this.cachedOffsetTop = this.cachedScrollParentRect.top;\n } else if (typeof window !== 'undefined') {\n this.cachedViewportHeight = window.innerHeight;\n this.cachedOffsetTop = 0;\n }\n\n this.isLayoutDirty = false;\n }\n\n private calculateProgress(): number {\n if (this.isLayoutDirty || !this.cachedRect) {\n this.updateCache();\n }\n\n const currentRect = this.container.getBoundingClientRect();\n const scrollDist = (this.cachedRect?.height || currentRect.height) - this.cachedViewportHeight;\n\n // Guard: Zero Height / Division by Zero\n if (scrollDist <= 0) return 1;\n\n const relativeTop = currentRect.top - this.cachedOffsetTop;\n const rawProgress = -relativeTop / scrollDist;\n \n const clamped = Math.min(Math.max(rawProgress, 0), 1);\n \n // Round to 6 decimals to prevent micro-drift\n return Math.round(clamped * 1000000) / 1000000;\n }\n\n private getScrollParent(node: Element): Element | Window {\n if (typeof window === 'undefined') return node; \n\n let current = node.parentElement;\n while (current) {\n const style = getComputedStyle(current);\n if (['auto', 'scroll'].includes(style.overflowY)) {\n return current;\n }\n current = current.parentElement;\n }\n return window;\n }\n\n destroy() {\n this.subscribers.clear();\n ScrollLoopManager.getInstance().unregister(this.tick);\n \n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n if (typeof window !== 'undefined') {\n window.removeEventListener('resize', this.onWindowResize);\n }\n }\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollTextProps {\n children: React.ReactNode;\n /** Progress start (0-1) where ENTRANCE animation begins */\n start?: number;\n /** Progress end (0-1) where ENTRANCE animation ends */\n end?: number;\n \n /** Progress start (0-1) where EXIT animation begins. If omitted, element stays visible. */\n exitStart?: number;\n /** Progress end (0-1) where EXIT animation ends */\n exitEnd?: number;\n\n /** Initial opacity */\n initialOpacity?: number;\n /** Target opacity (when entered) */\n targetOpacity?: number;\n /** Final opacity (after exit) */\n finalOpacity?: number;\n\n /** Y-axis translation range in pixels (e.g., 50 means move down 50px) */\n translateY?: number;\n \n style?: React.CSSProperties;\n className?: string;\n}\n\nexport function ScrollText({\n children,\n start = 0,\n end = 0.2,\n exitStart,\n exitEnd,\n initialOpacity = 0,\n targetOpacity = 1,\n finalOpacity = 0,\n translateY = 50,\n style,\n className,\n}: ScrollTextProps) {\n const ref = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n useEffect(() => {\n // Subscribe to updates\n if (typeof window === 'undefined') return;\n\n const unsubscribe = subscribe((progress) => {\n if (!ref.current) return;\n\n // Check for reduced motion preference\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n // If reduced motion is preferred, disable translation (keep opacity fade)\n const effectiveTranslateY = prefersReducedMotion ? 0 : translateY;\n\n let opacity = initialOpacity;\n let currentY = effectiveTranslateY;\n\n // 1. Entrance Phase\n if (progress < start) {\n opacity = initialOpacity;\n currentY = effectiveTranslateY;\n } else if (progress >= start && progress <= end) {\n const local = (progress - start) / (end - start);\n opacity = initialOpacity + (targetOpacity - initialOpacity) * local;\n currentY = effectiveTranslateY * (1 - local);\n } \n // 2. Hold Phase\n else if (!exitStart || progress < exitStart) {\n opacity = targetOpacity;\n currentY = 0;\n }\n // 3. Exit Phase\n else if (exitStart && exitEnd && progress >= exitStart && progress <= exitEnd) {\n const local = (progress - exitStart) / (exitEnd - exitStart);\n opacity = targetOpacity + (finalOpacity - targetOpacity) * local;\n // Move from 0 -> -translateY (or 0 if reduced motion)\n currentY = -effectiveTranslateY * local; \n }\n // 4. Final Phase\n else {\n opacity = finalOpacity;\n currentY = -effectiveTranslateY;\n }\n\n // Apply styles\n ref.current.style.opacity = opacity.toFixed(3);\n ref.current.style.transform = `translateY(${currentY}px)`;\n });\n\n return unsubscribe;\n }, [subscribe, start, end, exitStart, exitEnd, initialOpacity, targetOpacity, finalOpacity, translateY]);\n\n return (\n <div \n ref={ref} \n className={className}\n style={{\n opacity: initialOpacity, \n transform: `translateY(${translateY}px)`,\n transition: 'none', // Critical: no CSS transition fighting JS\n willChange: 'opacity, transform',\n ...style\n }}\n >\n {children}\n </div>\n );\n}\n","import React, { useRef, useEffect } from 'react';\nimport { useScrollTimeline } from './useScrollTimeline';\n\nexport interface ScrollWordRevealProps {\n text: string;\n /** Progress start (0-1) */\n start?: number;\n /** Progress end (0-1) */\n end?: number;\n className?: string;\n style?: React.CSSProperties;\n /** Stagger delay factor (not used in pure scroll map, simpler logic: map word index to sub-progress) */\n}\n\nexport function ScrollWordReveal({\n text,\n start = 0,\n end = 1,\n className,\n style\n}: ScrollWordRevealProps) {\n // We cannot create refs in loop dynamically in top level easily without array.\n // Better to have one parent ref and querySelectorAll children, OR use callback refs.\n const containerRef = useRef<HTMLDivElement>(null);\n const { subscribe } = useScrollTimeline();\n\n // Split words\n const words = text.split(/\\s+/);\n\n useEffect(() => {\n const unsubscribe = subscribe((globalProgress) => {\n if (!containerRef.current) return;\n const spans = containerRef.current.children;\n \n // Map global progress to local range [start, end]\n let localProgress = 0;\n if (globalProgress <= start) localProgress = 0;\n else if (globalProgress >= end) localProgress = 1;\n else localProgress = (globalProgress - start) / (end - start);\n\n // Calculate which word should be visible\n const totalWords = spans.length;\n const progressPerWord = 1 / totalWords;\n\n for (let i = 0; i < totalWords; i++) {\n const span = spans[i] as HTMLElement;\n \n // Each word fades in during its \"slot\"\n // Word 0: 0 -> 0.1\n // Word 1: 0.1 -> 0.2\n const wordStart = i * progressPerWord;\n const wordEnd = (i + 1) * progressPerWord;\n \n let wordOpacity = 0;\n if (localProgress >= wordEnd) {\n wordOpacity = 1;\n } else if (localProgress <= wordStart) {\n wordOpacity = 0.1; // faint visibility initially? or 0\n } else {\n // Interpolate\n wordOpacity = 0.1 + 0.9 * ((localProgress - wordStart) / (wordEnd - wordStart));\n }\n \n span.style.opacity = wordOpacity.toFixed(2);\n // Optional: translate Y too?\n const translate = (1 - wordOpacity) * 10;\n span.style.transform = `translateY(${translate}px)`;\n }\n });\n\n return unsubscribe;\n }, [subscribe, start, end]);\n\n return (\n <div ref={containerRef} className={className} style={{ ...style, display: 'flex', flexWrap: 'wrap', gap: '0.25em' }}>\n {words.map((word, i) => (\n <span \n key={i} \n style={{ \n opacity: 0.1, \n transform: 'translateY(10px)',\n transition: 'none',\n willChange: 'opacity, transform'\n }}\n >\n {word}\n </span>\n ))}\n </div>\n );\n}\n"],"mappings":"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","names":["React","useRef","useRef","useState","useRef","useState","jsx","useRef","React","useRef","useEffect","jsx","useRef","useEffect","useRef","useEffect","jsx","useRef","useEffect"]}
|