前言:
众所周知,小程序的迭代是很快的,时不时就会有文档更新。前面写了一篇小程序 | canvas篇,今天再更新一下Canvas,因为旧版canvas接口不再维护了,所以把新版canvas 2d接口记录一下:
(官方更新图)
先把差异点记录下:
① wxml中的修改:
旧版:使用 canvas-id 属性唯一标识 canvas。
新版:使用 id 标识,还要添加 type="2d" 属性标识为新版 Canvas 2D 接口。
修改如下:
<canvas id="canvas" type='2d' style="width: 171px;height: 305px;margin:0 auto;" />
② 获取canvas:
旧版:使用 wx.createCanvasContext 同步获取 CanvasContext。
const ctx = wx.createCanvasContext('myCanvas');
新版:通过 SelectorQuery 异步获取 Canvas 对象,再通过 Canvas.getContext 获取渲染上下文 RenderingContext。
wx.createSelectorQuery().select('#canvas').fields({ node: canvas })=>{
const ctx = canvas.getContext('2d');
}).exec()
修改如下:
wx.createSelectorQuery().select('#canvas').fields({ node: true, size: true }).exec((rect)=>{
const canvas = rect[0].node;
const ctx = canvas.getContext('2d');
})
③ 绘制图片:
旧版: CanvasContext.drawImage 直接传入图片 url 进行绘制。
新版: 先通过 Canvas.createImage 创建图片对象,onload 图片加载完成回调触发后,再将图片对象传入 ctx.drawImage 绘制。
修改如下:
const image = canvas.createImage();
image.src = cardbg;
image.onload = ()=>{
ctx.drawImage(image, 0, 0, 150, 100);
}
④ 绘制文字:
旧版:方法里面传参设置
新版:属性赋值设置
修改如下:
ctx.fillStyle = '#fff';
⑤ 绘制方法:
旧版:需要调用 CanvasContext.draw 才会进行绘制,并且绘制过程是异步的,需要等待绘制完成回调才能进行下一步操作。
新版:绘制方法会同步绘制到画布上。不需要再进行draw,直接在绘制完成后清空画布。
修改如下:
ctx.clearRect(0, 0, canvas.width, canvas.height)
⑥ 画布保存为图片:
旧版:wx.canvasToTempFilePath 接口传入canvasId。
新版:wx.canvasToTempFilePath 接口传入canvas。
修改如下:
wx.canvasToTempFilePath({
// canvasId: 'myCanvas', //旧版
canvas: canvas,
success: function (res) { })
});
实现代码:
getCanvas(headImg, codeImg ) {
let that = this;
let { cardbg } = that.data;
wx.createSelectorQuery().select('#canvas').fields({ node: true, size: true }).exec((rect)=>{
const canvas = rect[0].node;
that.setData({ canvas })
const ctx = canvas.getContext('2d');
canvas.width = rect[0].width
canvas.height = rect[0].height
let rpx = 1;
wx.getSystemInfo({
success(res) {
rpx = res.windowWidth / 375;
wx.getImageInfo({
src: cardbg,
success(res) {
let imgScale = 1;
let imgW = res.width; //图片宽度
let imgH = res.height; //图片高度
let canvasWidth = canvas.width; //画布宽度
let canvasHeight = canvas.height * .777; //画布高度
let x = 0;
let y = 0;
let imgScalew = canvasWidth / imgW;
let imgScaleh = canvasHeight / imgH;
if (imgScalew > imgScaleh) {
imgScale = imgScalew
y = -(imgScale * imgH - canvasHeight) / 2
} else {
imgScale = imgScaleh
x = -(imgScale * imgW - canvasWidth) / 2
}
const image = canvas.createImage(); //背景图
image.src = cardbg;
image.onload = ()=>{
ctx.drawImage(image, 0, 0, imgW, imgH, x, y, imgScale * imgW, imgScale * imgH);
}
ctx.fillStyle = '#fff';
ctx.fillRect(0, 474 / 2 *rpx , 342 / 2*rpx , 228 / 2 *rpx)
ctx.fontSize = 14*rpx;
ctx.fillStyle = '#3D3D3D';
ctx.fillText("我是昵称", 50*rpx , (474 / 2 + 34)*rpx );
const avatarImage = canvas.createImage(); // 3.绘制头像
avatarImage.src = codeImg;
avatarImage.onload = ()=>{
ctx.arc(24*rpx, 271*rpx , 24 *rpx, 0, Math.PI * 2, false);
ctx.clip();
ctx.drawImage(avatarImage, 0, 247*rpx , 48*rpx , 48*rpx )
}
}
})
},
})
// 绘制前清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 这里绘制完成
console.log('draw done')
});
},
文中差异点只提到项目需求中有用到的,其他业务暂时没涉及到的就没展示,大家可自行去官方文档查看。