'React Uncaught TypeError: canvas.toDataURL is not a function
I'm trying to save my canvas using .toDataURL() but I keep getting the error mentioned in the title.
The canvas and context are initialized as follows:
const canvas = useRef();
let ctx = null;
This is the main function that previews the canvas based on user input:
const onFinish = () => {
ctx?.clearRect(0, 0, canvas.width, canvas.height); //to reset canvas after input update
const canvasEle = canvas.current;
canvasEle.width = canvasEle.clientWidth;
canvasEle.height = canvasEle.clientHeight;
// get context of the canvas
ctx = canvasEle.getContext("2d");
//function that writes text on an image
writeText({
text: textA,
x: 350,
y: 100,
text2: textB,
x2: 350,
y2: 200,
});
//code breaks here
var dataURL = canvas?.toDataURL();
console.log(dataURL);
};
The canvas element is called as follows:
return(
<>
<div className="App">
<h3>Design Ecard</h3>
<canvas ref={canvas}></canvas>
</div>
</>
)
Update Tried using canvas.current.toDataURL() but that returned the URL of an empty canvas. I can also save the image properly by simply right-clicking and selecting Save Image
Update 2 The writeText function
const writeText = async (info) => {
const { text, x, y, text2, x2, y2 } = info;
var imageObj = new Image();
imageObj.onload = function () {
ctx?.drawImage(imageObj, 10, 10);
ctx?.beginPath();
ctx.font = fontSize + "px " + fontFamily;
ctx.textAlign = textAlign;
ctx.textBaseline = "top";
ctx.fillStyle = colorCode;
ctx.fillText(text, x, y);
ctx.fillText(text2, x2, y2);
ctx.stroke();
};
imageObj.src = bgImage;
imageObj.width = "600px";
imageObj.height = "550px";
};
Solution 1:[1]
useRef gives you a plain object whose reference is stable. If you put something in the ref with ref={canvas}, that value doesn't replace the ref, but gets assigned to a property of the ref.
var dataURL = canvas?.toDataURL();
should be
const dataURL = canvas.current?.toDataURL();
I'd also suggest changing the name of the ref from canvas to canvasRef to avoid confusing yourself - it's a ref that holds the canvas, not the canvas itself.
You also need to wait for the image to load before extracting from the canvas. Either call toDataURL inside writeText, or have writeText return a Promise.
const writeText = (info) => new Promise((resolve) => {
const { text, x, y, text2, x2, y2 } = info;
var imageObj = new Image();
imageObj.onload = function () {
ctx?.drawImage(imageObj, 10, 10);
ctx?.beginPath();
ctx.font = fontSize + "px " + fontFamily;
ctx.textAlign = textAlign;
ctx.textBaseline = "top";
ctx.fillStyle = colorCode;
ctx.fillText(text, x, y);
ctx.fillText(text2, x2, y2);
ctx.stroke();
resolve();
};
imageObj.src = bgImage;
imageObj.width = "600px";
imageObj.height = "550px";
});
writeText({
// ...
})
.then(() => {
var dataURL = canvas?.toDataURL();
console.log(dataURL);
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
