当前页面:
生成后的海报页面
总的解决思路:
- 计算出 rpx的换算比例
- 引入特殊字体
- 画图
1. 计算出 rpx的换算比例
// 获取系统信息
getSystemInfo() {
return new Promise((resolve, reject) => {
wx.getSystemInfo({
success: (f) => {
// console.log(24, f);
rpx = f.windowWidth / 750;
resolve();
},
fail: (err) => {
resolve();
},
});
});
}
2. 引入特殊字体
字体需要用网络子图
loadFontFace() {
return new Promise((resolve, reject) => {
wx.loadFontFace({
family: 'dincondensedbold',
source: 'url("https://xxxxxx/font/DINCondensedBold2.ttf")',
scopes: ['webview', 'native'],
success: (res) => {
console.log(res);
resolve();
},
fail: (err) => {
console.info(err);
resolve();
},
});
});
}
3. 开始画图
图片需要用网络图片
drawCanvas2D(detail) {
const query = wx.createSelectorQuery();
query
.select('#cavansId')
.fields({ node: true, size: true })
.exec(async (res) => {
// console.log(33, res);
const canvas = res[0].node;
this.canvas = canvas;
let ctx = canvas.getContext('2d');
// 设置整个画布dpr
const height = 1000 * rpx;
const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
ctx.scale(dpr, dpr);
// console.log(1111, canvas.width, canvas.height, dpr);
// 设置整个画布背景色和宽高
ctx.fillStyle = '#00c388';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 背景图
await this.drawImageByLoad(canvas, ctx, 'https://xxxxx/xxxxxx/opendoor/werun/v2/q11.png', 50, 220, 643, 805);
// 导航条
await this.drawImageByLoad(canvas, ctx, 'https://xxxxx/xxxxxx/opendoor/werun/v2/q3.png', 122, 275, 506, 70);
// 助力社区上升1 2 3名
let url = `https://xxxxx/xxxxxx/opendoor/werun/v2/q${randomRange(8, 10)}.png`;
await this.drawImageByLoad(canvas, ctx, url, 228, 365, 279, 35);
// 房价
await this.drawImageByLoad(canvas, ctx, 'https://xxxxx/xxxxxx/opendoor/werun/v2/q4.png', 130, 460, 105, 102);
// 户数
await this.drawImageByLoad(canvas, ctx, 'https://xxxxx/xxxxxx/opendoor/werun/v2/q5.png', 415, 460, 105, 102);
// 停车位
await this.drawImageByLoad(canvas, ctx, 'https://xxxxx/xxxxxx/opendoor/werun/v2/q7.png', 130, 600, 105, 102);
// 绿化率
await this.drawImageByLoad(canvas, ctx, 'https://xxxxx/xxxxxx/opendoor/werun/v2/q6.png', 415, 600, 105, 102);
// code
await this.drawImageByLoad(canvas, ctx, 'https://xxxxx/xxxxxx/opendoor/werun/v2/code.jpg', 500, 860, 160, 160);
ctx.save();
// 标题:上海市排名
ctx.fillStyle = '#fff';
this.setFontSizeByFont(ctx, 35 * rpx);
ctx.fillText('上海市排名', 80 * rpx, 70 * rpx);
// 排名
ctx.font = `normal ${96 * rpx}px dincondensedbold`;
ctx.fillText(detail.score_rank, 80 * rpx, 170 * rpx);
const w1 = ctx.measureText(detail.score_rank);
// 分数
// this.setFontSizeByFont(ctx, 40 * rpx);
ctx.font = `normal ${40 * rpx}px dincondensedbold`;
const a = detail.score.toFixed(0);
ctx.fillText(`(${a}分)`, (80 + 10) * rpx + w1.width, 170 * rpx); // 10 为 间隙宽度
// 导航条的文字
this.setFontSizeByFont(ctx, 32 * rpx);
const w2 = ctx.measureText(`我已为社区助力${this.step}步`);
ctx.fillText(`我已为社区助力${this.step}步`, (750 * rpx - w2.width) / 2, 320 * rpx); // 10 为 间隙宽度
// 标题:房价
this.setFontSizeByFont(ctx, 24 * rpx);
ctx.fillStyle = '#000000';
ctx.fillText('房价(平/元)', 245 * rpx, 490 * rpx);
ctx.font = `normal ${54 * rpx}px dincondensedbold`;
ctx.fillStyle = '#184655';
ctx.fillText(detail.price, 245 * rpx, 545 * rpx);
// 标题:户数
this.setFontSizeByFont(ctx, 24 * rpx);
ctx.fillStyle = '#000000';
ctx.fillText('户数(户)', 535 * rpx, 490 * rpx);
ctx.font = `normal ${54 * rpx}px dincondensedbold`;
ctx.fillStyle = '#184655';
ctx.fillText(detail.houses, 535 * rpx, 545 * rpx);
// 标题:停车位
this.setFontSizeByFont(ctx, 24 * rpx);
ctx.fillStyle = '#000000';
ctx.fillText('停车位(个)', 245 * rpx, 620 * rpx);
ctx.font = `normal ${54 * rpx}px dincondensedbold`;
ctx.fillStyle = '#184655';
ctx.fillText(detail.parkings, 245 * rpx, 675 * rpx);
// 标题:绿化率
this.setFontSizeByFont(ctx, 24 * rpx);
ctx.fillStyle = '#000000';
ctx.fillText('绿化率(%)', 535 * rpx, 620 * rpx);
ctx.font = `normal ${54 * rpx}px dincondensedbold`;
ctx.fillStyle = '#184655';
ctx.fillText(detail.green, 535 * rpx, 675 * rpx);
// ctx.restore();
});
// 背景色
// ctx.fillStyle = '#00c388';
// ctx.fillRect(0, 0, 750 * rpx, 1400 * rpx);
// 绘制排名
// this.drawGrade();
// ctx.draw();
}
drawImageByLoad(canvas, ctx, url, x, y, w, h) {
return new Promise((resolve, reject) => {
// 背景图
let img = canvas.createImage();
img.src = url;
img.onload = () => {
ctx.drawImage(img, x * rpx, y * rpx, w * rpx, h * rpx); // url x y w h
resolve();
};
});
}
setFontSizeByFont(ctx, fontszie) {
ctx.font = `normal ${fontszie}px Arial, Verdana, Tahoma, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif`;
}