diff --git a/components/LuckyPopup/LuckyPopup.vue b/components/LuckyPopup/LuckyPopup.vue index b054c7a..d5a1cfa 100644 --- a/components/LuckyPopup/LuckyPopup.vue +++ b/components/LuckyPopup/LuckyPopup.vue @@ -251,78 +251,108 @@ const onSaveImage = () => { // 5. 绘制内容区 (宜/忌) const gridY = 400; const boxW = (W - 64 - 24) / 2; // (600 - padding*2 - gap)/2 + const gridH = 140; // 增加高度防止内容溢出 // 宜 - drawBox(ctx, 32, gridY, boxW, 120, "#fbfbfb", "#f5f5f5"); + drawBox(ctx, 32, gridY, boxW, gridH, "#fbfbfb", "#f5f5f5"); ctx.setTextAlign("left"); ctx.setFontSize(24); ctx.setFillStyle("#d81e06"); - ctx.fillText("✔ 今日宜", 56, gridY + 40); + ctx.font = "bold 24px sans-serif"; + // 图标模拟 + ctx.fillText("✔ 今日宜", 56, gridY + 44); + ctx.setFontSize(22); ctx.setFillStyle("#666666"); - wrapText(ctx, resultData.value.yi, 56, gridY + 70, boxW - 48, 30); + ctx.font = "normal 22px sans-serif"; + wrapText(ctx, resultData.value.yi, 56, gridY + 80, boxW - 48, 30); // 忌 - drawBox(ctx, 32 + boxW + 24, gridY, boxW, 120, "#fbfbfb", "#f5f5f5"); + drawBox(ctx, 32 + boxW + 24, gridY, boxW, gridH, "#fbfbfb", "#f5f5f5"); ctx.setFontSize(24); ctx.setFillStyle("#666666"); - ctx.fillText("✖ 今日忌", 32 + boxW + 24 + 24, gridY + 40); + ctx.font = "bold 24px sans-serif"; + ctx.fillText("✖ 今日忌", 32 + boxW + 24 + 24, gridY + 44); + ctx.setFontSize(22); + ctx.font = "normal 22px sans-serif"; wrapText( ctx, resultData.value.ji, 32 + boxW + 24 + 24, - gridY + 70, + gridY + 80, boxW - 48, 30, ); // 6. 幸运元素 - const elY = 540; - drawBox(ctx, 32, elY, W - 64, 120, "#fbfbfb", "#f5f5f5"); + const elY = 570; // 下移,避免与上面重叠 + const elH = 160; // 增加高度 + drawBox(ctx, 32, elY, W - 64, elH, "#fbfbfb", "#f5f5f5"); // 标题 ctx.setFontSize(26); ctx.setFillStyle("#333333"); - ctx.fillText("★ 幸运元素", 56, elY + 40); + ctx.font = "bold 26px sans-serif"; + ctx.fillText("★ 幸运元素", 56, elY + 46); // 元素内容 - const colW = (W - 64) / 3; - const valY = elY + 90; + const contentW = W - 64; // 内容区域总宽度 + const colW = contentW / 3; // 三等分 + const startX = 32; // 起始X坐标 - // 颜色 + // 调整Y坐标,确保不重叠 + const labelY = elY + 90; + const valY = elY + 126; + + // 颜色 (第一列) ctx.setTextAlign("center"); ctx.setFontSize(20); ctx.setFillStyle("#999999"); - ctx.fillText("颜色", 32 + colW * 0.5, elY + 60); + ctx.font = "normal 20px sans-serif"; + ctx.fillText("颜色", startX + colW * 0.5, labelY); + ctx.setFontSize(26); ctx.setFillStyle("#d84315"); ctx.font = "bold 26px sans-serif"; - ctx.fillText(resultData.value.luckyColor, 32 + colW * 0.5, valY); + ctx.fillText(resultData.value.luckyColor, startX + colW * 0.5, valY); - // 数字 + // 数字 (第二列) ctx.setFontSize(20); ctx.setFillStyle("#999999"); - ctx.fillText("数字", 32 + colW * 1.5, elY + 60); + ctx.font = "normal 20px sans-serif"; + ctx.fillText("数字", startX + colW * 1.5, labelY); + ctx.setFontSize(26); ctx.setFillStyle("#333333"); - ctx.fillText(resultData.value.luckyNumber, 32 + colW * 1.5, valY); + ctx.font = "bold 26px sans-serif"; + ctx.fillText(resultData.value.luckyNumber, startX + colW * 1.5, valY); - // 方向 + // 方向 (第三列) ctx.setFontSize(20); ctx.setFillStyle("#999999"); - ctx.fillText("方向", 32 + colW * 2.5, elY + 60); + ctx.font = "normal 20px sans-serif"; + ctx.fillText("方向", startX + colW * 2.5, labelY); + ctx.setFontSize(26); ctx.setFillStyle("#333333"); - ctx.fillText(resultData.value.luckyDirection, 32 + colW * 2.5, valY); + ctx.font = "bold 26px sans-serif"; + ctx.fillText(resultData.value.luckyDirection, startX + colW * 2.5, valY); - // 分隔线 + // 分隔线 1 ctx.setStrokeStyle("#eeeeee"); + ctx.setLineWidth(2); ctx.beginPath(); - ctx.moveTo(32 + colW, elY + 30); - ctx.lineTo(32 + colW, elY + 90); - ctx.moveTo(32 + colW * 2, elY + 30); - ctx.lineTo(32 + colW * 2, elY + 90); + const lineTop = elY + 70; + const lineBottom = elY + 130; + ctx.moveTo(startX + colW, lineTop); + ctx.lineTo(startX + colW, lineBottom); + ctx.stroke(); + + // 分隔线 2 + ctx.beginPath(); + ctx.moveTo(startX + colW * 2, lineTop); + ctx.lineTo(startX + colW * 2, lineBottom); ctx.stroke(); // 7. 语录 @@ -330,7 +360,8 @@ const onSaveImage = () => { ctx.setFontSize(22); ctx.setFillStyle("#999999"); ctx.font = "italic 22px sans-serif"; - ctx.fillText(`“${resultData.value.quote}”`, W / 2, 720); + // 语录换行处理,下移坐标 + wrapTextCentered(ctx, `“${resultData.value.quote}”`, W / 2, 780, W - 80, 30); // 8. 底部区域 (Footer) const footerY = 850; @@ -435,6 +466,25 @@ function wrapText(ctx, text, x, y, maxWidth, lineHeight) { ctx.fillText(line, x, y); } +// 辅助函数:文字换行(居中) +function wrapTextCentered(ctx, text, x, y, maxWidth, lineHeight) { + let words = text.split(""); + let line = ""; + for (let n = 0; n < words.length; n++) { + let testLine = line + words[n]; + let metrics = ctx.measureText(testLine); + let testWidth = metrics.width; + if (testWidth > maxWidth && n > 0) { + ctx.fillText(line, x, y); + line = words[n]; + y += lineHeight; + } else { + line = testLine; + } + } + ctx.fillText(line, x, y); +} + const onShareMoments = () => { uni.showToast({ title: "请点击右上角分享", icon: "none" }); };