微信小程序原生如何使用画布生成名片

步骤 1:在页面中添加画布组件

首先在 .wxml 中定义画布,注意设置固定宽高(生成图片时尺寸更可控),并添加一个生成按钮:

复制代码
<!-- pages/card/card.wxml -->
<view class="container">
  <!-- 画布:用于绘制名片 -->
  <canvas 
    type="2d" 
    canvas-id="cardCanvas" 
    width="600" 
    height="400" 
    class="canvas"
  ></canvas>

  <!-- 生成图片按钮 -->
  <button bindtap="generateCard" class="generate-btn">生成名片图片</button>

  <!-- 预览生成的图片 -->
  <image 
    src="{{cardImage}}" 
    mode="widthFix" 
    class="preview-img" 
    wx:if="{{cardImage}}"
  ></image>
</view>

步骤 2:样式设置(可选)

.wxss 中设置画布和按钮的样式,确保画布显示正常:

复制代码
/* pages/card/card.wxss */
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20rpx;
}

.canvas {
  border: 1px solid #eee;
  width: 600rpx; /* 小程序中rpx适配,600rpx约等于300px */
  height: 400rpx;
}

.generate-btn {
  margin-top: 30rpx;
  background: #07c160;
  color: white;
}

.preview-img {
  margin-top: 30rpx;
  width: 600rpx;
  border: 1px solid #eee;
}

步骤 3:使用 Canvas 2D API 绘制名片

.js 中获取画布上下文,通过 API 绘制名片元素(背景、头像、文字、二维码等):

复制代码
// pages/card/card.js
Page({
  data: {
    cardImage: '', // 生成的名片图片路径
  },

  onLoad() {
    // 页面加载时先绘制名片
    this.drawCard();
  },

  // 绘制名片
  drawCard() {
    // 获取画布上下文(2D模式)
    const query = wx.createSelectorQuery()
    query.select('#cardCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        const canvas = res[0].node
        const ctx = canvas.getContext('2d')

        // 设置画布实际尺寸(与wxml中width/height一致)
        const dpr = wx.getSystemInfoSync().pixelRatio // 设备像素比,避免模糊
        canvas.width = res[0].width * dpr
        canvas.height = res[0].height * dpr
        ctx.scale(dpr, dpr) // 缩放上下文,解决高清屏模糊问题

        // 1. 绘制名片背景(渐变效果)
        const gradient = ctx.createLinearGradient(0, 0, 600, 0)
        gradient.addColorStop(0, '#f5f5f5')
        gradient.addColorStop(1, '#e8f5e9')
        ctx.fillStyle = gradient
        ctx.fillRect(0, 0, 600, 400) // 绘制矩形背景

        // 2. 绘制头像(先加载图片再绘制)
        const avatarImg = canvas.createImage()
        avatarImg.src = '/images/avatar.jpg' // 本地头像路径(需提前放置)
        avatarImg.onload = () => {
          // 绘制圆形头像(先画圆再裁剪)
          ctx.save()
          ctx.beginPath()
          ctx.arc(100, 100, 60, 0, 2 * Math.PI) // 圆心(100,100),半径60
          ctx.clip() // 裁剪为圆形
          ctx.drawImage(avatarImg, 40, 40, 120, 120) // 绘制图片(填满圆形区域)
          ctx.restore() // 恢复上下文状态

          // 3. 绘制姓名
          ctx.font = 'bold 36px sans-serif'
          ctx.fillStyle = '#333'
          ctx.fillText('张三', 220, 100)

          // 4. 绘制职位
          ctx.font = '24px sans-serif'
          ctx.fillStyle = '#666'
          ctx.fillText('产品经理', 220, 140)

          // 5. 绘制联系方式(电话/微信)
          ctx.font = '20px sans-serif'
          ctx.fillStyle = '#666'
          ctx.fillText('电话:13800138000', 220, 180)
          ctx.fillText('微信:zhangsan123', 220, 220)

          // 6. 绘制公司logo(可选)
          const logoImg = canvas.createImage()
          logoImg.src = '/images/logo.png' // 本地logo路径
          logoImg.onload = () => {
            ctx.drawImage(logoImg, 450, 60, 80, 80) // 绘制到右上角
          }

          // 7. 绘制二维码(可选,需提前准备二维码图片)
          const qrImg = canvas.createImage()
          qrImg.src = '/images/qrcode.jpg' // 本地二维码路径
          qrImg.onload = () => {
            ctx.drawImage(qrImg, 450, 220, 100, 100) // 绘制到右下角
          }

          // 8. 绘制底部线条
          ctx.strokeStyle = '#ddd'
          ctx.lineWidth = 2
          ctx.beginPath()
          ctx.moveTo(50, 350)
          ctx.lineTo(550, 350)
          ctx.stroke()

          // 9. 绘制公司名称
          ctx.font = '22px sans-serif'
          ctx.fillStyle = '#999'
          ctx.fillText('XX科技有限公司 © 2023', 180, 380)
        }
      })
  },

  // 生成名片图片(保存到本地或展示)
  generateCard() {
    wx.canvasToTempFilePath({
      canvasId: 'cardCanvas',
      success: (res) => {
        this.setData({
          cardImage: res.tempFilePath // 展示生成的图片
        })
        // 可选:保存到相册
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: () => wx.showToast({ title: '保存成功' }),
          fail: (err) => console.error('保存失败', err)
        })
      },
      fail: (err) => console.error('生成图片失败', err)
    })
  }
})

关键说明:

  1. 画布尺寸与模糊问题 :通过 pixelRatio 缩放画布,解决高清屏幕下绘制内容模糊的问题(核心是 canvas.width = 实际宽 * dprctx.scale(dpr, dpr))。

  2. 图片加载 :绘制网络图片或本地图片时,必须在 onload 回调中执行绘制(确保图片加载完成),否则会绘制失败。

  3. 元素绘制顺序:先绘制底层元素(如背景),再绘制上层元素(如文字、头像),避免被覆盖。

  4. 生成图片 :使用 wx.canvasToTempFilePath 将画布内容转为临时图片路径,可用于展示或保存到相册(需用户授权)。

相关推荐
Dragon Wu3 小时前
Taro 自定义tab栏和自定义导航栏
前端·javascript·小程序·typescript·前端框架·taro
游戏开发爱好者84 小时前
iOS 26 iPhone 使用记录分析 多工具组合构建全方位设备行为洞察体系
android·ios·小程序·uni-app·cocoa·iphone·webview
星光一影18 小时前
Java医院管理系统HIS源码带小程序和安装教程
java·开发语言·小程序
毕设源码-郭学长18 小时前
【开题答辩全过程】以 基于微信小程序的个性化饮品定制点餐系统设计与实现为例,包含答辩的问题和答案
微信小程序·小程序
马尚道19 小时前
uniapp陪诊小程序
微信小程序
Terio_my21 小时前
微信小程序-智慧社区项目开发完整技术文档(上)
微信小程序·小程序
從南走到北1 天前
JAVA国际版任务悬赏发布接单系统源码支持IOS+Android+H5
android·java·ios·微信·微信小程序·小程序
游戏开发爱好者81 天前
iOS 开发推送功能全流程详解 从 APNs 配置到上架发布的完整实践(含跨平台上传方案)
android·macos·ios·小程序·uni-app·cocoa·iphone
汤姆yu1 天前
基于微信小程序的博物馆文创系统
微信小程序·小程序·博物馆