要实现小程序上的二维码生成器,想想基于jquery的二维码生成插件有很多,但是小程序是不允许操作dom的,所以自己找了一个纯javascript版的二维码生成源码,然后换汤不换药把其中的hmtl5中的canvas改为小程序的canvas;
效果图:


纯javascript版js源码:
qrcode
1、解读源码,修改绘制canvas部分,源代码如下
draw: function (string, canvas, size, ecc) {
ecclevel = ecc || ecclevel;
canvas = canvas || _canvas;
if (!canvas) {
console.warn('No canvas provided to draw QR code in!')
return;
}
size = size || _size || Math.min(canvas.width, canvas.height);
var frame = genframe(string),
ctx = canvas.getContext('2d'),
px = Math.round(size / (width + 8));
var roundedSize = px * (width + 8),
offset = Math.floor((size - roundedSize) / 2);
size = roundedSize;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, size, size);
ctx.fillStyle = '#000';
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) {
ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
}
}
}
},
2、然后愉快的将代码修改如下:
draw: function (string, canvas, cavW, cavH, ecc) {
ecclevel = ecc || ecclevel;
canvas = canvas || _canvas;
if (!canvas) {
console.warn('No canvas provided to draw QR code in!')
return;
}
var size = Math.min(cavW, cavH);
var frame = this.getFrame(string),
ctx = wx.createContext(),
px = Math.round(size / (width + 8));
var roundedSize = px * (width + 8),
offset = Math.floor((size - roundedSize) / 2);
size = roundedSize;
ctx.clearRect(0, 0, cavW, cavW);
// ctx.setFillStyle('#ffffff');
// ctx.rect(0, 0, size, size);
ctx.setFillStyle('#000000');
// ctx.setLineWidth(1);
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) {
ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
}
}
}
wx.drawCanvas({
canvasId: canvas,
actions: ctx.getActions()
});
}
}
3、哈哈,愉快的运行起来~~~~~~报错!!
WAService.js:3 TypeError: ctx.fillRect is not a function
赶紧看看小程序的api,发现小程序是没有fillRect()方法的,只有rect()方法,所以啪~啪~啪改为如下:
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) {
ctx.rect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
}
}
}
运行,懵逼了,怎么没有二维码呢,我的二维码呢?好吧接着分析rect语fillRect的区别,其实rect方法只是绘制出轮廓,并不会对路径进行填充,所以紧接其后要对其fill填充。
把代码改为如下:
ctx.setFillStyle('#000000');
// ctx.setLineWidth(1);
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) {
ctx.rect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
ctx.fill();
}
}
}
运行~~~噢啦,终于出现期待已久的二维码喽!!

好了,总算完成了,但是怎么生成二维码的时候感觉有点慢呢,于是借用同事的手机(安卓系统)试了一下,输入网址,点击生成~~

崩了,微信直接挂了
好吧接着找原因,感觉影响速度的只能是for循环那块代码,于是把ctx.fill()拿到for最外层;
for (var i = 0; i < width; i++) {
for (var j = 0; j < width; j++) {
if (frame[j * width + i]) {
ctx.rect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
// ctx.fill();
}
}
}
ctx.fill();
运行~~这速度,飞快!自己的小7也不卡了,又用同事的试了一把,没问题。原来对绘制路径填充只需要最后填充就Ok了,我还二逼的对每次绘制进行了填充。
下载地址:生成二维码