旗下品牌:
石家庄网站开发 石家庄网站开发公司

资讯动态

察而思、思而行、行而后语、知行合一

小程序Canvas实战:轻松生成自定义二维码

发布时间:2025-07-11 热度:

一、二维码在小程序中的应用价值

在小程序开发中,二维码是极其重要的功能组件:

  • 用户分享推广的关键媒介

  • 活动页面入口的便捷方式

  • 支付、登录等安全验证手段

  • 商品、服务的快速识别通道

小程序自带的二维码生成API虽然方便,但存在样式单一、尺寸固定等问题。使用Canvas绘制二维码则提供了无限的自定义可能性!

二、实现思路与核心步骤

1. 技术方案选择

  • 使用第三方库weapp-qrcode生成二维码数据

  • 通过Canvas绘制基础二维码

  • 添加自定义样式和特效

  • 实现二维码保存功能

2. 准备工作

安装二维码生成库:

npm install weapp-qrcode --save

构建npm模块(小程序开发者工具中操作)

三、完整实现代码

WXML布局文件

<view class="container">
  <view class="canvas-container">
    <canvas 
      canvas-id="qrcodeCanvas" 
      style="width: 300px; height: 300px;"
      class="qrcode-canvas"
    ></canvas>
  </view>
  
  <view class="controls">
    <input 
      type="text" 
      placeholder="输入二维码内容" 
      bindinput="onInputChange" 
      value="{{text}}"
      class="input-box"
    />
    
    <view class="style-controls">
      <view class="color-picker">
        <text>主色:</text>
        <input type="color" bindinput="onColorChange" value="{{darkColor}}" />
      </view>
      
      <view class="color-picker">
        <text>背景色:</text>
        <input type="color" bindinput="onBgColorChange" value="{{lightColor}}" />
      </view>
    </view>
    
    <button bindtap="toggleLogo" class="btn">
      {{showLogo ? '移除Logo' : '添加Logo'}}
    </button>
    
    <button bindtap="saveImage" class="btn save-btn">保存到相册</button>
  </view>
</view>

WXSS样式文件

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20rpx;
  background: #f5f5f5;
  min-height: 100vh;
}


.canvas-container {
  background: white;
  border-radius: 16rpx;
  padding: 20rpx;
  box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
  margin-bottom: 40rpx;
}


.controls {
  width: 100%;
  max-width: 600rpx;
}


.input-box {
  width: 100%;
  height: 80rpx;
  background: white;
  border-radius: 8rpx;
  padding: 0 20rpx;
  margin-bottom: 30rpx;
  box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.05);
}


.style-controls {
  display: flex;
  justify-content: space-between;
  margin-bottom: 30rpx;
}


.color-picker {
  display: flex;
  align-items: center;
  background: white;
  padding: 10rpx 20rpx;
  border-radius: 8rpx;
  box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.05);
}


.color-picker text {
  margin-right: 10rpx;
  font-size: 28rpx;
}


.btn {
  width: 100%;
  height: 80rpx;
  line-height: 80rpx;
  background: #07c160;
  color: white;
  border-radius: 8rpx;
  margin-bottom: 20rpx;
  font-size: 32rpx;
}


.save-btn {
  background: #1a6bff;
  margin-top: 30rpx;
}


.qrcode-canvas {
  border: 1rpx solid #eee;
}

JavaScript逻辑代码

import QRCode from 'weapp-qrcode';


Page({
  data: {
    text: 'https://example.com',
    darkColor: '#000000',
    lightColor: '#ffffff',
    showLogo: false
  },


  onReady() {
    this.drawQRCode();
  },


  onInputChange(e) {
    this.setData({ text: e.detail.value });
    this.drawQRCode();
  },


  onColorChange(e) {
    this.setData({ darkColor: e.detail.value });
    this.drawQRCode();
  },


  onBgColorChange(e) {
    this.setData({ lightColor: e.detail.value });
    this.drawQRCode();
  },


  toggleLogo() {
    this.setData({ showLogo: !this.data.showLogo });
    this.drawQRCode();
  },


  drawQRCode() {
    const { text, darkColor, lightColor, showLogo } = this.data;
    
    // 获取Canvas上下文
    const ctx = wx.createCanvasContext('qrcodeCanvas', this);
    
    // 清空画布
    ctx.clearRect(0, 0, 300, 300);
    
    // 创建二维码
    const qrcode = new QRCode(ctx, {
      text: text || 'https://example.com',
      width: 300,
      height: 300,
      colorDark: darkColor,
      colorLight: lightColor,
      correctLevel: QRCode.CorrectLevel.H
    });
    
    // 绘制二维码
    qrcode.make();
    
    // 添加Logo
    if (showLogo) {
      ctx.drawImage('/images/logo.png', 125, 125, 50, 50);
    }
    
    // 添加外框装饰
    ctx.setStrokeStyle(darkColor);
    ctx.setLineWidth(4);
    ctx.strokeRect(10, 10, 280, 280);
    
    // 添加中心装饰
    ctx.beginPath();
    ctx.arc(150, 150, 30, 0, 2 * Math.PI);
    ctx.setFillStyle(lightColor);
    ctx.fill();
    
    // 绘制到Canvas
    ctx.draw();
  },


  saveImage() {
    wx.canvasToTempFilePath({
      canvasId: 'qrcodeCanvas',
      success: (res) => {
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: () => {
            wx.showToast({
              title: '保存成功',
              icon: 'success'
            });
          },
          fail: (err) => {
            console.error('保存失败', err);
            wx.showToast({
              title: '保存失败,请检查权限',
              icon: 'none'
            });
          }
        });
      },
      fail: (err) => {
        console.error('生成临时文件失败', err);
      }
    });
  }
});

四、关键技术与解决方案

1. Canvas高清绘制技巧

为解决Canvas在高分辨率设备上模糊的问题:

 

// 获取设备像素比
const dpr = wx.getSystemInfoSync().pixelRatio;


// 设置Canvas实际尺寸
const canvasWidth = 300 * dpr;
const canvasHeight = 300 * dpr;


// 设置Canvas显示尺寸
this.setData({
  canvasStyle: `width: 300px; height: 300px;`
});

2. 二维码容错级别选择

// 四个容错级别可选
QRCode.CorrectLevel = {
  L: 1,  // 约可纠错7%的数据
  M: 0,  // 约可纠错15%的数据
  Q: 3,  // 约可纠错25%的数据
  H: 2   // 约可纠错30%的数据(最高)
};

3. 解决Canvas层级问题

小程序中Canvas是原生组件,层级最高,可通过以下方案解决:

  • 使用cover-view覆盖需要显示的元素

  • 在不需要交互时隐藏Canvas

  • 使用图片替代Canvas显示二维码

五、效果优化与扩展功能

1. 添加动态效果

// 在二维码周围添加旋转动画
ctx.beginPath();
ctx.arc(150, 150, 160, 0, 2 * Math.PI);
ctx.setStrokeStyle('#ff6b6b');
ctx.setLineWidth(3);
ctx.setLineDash([10, 5]);
ctx.stroke();


// 添加旋转动画
this.animateCircle(ctx);

2. 生成渐变二维码

// 创建渐变对象
const gradient = ctx.createLinearGradient(0, 0, 300, 300);
gradient.addColorStop(0, '#ff9a9e');
gradient.addColorStop(1, '#fad0c4');


// 使用渐变填充
qrcode.colorDark = gradient;

3. 添加背景图片

// 绘制背景图
ctx.drawImage('/images/background.jpg', 0, 0, 300, 300);


// 在背景上绘制半透明覆盖层
ctx.setFillStyle('rgba(255,255,255,0.7)');
ctx.fillRect(0, 0, 300, 300);


// 在上面绘制二维码
qrcode.make();

六、常见问题及解决方案

  1. Canvas绘制不显示问题

    1. 确保在onReady或之后的生命周期调用绘制方法

    2. 检查Canvas ID是否正确

    3. 确认Canvas在页面中可见

保存图片权限问题

// 在保存前检查权限
wx.getSetting({
  success: (res) => {
    if (!res.authSetting['scope.writePhotosAlbum']) {
      wx.authorize({
        scope: 'scope.writePhotosAlbum',
        success: () => this.saveImage(),
        fail: () => wx.openSetting()
      });
    } else {
      this.saveImage();
    }
  }
});
  1. 安卓设备模糊问题

    1. 使用高清绘制技巧(像素比缩放)

    2. 避免在二维码中使用过细的线条

    3. 适当提高容错级别

 

七、总结

通过本文介绍的方法,你可以在小程序中实现:

  • 自定义样式的二维码生成

  • Logo和装饰元素的添加

  • 二维码保存与分享功能

  • 丰富的视觉效果增强

Canvas绘制二维码不仅提供了更大的灵活性,还能让你的小程序在视觉效果上脱颖而出。赶紧尝试实现属于你的个性二维码吧!

联系尚武科技
客户服务
石家庄APP开发
400-666-4864
为您提供售前购买咨询、解决方案推荐等1V1服务!
技术支持及售后
石家庄APP开发公司
0311-66682288
为您提供从产品到服务的全面技术支持 !
客户服务
石家庄小程序开发
石家庄小程序开发公司
加我企业微信
为您提供售前购买咨询、
解决方案推荐等1V1服务!
石家庄网站建设公司
咨询相关问题或预约面谈,可以通过以下方式与我们联系。
石家庄网站制作
在线联系:
石家庄Web开发
石家庄软件开发
石家庄软件开发公司
ADD/地址:
河北·石家庄
新华区西三庄大街86号河北互联网大厦B座二层
Copyright © 2008-2025尚武科技 保留所有权利。 冀ICP备12011207号-2 石家庄网站开发冀公网安备 13010502001294号《互联网平台公约协议》
Copyright © 2025 www.sw-tech.cn, Inc. All rights reserved