From 506f6d2e4e9f4a2e76792e64d64f51dd0ebeffeb Mon Sep 17 00:00:00 2001 From: cheng <545895878@qq.com> Date: Tue, 21 Jul 2026 06:59:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(card):=20=E4=BC=98=E5=8C=96=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E9=A1=B5=E9=9D=A2=E5=9B=BE=E7=89=87=E7=BB=98=E5=88=B6?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 loadImg 方法以获取图片的完整信息(路径、宽高) - 新增 drawImgFill 方法实现 aspectFill 图片绘制模式 - 使用新的图片绘制方法替换原有的 canvas 绘制逻辑 - 改进图片裁剪和填充算法,确保图片不变形且填满指定区域 --- pages/card/card.vue | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/pages/card/card.vue b/pages/card/card.vue index 4d81b2b..e7ad923 100644 --- a/pages/card/card.vue +++ b/pages/card/card.vue @@ -136,10 +136,25 @@ export default { loadImg(src) { return new Promise(r => { if (!src) return r(null) - uni.getImageInfo({ src, success: res => r(res.path), fail: () => r(null) }) + uni.getImageInfo({ + src, + success: res => r({ path: res.path, width: res.width, height: res.height }), + fail: () => r(null) + }) }) }, + // aspectFill 方式绘制图片(居中裁剪填满,不变形) + drawImgFill(ctx, img, dx, dy, dw, dh) { + if (!img) return + const sw = img.width, sh = img.height + if (!sw || !sh) { try { ctx.drawImage(img.path, dx, dy, dw, dh) } catch (e) {} return } + const scale = Math.max(dw / sw, dh / sh) + const cropW = dw / scale, cropH = dh / scale + const sx = (sw - cropW) / 2, sy = (sh - cropH) / 2 + try { ctx.drawImage(img.path, sx, sy, cropW, cropH, dx, dy, dw, dh) } catch (e) {} + }, + // ===== 海报绘制(醉美夜色风格) ===== async drawExportCard() { const ctx = uni.createCanvasContext('shareCanvas', this) @@ -245,7 +260,7 @@ export default { ctx.save() this.rr(ctx, P, y, maxW, heroH, 24, 'fill') ctx.clip() - if (imgs[0]) { try { ctx.drawImage(imgs[0], P, y, maxW, heroH) } catch (e) {} } + if (imgs[0]) { this.drawImgFill(ctx, imgs[0], P, y, maxW, heroH) } else { ctx.setFillStyle(WHITE_05); ctx.fillRect(P, y, maxW, heroH) } ctx.restore() y += heroH + 32 @@ -277,7 +292,7 @@ export default { ctx.save() this.rr(ctx, pos.x, pos.y, pos.w, pos.h, 16, 'fill') ctx.clip() - if (imgs[i]) { try { ctx.drawImage(imgs[i], pos.x, pos.y, pos.w, pos.h) } catch (e) {} } + if (imgs[i]) { this.drawImgFill(ctx, imgs[i], pos.x, pos.y, pos.w, pos.h) } else { ctx.setFillStyle(WHITE_05); ctx.fillRect(pos.x, pos.y, pos.w, pos.h) } ctx.restore() }