You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a use case where I want users to be able to click a link to download a QR code shown via the <QRCodeCanvas> component. My first attempt was to get a data URL from the canvas via toDataURL() in a ref callback, and set that as the href on a link.
functionMyApp(){const[dataUrl,setDataUrl]=useState('');constcanvasRefCallback=useCallback((canvas)=>{if(!canvas){return;}setDataUrl(canvas.toDataURL());},[]);return(<div><QRCodeCanvasref={canvasRefCallback}value={window.location.href}/>{dataUrl&&<ahref={dataUrl}download="qrcode">Download QR Code</a>}</div>);}
This unfortunately results in a transparent PNG because the <canvas> element is rendered and the ref callback is invoked before the useEffect() that draws the QR code into the canvas has run.
As a workaround, I'm having users click on a button first where I then create a link dynamically and call .click() on it to initiate the download. This is fine, but it's a little silly making users click on a button, so that I can create a link and call .click() on it, when the users themselves could just click on that link.
functionMyApp(){constcanvasRef=useRef();constdownloadLinkRef=useRef();constonDownloadQRCode=useCallback(()=>{constcanvas=canvasRef.current;constdonwloadLink=downloadLinkRef.current;if(!canvas||!downloadLink){return;}downloadLink.href=canvas.toDataURL();downloadLink.download='qrcode';downloadLink.click();},[]);return(<div><QRCodeCanvasref={canvasRef}value={window.location.href}/><buttononClick={onDownloadQRCode}>Download QR code</button><ahiddenref={downloadLinkRef}/></div>);}
Since drawing to the canvas is synchronous, I think the first example could work if <QRCodeCanvas> took a onComplete callback prop that it called at the end of the useEffect() after drawing the QR code has been completed.
functionMyApp(){const[dataUrl,setDataUrl]=useState('');constcanvasRef=useRef();constonDrawQRCodeComplete=useCallback(()=>{constcanvas=canvasRef.current;if(!canvas){return;}setDataUrl(canvas.toDataURL());},[]);return(<div><QRCodeCanvasonComplete={onDrawQRCodeComplete}ref={canvasRef}value={window.location.href}/>{dataUrl&&<ahref={dataUrl}download="qrcode">Download QR Code</a>}</div>);}
I'd be happy to open a PR if this is something everyone is open to.
The text was updated successfully, but these errors were encountered:
I could see this helping. There are a couple "complete" phases so it may make sense to be versatile. For Canvas specifically (where 2 & 3 may actually be done in single pass though I'd expect that to be rare, and 3 may never be done even if an image was specified):
initial DOM created (this also kicks off loading the embedded image) - this is what you're getting stuck on for your ref, which is fair
qrcode drawn to canvas
embedded image drawn to canvas
SVG does 1 & 2 together so would have some differences in reporting. Then there's also the matter of handling updates.
If y'all have an API design with more detail to propose here, I'm open to seeing what we can do :)
I have a use case where I want users to be able to click a link to download a QR code shown via the
<QRCodeCanvas>
component. My first attempt was to get a data URL from the canvas viatoDataURL()
in a ref callback, and set that as the href on a link.This unfortunately results in a transparent PNG because the
<canvas>
element is rendered and the ref callback is invoked before theuseEffect()
that draws the QR code into the canvas has run.As a workaround, I'm having users click on a button first where I then create a link dynamically and call
.click()
on it to initiate the download. This is fine, but it's a little silly making users click on a button, so that I can create a link and call.click()
on it, when the users themselves could just click on that link.Since drawing to the canvas is synchronous, I think the first example could work if
<QRCodeCanvas>
took aonComplete
callback prop that it called at the end of theuseEffect()
after drawing the QR code has been completed.I'd be happy to open a PR if this is something everyone is open to.
The text was updated successfully, but these errors were encountered: