Files
Test_animation/src/imageCanvas.jsx
2023-01-19 10:57:28 +03:00

75 lines
1.8 KiB
JavaScript

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 (
<div style={{height: scrollHeight}}>
<canvas ref={canvasRef}/>
</div>
);
};
export default ImageCanvas