Reputation: 333
I'm trying to load an image on to a canvas so I can write some text on it and maybe save it later on. I have two below functions:
openImage = (memeURL, index) => {
this.setState({currentMeme: index}, () => {
const base_image = new Image();
base_image.crossOrigin = "anonymous";
base_image.src = memeURL;
const base64 = this.getBase64Image(base_image);
this.setState({currentImagebase64: base64});
})
}
getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL("image/png");
return dataURL;
}
The openImage
function is bound to an onClick
event so when I click an image it fires up the above operations so that my <img src="">
can feed from state and display the image.
The problem is that when i click the image it never shows up and my currentImagebase64
state value is always data;
BUT if debug with web tools it appears fine because theres enough time for the image to load. Aparrently the solution is in the below answer:
canvas.toDataUrl() returns 'data:,'
However, if I write something like suggested the onload
function never triggers. For example below code won't trigger the onload for some reason, it just stops executing when it reaches it:
openImage = (memeURL, index) => {
this.setState({currentMeme: index}, () => {
const base_image = new Image();
base_image.onload = function() {
this.crossOrigin = "anonymous";
}
//Set src AFTER the image has loaded
base_image.src = memeURL;
const base64 = this.getBase64Image(base_image);
this.setState({currentImagebase64: base64});
})
}
Can any subject experts lend a hand please?
Upvotes: 1
Views: 1982
Reputation: 1
const base64 = this.getBase64Image(base_image);
this.setState({currentImagebase64: base64});
needs to be executed once the image has loaded
and
base_image.crossOrigin = "anonymous";
needs to be done before setting the src
So, the code becomes
openImage = (memeURL, index) => {
this.setState({currentMeme: index}, () => {
const base_image = new Image();
base_image.crossOrigin = "anonymous";
base_image.onload = () => { // use arrow function so `this` will be what is needed
const base64 = this.getBase64Image(base_image);
this.setState({currentImagebase64: base64});
}
base_image.src = memeURL;
})
}
Your comment
//Set src AFTER the image has loaded
suggests you don't know how onload works ... you set src which starts loading the image, and then onload is triggered when image finishes loading
Upvotes: 1
Reputation: 2365
I'm not entirely sure how react handles the states as above but I've had a similar issue in vanilla JS in which the src wasn't loading until added to the DOM. Keeping it hidden was fine though:
const image = new Image();
image.onload = (e)=>{
// do something
}
image.src = YOUR_IMAGE_PATH;
image.hidden = true;
// add to body
document.body.appendChild(image); // at this point the src is loaded and onload handler is fired
Upvotes: 0