小程序中绘制二维码

小序

一个新的小程序项目,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存到微信服务器及自己的服务器里就可以避免这个问题了

嗖嗖嗖~ 传送门

猜你喜欢

转载自blog.csdn.net/my_atlassian_yhl/article/details/84297613