wxml新版跟旧版的区别,旧版本可参考 旧版画布迁移指南 进行迁移
使用canvas加载图片的时候,新版使用的是img.onload加载图片,绘制的时候会先绘制文字,然后再绘制图片,导致图片盖住了文字,在这里踩了坑记录下,所以请求图片的时候用promise处理了下,通过Promise.all处理请求多个图片,响应成功后绘制图片+文字
新版
<canvas type="2d" id="myCanvas"></canvas>
旧版
<canvas canvas-id="myCanvas" style="height: 364rpx;width:640rpx;position: fixed;top: -10000px;"></canvas>
wxml
<canvas id="canvas" style="width:325px;height:185px;position: fixed;top: -10000px;" type="2d" class="canvas" />
js
Page({
data:{
userInfo: {}
},
onLoad(options) {
this.createCanvasImage()
},
// 获取图片对象
async getImage(url) {
const off = wx.createOffscreenCanvas({
type: "2d",
});
const image = off.createImage();
await new Promise((resolve, reject) => {
image.onload = resolve; // 绘制图片逻辑
image.src = url;
});
return image;
},
// 生成图片
async createCanvasImage() {
let { userInfo, colorIndex } = this.data;
let that = this;
const $ = wx.createSelectorQuery();
$.select("#canvas")
.fields({
node: true,
size: true,
})
.exec((res) => {
// 这里是canvas的宽高
console.log(res[0].width, res[0].height);
// Canvas 对象
const canvas = res[0].node;
that.canvas = canvas;
// Canvas 画布的实际绘制宽高
const width = res[0].width;
const height = res[0].height;
// 创建canvas渲染上下文
const ctx = canvas.getContext("2d");
const dpr = wx.getWindowInfo().pixelRatio;
console.log("---dpr", dpr);
// 手动改变canvas的宽和高
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
// 以上代码都是基础工作
let bg = that.getImage(
`xxx`
);
let wxCodeImg = that.getImage(userInfo.wxCodeImg);
let headImg = that.getImage(userInfo.userPhoto);
let promiseList = [bg, headImg];
if (userInfo.wxCodeImg) {
promiseList = [bg, headImg, wxCodeImg];
}
Promise.all(promiseList).then((result) => {
console.log(res);
ctx.drawImage(result[0], 0, 0, 325, 185);
if (userInfo.wxCodeImg) {
ctx.drawImage(result[2], 260, 10, 50, 50);
}
ctx.save();
ctx.beginPath(); //开始绘制
let avatarurl_width = 106, //绘制的头像宽度
avatarurl_heigth = 106, //绘制的头像高度
avatarurl_x = 28, //绘制的头像在画布上的位置
avatarurl_y = 50; //绘制的头像在画布上的位置
//先画个圆 前两个参数确定了圆心 (x,y) 坐标 第三个参数是圆的半径 四参数是绘图方向 默认是false,即顺时针
ctx.arc(
avatarurl_width / 2 + avatarurl_x,
avatarurl_heigth / 2 + avatarurl_y,
avatarurl_width / 2,
0,
Math.PI * 2,
false
);
ctx.clip(); //画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
ctx.drawImage(
result[1],
avatarurl_x,
avatarurl_y,
avatarurl_width,
avatarurl_heigth
);
ctx.restore();
ctx.fillStyle = "#fff";
ctx.font = `15px serif`;
ctx.fillText(userInfo.name, 183, 74); // 绘制文字
ctx.font = `10px serif`;
ctx.fillText(userInfo.position, 183, 88); // 绘制文字
ctx.font = `8px serif`;
ctx.fillText(userInfo.company, 183, 113); // 绘制文字
ctx.font = `8px serif`;
ctx.fillText(userInfo.phone, 183, 130); // 绘制文字
ctx.font = `8px serif`;
ctx.fillText(userInfo.wx, 183, 148); // 绘制文字
ctx.font = `8px serif`;
ctx.fillText(userInfo.email, 183, 164); // 绘制文字
ctx.font = `8px serif`;
if (userInfo.wxCodeImg) {
ctx.fillText("截图扫码", 270, 70); // 绘制文字
}
ctx.restore(); //恢复之前保存的绘图上下文状态 可以继续绘制
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 325,
height: 185,
canvas: this.canvas, // canvas实例对象
destWidth: 1300,
destHeight: 740,
success(res) {
that.uploadFile(res.tempFilePath);
console.log(res.tempFilePath, "canvasToTempFilePath");
},
});
});
});
},
})