129 lines
3.7 KiB
JavaScript
129 lines
3.7 KiB
JavaScript
|
// import extend from 'extend'
|
||
|
import {
|
||
|
QRCode,
|
||
|
QRErrorCorrectLevel
|
||
|
} from './qrcode'
|
||
|
|
||
|
// support Chinese
|
||
|
function utf16to8(str) {
|
||
|
var out, i, len, c
|
||
|
out = ''
|
||
|
len = str.length
|
||
|
for (i = 0; i < len; i++) {
|
||
|
c = str.charCodeAt(i)
|
||
|
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||
|
out += str.charAt(i)
|
||
|
} else if (c > 0x07FF) {
|
||
|
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
|
||
|
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
|
||
|
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
|
||
|
} else {
|
||
|
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
|
||
|
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
|
||
|
}
|
||
|
}
|
||
|
return out
|
||
|
}
|
||
|
|
||
|
function drawQrcode(Taro, opt) {
|
||
|
let defaultOpt = {
|
||
|
canvasId: 'myQrcode',
|
||
|
canvas: null,
|
||
|
text: '爱一个人就要勇敢说出来',
|
||
|
width: 260,
|
||
|
padding: 20,
|
||
|
paddingColor: null, // 默认与background一致
|
||
|
typeNumber: -1,
|
||
|
correctLevel: QRErrorCorrectLevel.H,
|
||
|
background: '#ffffff',
|
||
|
foreground: '#000000',
|
||
|
image: {
|
||
|
imageResource: '',
|
||
|
width: 80,
|
||
|
height: 80,
|
||
|
round: true
|
||
|
}
|
||
|
}
|
||
|
let options = defaultOpt
|
||
|
for (let key in opt) {
|
||
|
options[key] = opt[key]
|
||
|
}
|
||
|
|
||
|
if (!options.canvasId && !options.canvas) {
|
||
|
console.warn('please set canvasId or canvas!')
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if (!options.paddingColor) options.paddingColor = options.background
|
||
|
|
||
|
// createCanvas
|
||
|
// create the qrcode itself
|
||
|
var qrcode = new QRCode(options.typeNumber, options.correctLevel)
|
||
|
qrcode.addData(utf16to8(options.text))
|
||
|
qrcode.make()
|
||
|
|
||
|
const dpr = Taro.getSystemInfoSync().pixelRatio
|
||
|
var canvas = options.canvas
|
||
|
const ctx = canvas.getContext('2d')
|
||
|
canvas.width = options.width * dpr
|
||
|
canvas.height = options.width * dpr
|
||
|
const width = canvas.width
|
||
|
console.log(`canvas, ctx, width, dpr, qrcode, options`, canvas, ctx, width, dpr, qrcode, options)
|
||
|
|
||
|
// 填充背景色
|
||
|
ctx.fillStyle = options.paddingColor
|
||
|
// ctx.clearRect(0, 0, width + options.padding * 2, width + options.padding * 2) // 绘制前清空画布
|
||
|
ctx.fillRect(0, 0, width + options.padding * 2, width + options.padding * 2);
|
||
|
|
||
|
var tileW = (width - options.padding * 2) / qrcode.getModuleCount()
|
||
|
var tileH = (width - options.padding * 2) / qrcode.getModuleCount()
|
||
|
|
||
|
// 绘制二维码
|
||
|
for (var row = 0; row < qrcode.getModuleCount(); row++) {
|
||
|
for (var col = 0; col < qrcode.getModuleCount(); col++) {
|
||
|
ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background
|
||
|
var w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW))
|
||
|
var h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW))
|
||
|
ctx.fillRect(Math.round(col * tileW) + options.padding, Math.round(row * tileH) + options.padding, w, h);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 绘制中心图标
|
||
|
if (options.image.imageResource) {
|
||
|
const imgW = options.image.width * dpr
|
||
|
const imgH = options.image.height * dpr
|
||
|
const dx = (width - imgW) / 2
|
||
|
const dy = (width - imgH) / 2
|
||
|
if (options.image.round) {
|
||
|
// Logo边框
|
||
|
const imgW2 = options.image.width * dpr + 30
|
||
|
const dx2 = (width - imgW2) / 2
|
||
|
const r2 = imgW2 / 2
|
||
|
const cx2 = dx2 + r2;
|
||
|
ctx.beginPath();
|
||
|
ctx.arc(cx2, cx2, r2, 0, 2 * Math.PI);
|
||
|
ctx.fillStyle = '#ffffff'
|
||
|
ctx.fill();
|
||
|
ctx.restore();
|
||
|
|
||
|
// 画Logo
|
||
|
const r = imgW / 2
|
||
|
const cx = dx + r;
|
||
|
const cy = dy + r;
|
||
|
ctx.beginPath();
|
||
|
ctx.arc(cx, cy, r, 0, 2 * Math.PI);
|
||
|
ctx.clip();
|
||
|
|
||
|
ctx.drawImage(options.image.imageResource, dx, dy, imgW, imgW);
|
||
|
ctx.restore();
|
||
|
} else {
|
||
|
ctx.drawImage(options.image.imageResource, dx, dy, imgW, imgH)
|
||
|
ctx.restore();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ctx
|
||
|
}
|
||
|
|
||
|
export default drawQrcode
|