Canvas如何应用在微信小程序中
- 首先在wxml中添加canvas模板:
<canvas type="2d" id="canvas-area-id" class="canvas-area"></canvas>
- 封装绘制Canvas的方法,并在进入页面时执行绘制:
首先通过 wx.createSelectorQuery() 接口通过id选择器获取wxml元素的节点信息,
然后通过 query.select() 选择id名为canvas-area-id的节点,
然后通过 .filed 获取节点信息字段, .exec((res)=>{}) 执行所有的查询操作,并在回调函数中处理查询结果,
通过 res[0].node 获取对象本身,并定义为canvas,
然后通过 canvas.getContext('2d') 获取Canvas节点的2D绘制上下文,后续进行Canvas的绘制操作
// 这部分的代码可以放在onLoad中执行,在进入页面时获取屏幕尺寸
const that = this;
// 获取屏幕宽度,用于计算画布尺寸
wx.getSystemInfo({
success(res) {
const screenWidth = res.screenWidth;
const canvasWidth = screenWidth;
that.setData({
canvasWidth: canvasWidth
});
}
});
进行canvas绘制前,最好先在进入页面时调用wx.getSystemInfo接口获取屏幕的宽度,这样后续绘制使用该单位方便在不同尺寸的移动端设备上表现出相同的效果,然后进行正式的绘制流程:
async onLoad() { // 进入页面后执行绘制Canvas的方法
this.drawCanvas()
},
drawCanvas() {
const query = wx.createSelectorQuery();
query.select('canvas-area-id').fields({ node: true, size: true }).exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const imgBg = canvas.createImage()
imgBg.src = './static/image/xxxx.png'
imgBg.onload = () => {
ctx.drawImage(imgBg,0,0,canvasWidth,canvasWidth * 3.3)
ctx.fillStyle = '#FFFFFF';
ctx.font = '17px Alibaba PuHuiTi';
ctx.fillText(this.data.userInfo.nickname, 62, 60);
ctx.fillStyle = '#57C27B';
ctx.fillRect(28,574,4,14);
ctx.beginPath();
ctx.moveTo(65, 80);
ctx.lineTo(165, 80);
ctx.strokeStyle = '#F34854'; // 红色线条
ctx.lineWidth = 2; // 线条宽度
ctx.stroke();
setTimeout(()=>{
wx.canvasToTempFilePath({
canvas,
fileType: "jpg",
quality: 1,
success: function (res) {
// 导出成功后,将图片路径设置到页面数据中
that.setData({ imagePath: res.tempFilePath });
wx.navigateTo({
url: `/pages/share/index?url=${encodeURIComponent(res.tempFilePath)}`
});
},
fail: function (err) {
console.error('导出图片失败', err);
}
});
},500)
}
});
},
通过以上代码,我们可以在一个canvas平面上绘制一个背景图,在背景图上绘制文字,方块,线条等元素,并在绘制完成后调用wx.canvasToTempFilePath将canvas转为图片,生成暂存图片的url,将url应用在image元素上可以展示出来导出的图片。
- canvas常用的属性及传参的用法:
const imgBg = canvas.createImage()
imgBg.src = './static/image/xxxx.png'
imgBg.onload = () => {
ctx.drawImage(imgBg,0,0,canvasWidth,canvasWidth * 3.3)
}
绘制一个图片,在调用该方法前,需要使用canvas.createImage()先定义一个图片对象,并定义该图片对象的src图片路径,最好在图片对象onload后执行drawImage方法,确保图片已经加载出来可以绘制在canvas上,drawImage有5个属性,第一个是图片对象,第二个是该图片在canvas中横轴的位置,第三个是该图片在canvas中纵轴的位置,第三个是图片宽度,第四个是图片高度。
ctx.fillStyle = '#FFFFFF';
ctx.font = '17px Alibaba PuHuiTi';
ctx.fillText(this.data.userInfo.nickname, 62, 60);
绘制文字,fillStyle设置文字颜色,font设置文字大小与字体,fillText设置文字内容,三个参数,第一个参数是文字内容,可以是变量,也可以是字符串,第二个参数是文字在canvas中横轴的位置,第三个参数是文字在canvas中纵轴的位置。
ctx.fillStyle = '#57C27B';
ctx.fillRect(28,574,4,14);
绘制一个矩形,fillStyle设置矩形的背景颜色,font设置文字大小与字体,fillRect设置矩形,四个参数,第一个参数是矩形在canvas中横轴的位置,第二个参数是矩形在canvas中纵轴的位置,第三个参数是矩形的宽度,第四个参数是矩形的高度。
ctx.beginPath();
ctx.moveTo(65, 80);
ctx.lineTo(165, 80);
ctx.strokeStyle = '#F34854'; // 红色线条
ctx.lineWidth = 2; // 线条宽度
ctx.stroke();
绘制线条,绘制线条时有一些需要注意的事项,具体如下:
beginPath():开始一个新的路径。每次绘制新的图形时,都应该调用beginPath()来清除之前的路径状态,确保新绘制的图形不会受到之前路径的影响。moveTo(x, y):将绘图的当前位置移动到指定的坐标(x, y)。这不会绘制任何内容,只是将“笔”移动到新的起点。lineTo(x, y):从当前的位置绘制一条直线到指定的坐标(x, y)。strokeStyle:设置线条的颜色、渐变或模式。lineWidth:设置线条的宽度。stroke():根据当前的路径绘制线条。如果没有调用stroke(),路径将不会被绘制到 Canvas 上。
利用如上方法,就可以实现微信小程序海报图片的绘制,设置图片,文字,元素样式等来实现一个完整的海报。
tip:需要注意的一点是,Canvas 本身并没有图层的概念,可以通过控制绘制的顺序来模拟图层的效果,先绘制的图形会被后绘制的图形覆盖,就像画画一样,后面画的东西会覆盖前面已经画好的部分,通过这个特性,我们就可以控制哪些元素会覆盖在其他元素的上面。