最近工作中碰到一个需求,实现一个自定义的二维码
- 背景是一张自定义的图片
- 二维码居中展示
- 在微信里长按可识别
类似于下图
经过一番查资料和思考,整理如下
drawImage
canvas可以用这个方法讲一个图片或者视频画入画布中,drawImage函数有三种函数原型
drawImage(image, dx, dy)
drawImage(image, dx, dy, dw, dh)
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
第一个参数image可以用HTMLImageElement,HTMLCanvasElement或者HTMLVideoElement作为参数。dx和dy是image在canvas中定位的坐标值;dw和dh是image在canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值;sx和sy是image所要绘制的起始位置,sw和sh是image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值
一句话概括就是sx,sy是在原图上剪切的起始坐标点,sh,sw则是剪切的高宽.
而dx,dy就是把剪切的图放到画布中的位置,dh,dw则是放到画布的高宽.
说完了概念,现在来实操
需求一
先在html上放个canvas标签
<canvas id="myCanvas" class="my-canvas"></canvas>
然后通过canvas的API创建context对象
var c = document.getElementById ("myCanvas");
var ctx = c.getContext ("2d");
将背景图片绘入
var img = document.getElementById ("bgc");
ctx.drawImage (
img, //图片资源
0, 0, //截取图片的坐标点
img.width, img.height, //截取图片的宽高,这里是原宽高
0, 0, //放入画布中的坐标点
ctx.canvas.width, ctx.canvas.height //截取的图片放入画布的宽高 = 画布的宽高
);
上面的最后两个参数ctx.canvas.width, ctx.canvas.height
的作用是让截取的图片拉伸为画布大小,这样就填充了整个画布.
好了,到此,我们完成了第一个需求.
需求二
先生成一个二维码
var code = $ ('#qrcode').qrcode ({
text: "www.baidu.com",
render: "canvas",
width: 120,
height: 120,
typeNumber: -1,
background: '#FFFFFF',
foreground: '#000000'
});
接下来要怎么样把二维码居中放入画布呢?
我们先来思考绝对定位居中是怎么实现的
<div class="father">
<div class="sone"></div>
</div>
.father{
height:100px:
width:100px;
border:1px solid red;
}
.son{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
可以得出,先把son往下往右移动50%father的宽度和高度.再把son自己往上往左移动自己50%的宽度和高度.就可以实现居中.
同理,canvas的二维码居中也是可以这样实现的
ctx.drawImage (
qrcode,
0, 0,
qrcode.width, //二维码宽度
qrcode.height, //二维码高度
Math.abs (ctx.canvas.width - ctx.canvas.width * 0.5) * 0.5, //放入画布中的起始x坐标
Math.abs (ctx.canvas.height - ctx.canvas.height * 0.5) * 0.5, //放入画布中的起始y坐标
ctx.canvas.width * 0.5, //放入画布中的宽
ctx.canvas.height * 0.5 //放入画布中的高
);
我们用同样的计算方式可以获得放入画布中坐标点,这样就可以让二维码居中了
在微信里长按可识别
canvas得到的图片在微信里是不能被长按识别的,只要改成img就可以了