|
@@ -48,20 +48,22 @@ export async function REPORT_BEHAVIOR(eventName = '', extra = {}) {
|
|
export async function DRAW_POSTER() {
|
|
export async function DRAW_POSTER() {
|
|
const userInfo = getApp().globalData.userInfo || wx.getStorageSync('userInfo');
|
|
const userInfo = getApp().globalData.userInfo || wx.getStorageSync('userInfo');
|
|
const programConfig = getApp().globalData.programConfig || wx.getStorageSync('programConfig');
|
|
const programConfig = getApp().globalData.programConfig || wx.getStorageSync('programConfig');
|
|
- const ctx = wx.createCanvasContext('posterCanvas', this);
|
|
|
|
|
|
+ const ctx = wx.createCanvasContext('posterCanvas'); // 不要传 this,容易丢失上下文
|
|
const canvasWidth = 300;
|
|
const canvasWidth = 300;
|
|
const canvasHeight = 600;
|
|
const canvasHeight = 600;
|
|
const bottomHeight = 80;
|
|
const bottomHeight = 80;
|
|
const radius = 16; // 圆角半径
|
|
const radius = 16; // 圆角半径
|
|
|
|
|
|
|
|
+ // 白色背景 + 圆角
|
|
ctx.save();
|
|
ctx.save();
|
|
ctx.setFillStyle('#fff');
|
|
ctx.setFillStyle('#fff');
|
|
drawRoundRect(ctx, 0, 0, canvasWidth, canvasHeight, radius);
|
|
drawRoundRect(ctx, 0, 0, canvasWidth, canvasHeight, radius);
|
|
|
|
+ ctx.fill();
|
|
|
|
+ ctx.restore();
|
|
|
|
|
|
// 背景图
|
|
// 背景图
|
|
- const bgUrl = programConfig.share_img;
|
|
|
|
- if (bgUrl) {
|
|
|
|
- const bgPath = bgUrl.startsWith('http') ? await downloadImage(bgUrl) : bgUrl;
|
|
|
|
|
|
+ if (programConfig.share_img) {
|
|
|
|
+ const bgPath = await loadImage(programConfig.share_img);
|
|
ctx.drawImage(bgPath, 0, 0, canvasWidth, canvasHeight - bottomHeight);
|
|
ctx.drawImage(bgPath, 0, 0, canvasWidth, canvasHeight - bottomHeight);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -69,10 +71,9 @@ export async function DRAW_POSTER() {
|
|
ctx.setFillStyle('#fff');
|
|
ctx.setFillStyle('#fff');
|
|
ctx.fillRect(0, canvasHeight - bottomHeight, canvasWidth, bottomHeight);
|
|
ctx.fillRect(0, canvasHeight - bottomHeight, canvasWidth, bottomHeight);
|
|
|
|
|
|
- // 用户头像(圆形)
|
|
|
|
- const avatarUrl = userInfo.avatar;
|
|
|
|
- if (avatarUrl) {
|
|
|
|
- const avatarPath = avatarUrl.startsWith('http') ? await downloadImage(avatarUrl) : avatarUrl;
|
|
|
|
|
|
+ // 用户头像(圆形裁剪)
|
|
|
|
+ if (userInfo.avatar) {
|
|
|
|
+ const avatarPath = await loadImage(userInfo.avatar);
|
|
const avatarSize = 40;
|
|
const avatarSize = 40;
|
|
const avatarX = 20;
|
|
const avatarX = 20;
|
|
const avatarY = canvasHeight - bottomHeight + (bottomHeight - avatarSize) / 2;
|
|
const avatarY = canvasHeight - bottomHeight + (bottomHeight - avatarSize) / 2;
|
|
@@ -88,47 +89,46 @@ export async function DRAW_POSTER() {
|
|
const nickName = userInfo.nickname || '游客';
|
|
const nickName = userInfo.nickname || '游客';
|
|
ctx.setFontSize(16);
|
|
ctx.setFontSize(16);
|
|
ctx.setFillStyle('#000');
|
|
ctx.setFillStyle('#000');
|
|
- const textX = 20 + 40 + 12;
|
|
|
|
- const textY = canvasHeight - bottomHeight + bottomHeight / 2 + 6;
|
|
|
|
- ctx.fillText(nickName, textX, textY);
|
|
|
|
|
|
+ ctx.fillText(nickName, 72, canvasHeight - bottomHeight / 2 + 6);
|
|
|
|
|
|
// 二维码
|
|
// 二维码
|
|
- const qrUrl = programConfig.share_qrcode;
|
|
|
|
- if (qrUrl) {
|
|
|
|
- const qrPath = qrUrl.startsWith('http') ? await downloadImage(qrUrl) : qrUrl;
|
|
|
|
|
|
+ if (programConfig.share_qrcode) {
|
|
|
|
+ const qrPath = await loadImage(programConfig.share_qrcode);
|
|
const qrSize = 50;
|
|
const qrSize = 50;
|
|
const qrX = canvasWidth - qrSize - 20;
|
|
const qrX = canvasWidth - qrSize - 20;
|
|
const qrY = canvasHeight - bottomHeight + (bottomHeight - qrSize) / 2;
|
|
const qrY = canvasHeight - bottomHeight + (bottomHeight - qrSize) / 2;
|
|
ctx.drawImage(qrPath, qrX, qrY, qrSize, qrSize);
|
|
ctx.drawImage(qrPath, qrX, qrY, qrSize, qrSize);
|
|
}
|
|
}
|
|
- ctx.restore(); // 恢复裁剪
|
|
|
|
|
|
+
|
|
|
|
+ // 导出图片
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
- ctx.draw(true, () => {
|
|
|
|
|
|
+ ctx.draw(false, () => {
|
|
wx.canvasToTempFilePath({
|
|
wx.canvasToTempFilePath({
|
|
canvasId: 'posterCanvas',
|
|
canvasId: 'posterCanvas',
|
|
|
|
+ destWidth: canvasWidth * 2, // 提高清晰度,避免导出失败
|
|
|
|
+ destHeight: canvasHeight * 2,
|
|
success: res => resolve(res.tempFilePath),
|
|
success: res => resolve(res.tempFilePath),
|
|
fail: err => {
|
|
fail: err => {
|
|
console.error('生成临时文件失败:', err);
|
|
console.error('生成临时文件失败:', err);
|
|
reject(err);
|
|
reject(err);
|
|
}
|
|
}
|
|
- }, this);
|
|
|
|
|
|
+ });
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
-// 下载网络图片到临时路径
|
|
|
|
-function downloadImage(url) {
|
|
|
|
|
|
+
|
|
|
|
+// 图片预加载
|
|
|
|
+function loadImage(url) {
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
- wx.downloadFile({
|
|
|
|
- url,
|
|
|
|
- success(res) {
|
|
|
|
- if (res.statusCode === 200) resolve(res.tempFilePath);
|
|
|
|
- else reject(new Error('下载失败'));
|
|
|
|
- },
|
|
|
|
|
|
+ wx.getImageInfo({
|
|
|
|
+ src: url,
|
|
|
|
+ success(res) { resolve(res.path); },
|
|
fail(err) { reject(err); }
|
|
fail(err) { reject(err); }
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
-// 绘制圆角矩形函数
|
|
|
|
|
|
+
|
|
|
|
+// 圆角矩形
|
|
function drawRoundRect(ctx, x, y, w, h, r) {
|
|
function drawRoundRect(ctx, x, y, w, h, r) {
|
|
ctx.beginPath();
|
|
ctx.beginPath();
|
|
ctx.moveTo(x + r, y);
|
|
ctx.moveTo(x + r, y);
|
|
@@ -137,6 +137,4 @@ function drawRoundRect(ctx, x, y, w, h, r) {
|
|
ctx.arcTo(x, y + h, x, y, r);
|
|
ctx.arcTo(x, y + h, x, y, r);
|
|
ctx.arcTo(x, y, x + w, y, r);
|
|
ctx.arcTo(x, y, x + w, y, r);
|
|
ctx.closePath();
|
|
ctx.closePath();
|
|
- ctx.fill();
|
|
|
|
- ctx.clip(); // 关键:裁剪出圆角
|
|
|
|
}
|
|
}
|