1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| <template> <div> <!-- 二维码和icon --> <img :src="rediusIconSrc" alt="ICON"> <img :src="qrCodeSrc" alt="qrcode"> <img :src="iconCodeSrc" alt="IconAndQrcode"> <button @click="getQrcode">下载</button> </div> </template> <script> import QRCode from 'qrcode'; // 需安装 qrcode 插件; export default { data() { return { qrCodeSrc: '', rediusIconSrc: '', iconCodeSrc: '', qrCodeW: '200', qrCodeH: '200', codeContext: 'text123', iconScale: 0.2 // icon 占二维码的比例; }; }, mounted() { this.getCanvas(this.codeContext); }, methods: { getQrcode() { let _a = document.createElement('a'); _a.href = this.iconCodeSrc; _a.download = '带有 icon 的二维码'; _a.click(); }, getCanvas(codeContext, option = {errorCorrectionLevel: 'H', margin: 1}) { // 配置参数 参考https://github.com/soldair/node-qrcode#options
QRCode.toDataURL(codeContext, option, (err, url) => { if (err) throw err; this.qrCodeSrc = url;
this.addicon(); }); }, addicon(X = 0, Y = 0, W, H, radius = 5, birderW = 2, borderColor = '#fff', isbgColor = true, bgColor = 'rgba(255,255,255, 1)') { let c = document.createElement('canvas'); c.width = this.qrCodeW * this.iconScale; c.height = this.qrCodeH * this.iconScale; let _w = W || c.width, _h = H || c.height; let ctx = c.getContext('2d');
if (isbgColor) { ctx.fillStyle = bgColor; ctx.fillRect(0, 0, c.width, c.height); } this.drawRoundRect(ctx, X, Y, _w, _h, radius, birderW, borderColor); let img = document.createElement('img');
img.src = 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2069790559,642682254&fm=26&gp=0.jpg';
img.setAttribute('crossOrigin', 'Anonymous'); img.onload = () => { ctx.clip(); ctx.drawImage(img, 0, 0, 40, 40); ctx.restore(); this.rediusIconSrc = c.toDataURL(); this.mergeImg(); }; }, mergeImg() { let c = document.createElement('canvas'); c.width = this.qrCodeW; c.height = this.qrCodeH; let ctx = c.getContext('2d'); let bg = document.createElement('img'); let icon = document.createElement('img'); bg.src = this.qrCodeSrc; icon.src = this.rediusIconSrc;
let _bgLoad = new Promise((resolve, reject) => { try { bg.onload = () => resolve(); } catch (error) { reject(error); } }); let _iconLoad = new Promise((resolve, reject) => { try { icon.onload = () => resolve(); } catch (error) { reject(error); } });
Promise.all([_bgLoad, _iconLoad]).then(res => { let w = this.qrCodeW; let h = this.qrCodeH; let iconW = w * this.iconScale; let iconH = h * this.iconScale; let iconX = (w - iconW) / 2; let iconY = (h - iconH) / 2; ctx.drawImage(bg, 0, 0, w, h); ctx.drawImage(icon, iconX, iconY, iconW, iconH); this.iconCodeSrc = c.toDataURL(); }).catch(e => { console.log('error-', e); }); }, drawRoundRect(ctx, x, y, width, height, radius, lineWidth, lineColor) { ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; ctx.beginPath(); ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2); ctx.lineTo(width - radius + x, y); ctx.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2); ctx.lineTo(width + x, height + y - radius); ctx.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2); ctx.lineTo(radius + x, height + y); ctx.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI); ctx.closePath(); ctx.stroke(); } } }; </script>
|