小序
一个新的小程序项目,VIP亲子年卡(以下简称客户端), 和一个对应的商家端, 在做的过程中有一个需求,在客户端展示二维码, 商家端扫码获取信息。
既然需求已经订了,就搞一搞绘制二维码
先写元素
<view class='hxm-bg'>
<view class='hxm-show'>
<view class='canvas-img'>
<image src="{{imagePath}}" mode='widthFix'></image>
<view class='fs-28'>参加活动请出示核销码</view>
</view>
</view>
</view>
<view class="canvas-box">
<!-- 正方形 宽高一致-->
<canvas hidden="{{canvasHidden}}" style="width: 686rpx;height: 686rpx;background:#f1f1f1;" canvas-id="mycanvas"/>
</view>
样式
.canvas-box{
position: fixed;
left: -9999em; /* 让canvas放在可视范围外*/
}
.canvas-img{
height: 500rpx;
width: 500rpx;
margin: 0 auto;
position: relative;
}
.canvas-img image {
z-index: 99;
width: 100%;
height: 100%;
}
这生成图片的样式,之前我试过用position各种布局定位,发现还是不称心,最后写成这种
逻辑
qrcode在此处下载http://davidshimjs.github.io/qrcodejs/
const QR = require("../../utils/qrcode.js"); // 引用js
data: {
canvasHidden: false, // canvas显示/隐藏
imagePath:'', // 默认图片路径
qrCodeContent: ''// 默认二维码生成文本 - 后端返参数
},
onload () {
this._htrequest()
},
_htrequest () { // 这是一个接口
let _t = this
wx.request({
...,
success (res) {
let size = _t.setCanvasSize();//动态设置画布大小
let imagePath = wx.getStorageSync('ocs_mini_qrCodeContentImgs')
if (imagePath) { // 取缓存,增强体验
_t_.setData({
imagePath: wx.getStorageSync('ocs_mini_qrCodeContentImgs') || ''
})
} else { // 不存在则生成
let initUrl = res.qrCodeContent;
_t.createQrCode(initUrl, "mycanvas", size.w, size.h);
}
}
})
},
setCanvasSize () { //适配不同屏幕大小的canvas
var size={};
try {
var res = wx.getSystemInfoSync();
var scale = 750/686; // canvas的适配比例;设计稿是750宽 686canvas宽度
var width = res.windowWidth/scale;
var height = width; // canvas画布为正方形
size.w = width;
size.h = height;
} catch (e) {
console.log("获取设备信息失败"+e);
}
return size;
},
createQrCode (url,canvasId,cavW,cavH) {
//调用插件中的draw方法,绘制二维码图片
QR.api.draw(url,canvasId,cavW,cavH)
setTimeout(() => { this.canvasToTempImage();},1000);
},
canvasToTempImage () { //获取生成canvas文件的临时路径,存入data中
let _t = this;
wx.canvasToTempFilePath({
canvasId: 'mycanvas', // 对应元素中的canvasid
success (res) {
var tempFilePath = res.tempFilePath;
_t.setData({
imagePath: tempFilePath,
// canvasHidden:true
});
wx.setStorageSync('ocs_mini_qrCodeContentImgs', tempFilePath)
wx.hideLoading()
},
fail: function (res) {
console.log(res);
}
});
}
这时候会有一个问题, 当你已经成功一次了,缓存记录了, 下次过一阵取的时候,这个图片是会有时效的, 下次的这个路径可能就已经失效了
// wxml 为image图片元素绑定一个error元素
<image src="{{imagePath}}" mode='widthFix' binderror='imageError'></image>
// js
imageError (e) { // 当图片路径失效时,再次生成临时图片路径
var size = this.setCanvasSize();//动态设置画布大小
this.createQrCode(this.data.userInfo.qrCodeContent, "mycanvas", size.w, size.h);
},
还有一个解决方案, 在wx.canvasToTempFilePath成功时候将图片路径wx.upload存到微信服务器及自己的服务器里就可以避免这个问题了