我正在尝试使用图像序列创建滚动动画,但不断遇到此错误:
“未捕获的 DOMException:无法在“CanvasRenderingContext2D”上执行“drawImage”:提供的 HTMLImageElement 处于“损坏”状态。 渲染时”
这意味着图像路径不正确,但我几乎可以肯定它是正确的。 “console.log(图像[frameIndex]);”返回具有正确路径的图像元素。还有其他原因会导致我收到此错误吗?
import React, { useRef, useEffect, useState } from 'react';
function getCurrentFrame(index) {
return `${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);
// Step 1: Load images
function preloadImages() {
for (let i = 1; i <= numFrames; i++) {
const img = new Image();
const imgSrc = getCurrentFrame(i);
console.log(imgSrc);
img.src = imgSrc;
setImages((prevImages) => [...prevImages, img]);
}
}
// Step 2: Handle scroll events
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);
};
// Step 3: Set up canvas
const renderCanvas = () => {
const context = canvasRef.current.getContext("2d");
context.canvas.width = width;
context.canvas.height = height;
};
// Step 4: Render images to canvas
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;
const render = () => {
console.log(images[frameIndex]);
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;
虽然我无法完全让这个功能正常工作,但我确实找出了错误,并希望将其放在这里,以防其他人遇到这个问题。通过将图像序列文件夹移动到公共文件夹并更新图像源,我不再收到上述错误。
function getCurrentFrame(index) {
return `/desk/${index.toString().padStart(4, "0")}.jpg`;
}