Estoy tratando de guardar mi lienzo usando .toDataURL()
pero sigo recibiendo el error mencionado en el título.
El lienzo y el contexto se inicializan de la siguiente manera:
const canvas = useRef(); let ctx = null;
Esta es la función principal que muestra una vista previa del lienzo en función de la entrada del usuario:
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); };
El elemento canvas se llama de la siguiente manera:
return( <> <div className="App"> <h3>Design Ecard</h3> <canvas ref={canvas}></canvas> </div> </> )
Actualizar Intenté usar canvas.current.toDataURL()
pero devolvió la URL de un lienzo vacío. También puedo guardar la imagen correctamente simplemente haciendo clic derecho y seleccionando Guardar imagen
Actualización 2 La función writeText
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"; };
useRef
te da un objeto simple cuya referencia es estable. Si coloca algo en la referencia con ref={canvas}
, ese valor no reemplaza la referencia, sino que se asigna a una propiedad de la referencia.
var dataURL = canvas?.toDataURL();
debiera ser
const dataURL = canvas.current?.toDataURL();
También sugeriría cambiar el nombre de la referencia de canvas
a canvasRef
para evitar confundirse: es una referencia que sostiene el lienzo, no el lienzo en sí.
También debe esperar a que se cargue la imagen antes de extraerla del lienzo. Llame a toDataURL
dentro de writeText
o haga que writeText
devuelva una Promesa.
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); });