We need to synthesize the current URL two-dimensional code and the current logo into a picture for users to download, which supports PC and mobile terminal. The following is the picture we need to synthesize
Qr code
To generate the qrcode, use the qrcode.react component
import QRCode from 'qrcode.react';
<QRCode style={{ height: 70, width: 70, display: "none" }} className="QR-code-Img" value={window.localtion.href} />
Copy the code
Then we draw directly, in the picture reference two-dimensional code is good, relatively simple, the page display is OK
const img3 = document.createElement('img'); const getQRdom = document.querySelector('.QR-code-Img'); img3.src = getQRdom.toDataURL("image/png"); CTX. DrawImage (img3, 12.5, 212.5, 65, 65);Copy the code
There was a problem with the download
Our download is also simple, directly convert to base64 download is good, the code is:
const ctx = document.getElementById('myCanvas');
const dom = document.createElement("a");
dom.href = ctx.toDataURL("image/png");
dom.download = new Date().getTime() + ".png";
dom.click();
Copy the code
Third-party images cross domains
It is found that we call img when drawing pictures on canvas, which normally shows no problem on canvas, but when downloading, it will be considered as calling third-party resources, i.e. cross-domain. Therefore, we need to add a source of “crossOrigin”, ‘Anonymous’, when drawing, as follows:
const img3 = document.createElement('img'); img3.setAttribute("crossOrigin", 'Anonymous')img3.src = '*****.jpg'; Img3. Onload = function () {CTX. DrawImage (img3, 12.5, 212.5, 65, 65); }Copy the code
Then the PC side is done
Mobile is a bit of a mess, because it doesn’t support Base64, so we had to figure out how to convert it to binary, so we had to use toBlob, as follows
const ctx = document.getElementById('myCanvas'); canvas.toBlob(blob => {let dom = document.createElement("a"); dom.href = URL.createObjectURL(blob); let filename = `${title}.jpg`; dom.download = filename; dom.filename = filename; dom.click(); },"image/jpeg",1 // [0,1] for image quality);Copy the code
Add a compatibility code
if (! HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { value: function (callback, type, quality) { var binStr = atob(this.toDataURL(type, quality).split(',')[1]), len = binStr.length, arr = new Uint8Array(len); for (var i = 0; i < len; i++) { arr[i] = binStr.charCodeAt(i); } callback(new Blob([arr], { type: type || 'image/png' })); }}); }Copy the code
SecurityError The Operation is insecure SecurityError The operation is insecure The search is all about mobile phone permissions, cross-domain problems, I cross-domain is not solved, what?
The solution
God knows how to solve it, there is no way, delete the code one by one, and then mobile test…
Qrcode.react generates a canvas of its own, but it’s not a canvas of its own, and it’s a canvas of its own, and it’s a canvas of its own. I converted it to Base64 and used it on another canvas, logically, but when downloading, the IMG link read Base64, and the canvas was tainted, so I thought it was risky and changed it to
const getQRdom = document.querySelector('.QR-code-Img'); CTX. DrawImage (getQRdom, 12.5, 212.5, 65, 65);Copy the code
So perfect solution!!
High definition map making
The visual size of our canvas is fixed, but how to draw the hd image within the visual size,
Canvas has two kinds of width and height: 1. One is width and height properties, which are generally called Canvas size, namely the place where the graph is drawn.
Our visual size is the artboard size, so we just need to set the artboard size, and then manually set the canvas size
var device=2 var canvas=document.getElementById('canvas'); canvas.width=canvas. clientWidth*device; canvas.height=canvas.clientHeight*device; // All subsequent sizes *deviceCopy the code