小程序中绘制二维码

小序

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

嗖嗖嗖~ 传送门

### 微信小程序使用 Canvas API 绘制二维码 #### 创建 WXML 文件结构 为了在微信小程序绘制二维码,需创建两个 `canvas` 元素用于分别绘制二维码和背景图像。WXML文件中的代码如下所示: ```html <canvas type="2d" style="width: 750rpx;height: 1260rpx;position:fixed;top: 1000px;left: 0px;z-index: 9999999999;" id="mycanvas"></canvas> <canvas type="2d" style="width: 200rpx;height: 200rpx;position:fixed;top: 1000px;left: 0px;z-index: 9999999999;" id="myQrcode"></canvas> ``` 上述代码定义了一个较大尺寸的画布作为背景图层以及一个小一些的画布专门用来显示二维码[^2]。 #### 编写 JavaScript 实现逻辑 接下来,在对应的 JS 文件里编写函数来控制这两个画布的行为。这里展示如何通过调用自定义工具库的方法完成二维码生成,并将其放置于指定位置上。 ```javascript import util from '../../../utils/common'; Page({ data: { codeStatus: false, }, showCode(){ this.setData({ codeStatus: true }, () => { // 调用工具类方法生成带logo的二维码 util.qrcode2dLogo('code', '798', '/img/1.jpeg'); }); }, hideCode(){ this.setData({ codeStatus: false }) } }) ``` 此部分脚本实现了当用户触发特定事件时(比如点击按钮),会设置状态变量使二维码可见,并立即执行生成操作;而隐藏功能则是简单地改变布尔值关闭视图[^5]。 #### 工具库辅助处理 对于实际项目开发而言,通常还会借助第三方插件或封装好的组件来进行更复杂的图形渲染工作。例如上面提到的例子就依赖了一个名为`util`的对象,它内部包含了几个静态成员函数可以方便快捷地满足不同场景下的需求,像带有公司标志的小程序码制作等特殊效果都能轻松搞定[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值