微信小程序原生如何使用画布生成名片
步骤 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].nodeconst ctx = canvas.getContext('2d')// 设置画布实际尺寸(与wxml中width/height一致)const dpr = wx.getSystemInfoSync().pixelRatio // 设备像素比,避免模糊canvas.width = res[0].width * dprcanvas.height = res[0].height * dprctx.scale(dpr, dpr) // 缩放上下文,解决高清屏模糊问题// 1. 绘制名片背景(渐变效果)const gradient = ctx.createLinearGradient(0, 0, 600, 0)gradient.addColorStop(0, '#f5f5f5')gradient.addColorStop(1, '#e8f5e9')ctx.fillStyle = gradientctx.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),半径60ctx.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 = 2ctx.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)})}
})关键说明:
画布尺寸与模糊问题:通过
pixelRatio缩放画布,解决高清屏幕下绘制内容模糊的问题(核心是canvas.width = 实际宽 * dpr并ctx.scale(dpr, dpr))。图片加载:绘制网络图片或本地图片时,必须在
onload回调中执行绘制(确保图片加载完成),否则会绘制失败。元素绘制顺序:先绘制底层元素(如背景),再绘制上层元素(如文字、头像),避免被覆盖。
生成图片:使用
wx.canvasToTempFilePath将画布内容转为临时图片路径,可用于展示或保存到相册(需用户授权)。
