import {useEffect, useRef, useState} from "react"; function getCurrentFrame(index) { return `/images/${index .toString() .padStart(4, "0")}.jpg`; } const ImageCanvas = ({scrollHeight, numFrames, width, height}) => { const canvasRef = useRef(null); const [images, setImages] = useState([]); const [frameIndex, setFrameIndex] = useState(0); function preloadImages() { for (let i = 1; i <= numFrames; i++) { const img = new Image(); const imgSrc = getCurrentFrame(i); img.src = imgSrc; setImages((prevImages) => [...prevImages, img]); } } const handleScroll = () => { const scrollFraction = window.scrollY / (scrollHeight - window.innerHeight); const index = Math.min( numFrames - 1, Math.ceil(scrollFraction * numFrames) ); if (index <= 0 || index > numFrames) { return; } setFrameIndex(index); }; const renderCanvas = () => { const context = canvasRef.current.getContext("2d"); context.canvas.width = width; context.canvas.height = height; }; useEffect(() => { preloadImages(); renderCanvas(); window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); useEffect(() => { if (!canvasRef.current || images.length < 1) { return; } const context = canvasRef.current.getContext("2d"); let requestId; console.log(frameIndex) const render = () => { context.drawImage(images[frameIndex], 0, 0); requestId = requestAnimationFrame(render); }; render(); return () => cancelAnimationFrame(requestId); }, [frameIndex, images]); return (
); }; export default ImageCanvas