EDIT: This is how I managed to make it work. I realized I had to create the image object inside the initial useEffect hook to prevent it from being reloaded at every re-render, and refer to it later using a ref object. Also, I had to import the image src at the start of the code because if I tried to do it like this: image src = "./images/image.png" later when i created the image object, something called Webpack messed up the path and that's why the image wouldn't draw. I'm not clear on the latter part yet, but at least I got it the code work.
import React, { useRef, useEffect, useState } from "react";
import image1 from "./images/image.png";
function MyCanvasComponent() {
const canvasRef = useRef(null);
const imageRef = useRef(null);
const [imageloaded, setImageloaded] = useState(false);
useEffect(() => {
imageRef.current = new Image();
imageRef.current.onload = () => setImageloaded(true);
imageRef.current.src = image1;
}, []);
function draw(image, x) {
if (canvasRef.current) {
const canvas = canvasRef.current;
const context = canvasRef.current.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(image, x, 0, image.width, image.height);
}
}
let counter = 1;
setInterval(() => {
if (imageloaded) {
if (counter % 2 === 0) {
draw(imageRef.current, 200);
} else draw(imageRef.current, 100);
counter++;
}
}, 1000);
return (
<div>
<canvas ref={canvasRef} width={300} height={200} />
</div>
);
}
function App() {
return (
<div>
<h1>My Canvas App</h1>
<MyCanvasComponent />
</div>
);
}
export default App;
ORIGINAL POST: Using setInterval, I want to show an image moving around on my canvas, which is inside a React component. However, the only way I get the image to display without any errors is when I define the image object inside the very function that draws the image. That way, however, it reloads at every interval, which makes the animation very choppy. When I try to define the image object outside that function, it either doesn't show or gives an error:
Uncaught DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The HTMLImageElement provided is in the 'broken' state.
What am I doing wrong?
this way, it works, but it reloads the image at every interval
function draw() {
const canvas = canvasRef.current;
const context = canvasRef.current.getContext("2d");
const image = new Image();
image.onload = () => {
context.drawImage(image, x, y, laius, korgus);
};
image.src = imageSource;
}
this way (or along these lines, I've tried many ways), I get errors, or nothing displays
function draw() {
const canvas = canvasRef.current;
const context = canvasRef.current.getContext("2d");
context.drawImage(image, x, y, laius, korgus);
}
const image = new Image();
image.onload = () => {
draw();
};
image.src = imageSource;
when I run this, it tells me that it is an HTML image alright
function isImage(i) {
return i instanceof HTMLImageElement;
}