From 8a4b44666f5fd2ddaa584a19315c0edc509adb4e Mon Sep 17 00:00:00 2001 From: kron Date: Fri, 14 Nov 2025 18:13:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=88=86=E4=BA=AB=E8=AE=A1?= =?UTF-8?q?=E5=88=86=E8=AF=A6=E6=83=85=E7=9A=84=E6=9F=B1=E7=8A=B6=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util.js | 128 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 7 deletions(-) diff --git a/src/util.js b/src/util.js index 4c4c8cb..8dd95d6 100644 --- a/src/util.js +++ b/src/util.js @@ -874,22 +874,35 @@ export const generateShareCard = (canvasId, date, actual, total) => { } }; +export function drawLine(ctx, x1, y1, x2, y2, color = "#000", width = 1) { + ctx.beginPath(); + ctx.lineWidth = width; + ctx.strokeStyle = color; + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); +} + export const generateShareImage = async (canvasId, data) => { try { const pointBook = uni.getStorageSync("point-book"); + const arrowData = data.groups && data.groups[0] ? data.groups[0] : {}; + console.log(arrowData); + // const hasPoint = arrowData.list.some((arrow) => arrow.x && arrow.y); + const hasPoint = true; console.log("generate data:", data, pointBook); const ctx = uni.createCanvasContext(canvasId); const width = 375; - const height = 800; + const height = hasPoint ? 800 : 440; ctx.setFillStyle("#F5F5F5"); ctx.fillRect(0, 0, width, height); const bgUrl = await loadImage( - "https://static.shelingxingqiu.com/attachment/2025-11-14/de82iol96zxgwxbjhb.png" + "https://static.shelingxingqiu.com/attachment/2025-11-14/de88ugdgqwecnmsqfv.png" ); - ctx.drawImage(bgUrl, 0, 0, width, height); + ctx.drawImage(bgUrl, 0, 0, width, 300); const avatarUrl = await loadImage(data.user.avatar); drawRoundImage(ctx, avatarUrl, 13, 13, 54, 54, 27, "#000", 1); renderText(ctx, data.user.name, 18, "#000", 84, 36); @@ -933,10 +946,111 @@ export const generateShareImage = async (canvasId, data) => { 6, 2 ); - // const pointBookQrcodeUrl = await loadImage( - // "https://static.shelingxingqiu.com/attachment/2025-11-13/de7fzgghsfgqu0ytu6.png" - // ); - // ctx.drawImage(pointBookQrcodeUrl, 45, 777, 68, 68); + renderText(ctx, "落点稳定性", 13, "#999", 25, 110); + renderText(ctx, "黄心率", 13, "#999", 145, 110); + renderText(ctx, "10环数", 13, "#999", 262, 110); + + renderText(ctx, arrowData.stability, 15, "#000", 25, 133); + renderText( + ctx, + Number((arrowData.yellowRate * 100).toFixed(2)) + "%", + 15, + "#000", + 145, + 133 + ); + renderText(ctx, arrowData.tenRings, 15, "#000", 262, 133); + renderText(ctx, "平均环数", 13, "#999", 25, 175); + renderText(ctx, "总换数", 13, "#999", 145, 175); + renderText(ctx, arrowData.averageRing, 15, "#000", 25, 200); + renderText( + ctx, + `${arrowData.userTotalRing}/${arrowData.totalRing}`, + 15, + "#000", + 145, + 200 + ); + if (hasPoint) { + drawRoundedRect(ctx, 20, 230, 5, 15, 5, "#FED847"); + renderText(ctx, "落点分布", 13, "#999", 32, 242); + const bowUrl = await loadImage(pointBook.bowtargetType.iconPng); + ctx.drawImage(bowUrl, 375 * 0.08, 250, 375 * 0.84, 375 * 0.84); + arrowData.list.forEach((arrow) => {}); + } + const ringNames = ["X", 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, "M"]; + const ringBarHeight = hasPoint ? 700 : 340; + // 统计每个环数的次数 + let rings = new Array(12).fill(0); + arrowData.list.forEach((arrow) => { + if (arrow.ring === 0) rings[0]++; + else if (arrow.ring === -1) rings[11]++; + else rings[arrow.ring]++; + }); + [rings[0], rings[11]] = [rings[11], rings[0]]; + rings = rings.reverse(); + rings = rings.map((count) => ({ + count, + rate: count / arrowData.list.length, + })); + // 渲染柱子 + const barColor = (rate) => { + if (rate >= 0.4) return "#FDC540"; + if (rate >= 0.2) return "#FED847"; + return "#ffe88f"; + }; + const barWidth = 20; + const barSpacing = 7.1; + const startX = 38; + const startY = ringBarHeight - 15; + rings.forEach((ring, index) => { + const barHeight = ring.rate * 90; + if (ring.rate > 0) { + renderText( + ctx, + Number((ring.rate * 100).toFixed(1)) + "%", + 9, + "#333", + startX + index * (barWidth + barSpacing), + startY - barHeight - 3 + ); + } + ctx.fillStyle = barColor(ring.rate); + ctx.fillRect( + startX + index * (barWidth + barSpacing), + startY - barHeight, + barWidth, + barHeight + ); + }); + + renderText(ctx, "环值", 9, "#999", 15, ringBarHeight - 1); + ringNames.forEach((ring, index) => { + renderText( + ctx, + ring, + 11, + "#333", + 48 + index * 27, + ringBarHeight, + "center" + ); + }); + drawLine(ctx, 15, ringBarHeight - 15, 362, ringBarHeight - 15, "#333"); + const pointBookQrcodeUrl = await loadImage( + "https://static.shelingxingqiu.com/attachment/2025-11-13/de7fzgghsfgqu0ytu6.png" + ); + ctx.drawImage(pointBookQrcodeUrl, 40, hasPoint ? 715 : 360, 68, 68); + renderText(ctx, "射灵星球", 18, "#333", 120, hasPoint ? 737 : 380); + renderText( + ctx, + "高效记录每一箭,快来一起打卡吧!", + 13, + "#999", + 120, + hasPoint ? 759 : 402 + ); + renderText(ctx, "扫码打卡", 13, "#FFA118", 120, hasPoint ? 780 : 422); ctx.draw(); } catch (e) { console.error("generateShareImage 绘制失败:", e);