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.

This is commonly referred to as the artboard size and is used to render the finished graphics. The default value is null.

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