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 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 ±3 frames in memory for huge sequences (800+ frames)
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** | ~22.0 kB |
328
- | **Gzipped** | ~6.08 kB |
349
+ | **Minified** | ~23.72 kB |
350
+ | **Gzipped** | ~7.11 kB |
329
351
 
330
- ✨ **Zero dependencies** Uses native Canvas API, no heavyweight libraries.
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 containerRef = (0, import_react3.useRef)(null);
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: "cover",
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
- const prefersReducedMotion = import_react4.default.useMemo(() => {
684
- if (typeof window !== "undefined") {
685
- return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
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
- return false;
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 containerRef = useRef2(null);
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: "cover",
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
- const prefersReducedMotion = React2.useMemo(() => {
641
- if (typeof window !== "undefined") {
642
- return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
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
- return false;
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
 
@@ -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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-scroll-media",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Production-ready scroll-driven image sequence rendering component for React",
5
5
  "license": "MIT",
6
6
  "author": "Thanniru Sai Teja",