首先:
  • canvas 里的的位置单位都是 px;
  • 创建 canvas 标签到 wxml,Canvas 画布一定要先设置大小;
  • canvas 文字不支持自定义字体;

1.获取 canvas 实例

wx.createCanvasContext 获取小程序实例,canvasId 是在 canvas 标签上定义的 canvas-id

1
ctx = wx.createCanvasContext(canvasId, this);

2.绘制图片

1
2
3
4
// 绘制图片
ctx.drawImage(imageResource, dx, dy, dWidth, dHeight);
ctx.drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
// 从 1.9.0 起支持

如果绘制的图片是网络图片,需要 wx.downloadFile 先下载. ( 需要吧下载图片的域名加入下载域名的白名单)

如何绘制圆形头像:

1
2
3
4
5
6
7
8
9
10
11
const src = "https://wx.qlogo.cn/mmopen2";
const avatar_width = 60; //绘制的头像宽度
const avatar_heigth = 60; //绘制的头像高度
const avatar_x = 0; //绘制的头像在画布上的位置
const avatar_y = 0; //绘制的头像在画布上的位置

// 画圆
ctx.arc(avatar_width / 2, avatar_heigth / 2, avatar_width / 2, 0, 360, false);
ctx.clip();
// 从原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。可以在使用 clip 方法前通过使用 save 方法对当前画布区域进行保存,并在以后的任意时间通过restore方法对其进行恢复。
ctx.drawImage(src, 0, 0, avatar_width, avatar_heigth);

3.文字

1
2
3
ctx.font = "40px serif";
ctx.setTextAlign("center");
ctx.fillText(textContent, x, y, maxWidth);

文字支持设置文字的大小,颜色,对齐方式,但不能自定义字体,所有的设置要在 fillText() 之前设置才起效。

文本块可以设置最大宽度,但超出最大宽度不会自动换行。

绘制多段文字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 最大宽度 100px,文字 font-size: 15px; line-height: 18px;
// 100 /15 = 6.66 最多一行6个字
const maxWidth = 100;
const content =
"文本块可以设置最大宽度,但超出最大宽度不会自动换行。文本块可以设置最大宽度,但超出最大宽度不会自动换行。";
let x = 0;
let y = 0;
let currentLine = "";
for (let i = 0; i < content.length; i++) {
currentLine += content[i];
if ((i + 1) % 6 === 0 || i === content.length - 1) {
ctx.fillText(currentLine, x, y, maxWidth);
currentLine = "";
y += 18;
}
}

4. 边框/ 色块

1
2
3
4
5
6
7
8
9
ctx.moveTo(x, y); // 移动到画布中的指定点
ctx.lineTo(x, y); // 直线移动到点(x,y)
ctx.arcTo(startX, startY, endX, endY, radius); // 弧线移动到点(x,y)

// 画边框
ctx.stroke();

// 填充色
ctx.fill();

5. 结束绘制

1
ctx.draw(reserve, callback);

所有的 fillText(), drawImage() 等像是一个一个的任务,写了并不会立马执行,最后要执行 draw() 才会依次绘制。而且这是个异步操作,所以结束绘制后的操作要用 callback 来实现, 因此下面的保存过程要放到 callback 里。

5. 生成图片并保存

1
2
3
4
5
6
7
8
9
10
11
12
13
// 生成图片
wx.canvasToTempFilePath({
canvasId, // 必传
success(res) {
console.log(res.tempFilePath); // 图片临时路径
}
});

// 保存图片到相册
wx.saveImageToPhotosAlbum({
filePath,
success(res) {}
});
  • (Tip: 保存图片到相册需要用户授权, 并且用户拒绝后,不会再次请求授权)