小程序绘制二维码

452 阅读3分钟

首先小程序本身没有绘制二维码的api,就需要用到weapp-qrcode这个库,下载地址:weapp-qrcode

1、首先去github上下载下来,主要用到的是/dist/weapp-qrcode.js这个js文件 

2、定义好canvas和canvas-id 用 wx:if 将会消耗更多资源,因为每次呈现的时候他都会渲染,每次隐藏的时候,他都会销毁;如果用hidden它是已经渲染的,只是控制显示隐藏,所以用hidden能够有更好的效果

<canvas style="margin:0 auto" hidden="{{!isShowQrCode}}" class="user-qrcode-modal-can" canvas-id="myQrcode1"  ></canvas>

3、在对应js文件中引入weapp-qrcode.js

const drawQrcode = require('../../utils/QRcode.js');

4、使用drawQrcode将二维码绘制在canvas中

这里宽高不应该写死,应该是根据每个手机屏幕的宽高动态的设置,下面将会写到

drawQrcode({
            width: 200,
            height: 200,
            ctx: wx.createCanvasContext('myQrcode1', this),
            text: newVal,
})

5、完整代码

因为项目中用到的二维码地方比较多,所以封装成了一个组件,下面是完整的代码

drawQrcode.wxml

<!--components/pay_code/pay_code.wxml-->
<view class="user-qrcode-main-container">
  <!-- <image class="user-qrcode-img" src="{{imagePath}}/docsmall/qrcode.png" catchtap="onClickQR"></image> -->

  <view class="user-qrcode-modal-container" style="pointer-events: {{isShowModal ? 'auto' : 'none'}}">
		<view class="bg-mk {{isShowModal ? 'bg-mk-ac' : ''}}" catchtap="onClickConfirm"></view>
    <!--模态框主体-->
    <view class="user-qrcode-modal-wraper {{isShowModal ?'user-qrcode-modal-wraper-active':'user-qrcode-modal-wraper-unactive'}}">
      
      <!--核销二维码-->
      <view class="code-content" wx:if="{{isShowModal}}">
        <canvas style="margin:0 auto" hidden="{{!isShowQrCode}}" class="user-qrcode-modal-can" canvas-id="myQrcode1"  ></canvas>
      </view>
      <view class="close" catchtap="onClickConfirm">X</view>
    </view>
  </view>
</view>


drawQrcode.wxss

/* components/pay_code/pay_code.wxss */
.user-qrcode-main-container{
  margin-left: 20rpx;
  width: 32rpx;
  /* height: 32rpx; */
}
.mk-click{
  position: absolute;
  top: 0;
  left: 0;
  /* z-index: 99; */
  width: 100%;
  height: 100%;
}
.code-title{
  font-size: 40rpx;
  color: #666;
  margin-top: 30rpx;
  margin-bottom: 16rpx;
  text-align: center;
}
.card-no{
  font-size: 48rpx;
  color: #666666;
  font-weight: 600;
  margin-bottom: 16rpx;
}
.user-qrcode-modal-container{
  position: fixed;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 99;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  /* background: rgba(0, 0, 0, .3); */
}
.bg-mk{
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  width: 100vw;
  height: 100vh;
  opacity: 0;
  transition: opacity cubic-bezier(0, 1.05, 0.6, 1.01) .3s;
  background-color: rgba(255, 255, 255, 1);
}
.bg-mk-ac {
  opacity: 1;
}
.bt-txt{
  color: #666666;
  font-size: 20rpx;
  margin-top: 10rpx;
  margin-bottom: 16rpx;
}
.close{
  color: #db0629;
  font-weight: bolder;
  font-size: 35rpx;
  /* margin-top: 30rpx; */
  /* position: absolute;
  top: 30rpx;
  right: 30rpx;
  z-index: 99; */
}
.user-qrcode-modal-wraper{
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 700rpx;
  /* border-radius: 15px; */
  overflow: hidden;
  background: #fff;
  transition: all 0.3s ease-in-out;
  /* padding-left: 40rpx; */
}
.user-qrcode-modal-wraper-active{
  transform: scale(1);
}
.user-qrcode-modal-wraper-unactive{
  transform: scale(0);
}
.user-qrcode-img {
  width: 120rpx;
  height: 120rpx;
  position: absolute;
  top: 10rpx;
  left: 10rpx;
  z-index: 99;
}
.user-qrcode-modal-confirm-container{
  width: 640rpx;
  height: 100rpx;
  line-height: 100rpx;
  text-align: center;
  font-size: 32rpx;
  color: #1989fa;
}
.user-qrcode-modal-confirm-container:active{
  background: rgb(224, 223, 223);
}
.code-content{
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #fff;
  margin: 25rpx 0;
  width: 670rpx; 
  height: 670rpx;
}
.user-qrcode-modal-can{
  width: 670rpx; 
  height: 670rpx;
  margin: 0 auto;
}

drawQrcode.js

const app = getApp();
const Util = require('../../utils/util.js');
const {
  host
} = require('../../utils/httpUrlUtil.js');
const {
  imageProPath
} = require('../../utils/imageUrlUtil.js');
const drawQrcode = require('../../utils/QRcode.js');

Component({
  /**
   * 组件的属性列表
   */
  properties: {
    code: {
      type: String,
      value: ''
    },
    isShowCode: {
      type: Boolean,
      value: false,
    }
  },

  observers: {
    isShowCode(newVal, oldVal) {
      this.setData({
        isShowModal: newVal
      })
    },
    code(newVal, oldVal) {
      console.log(newVal)
      let that = this;
      let showQrId = setTimeout(() => {
        this.setData({
          isShowQrCode: true
        })
        //我们这里需要根据每个手机屏幕的宽高动态的设置宽高乘以0.88是根据iPhone的宽高比例换算的
        let { screenWidth } = wx.getSystemInfoSync();
        
        drawQrcode({
          width: screenWidth * 0.88,
          height: screenWidth * 0.88,
          ctx: that.qrCanvas,
          //这里的text必须是一个字符串
          text: newVal,
        })
        clearTimeout(showQrId)
      }, 300)
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    //图片主路径
    imagePath: imageProPath,
    //是否展示模态框
    isShowModal: false,
    //是否展示二维码
    isShowQrCode: false,
  },

  attached() {
    this.qrCanvas = wx.createCanvasContext('myQrcode1', this);
  },

  /**
   * 组件的方法列表
   */
  methods: {
    
    //点击X时触发
    onClickConfirm(e) {
      this.setData({
        isShowQrCode: false,
        isShowModal: false
      })
    }
  }
})

这里在canvas中加一个判断是因为ios机型中,点击关闭后canvas的二维码不会消失 画布的宽和高尽量设置的大一点,不然扫码的时会扫不出来或者扫码失败

使用:在父组件中

不要忘记给父容器加相对定位
<view class="discount-item-container">
根据优惠券的唯一券码进行绘制
	<pay_code hidden="{{discountInfo.couponType === 4}}" code="{{code}}" isShowCode="{{isShowQrCode}}" />
	
</view>


//点击优惠卷整体时触发
    onClickDiscount(e) {
      let { discountInfo } = this.data
      console.log(discountInfo.couponType)
      this.triggerEvent('onClickDiscount', discountInfo)
      let tTimeid = setTimeout(() => {
        if(discountInfo.couponType == 4){
          this.setData({
            isShowQrCode: true,
            code: discountInfo.couponCode
          })
        }
        
      }, 400)
      this.setData({
        isShowModal: true
      })
    },

这样就能绘制出来了
要保证二维码的周围都是没有东西的,灰色的蒙层有时候也不可以,所以我设置了一个白色的背景

在这里插入图片描述