From 9abc74fbc408c196862ae6f43b9bd822a33b78c0 Mon Sep 17 00:00:00 2001 From: zihanjian Date: Sat, 7 Jun 2025 22:24:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96CompletionCard=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E7=BB=98=E5=88=B6=E6=95=88=E6=9E=9C=EF=BC=8C?= =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=83=8C=E6=99=AF=E6=B8=90=E5=8F=98=E3=80=81?= =?UTF-8?q?=E8=BE=B9=E6=A1=86=E6=A0=B7=E5=BC=8F=E5=92=8C=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E6=96=B9=E5=BC=8F=EF=BC=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E6=95=B4=E4=BD=93=E7=BE=8E=E8=A7=82=E6=80=A7=E5=92=8C=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/CompletionCard.tsx | 104 +++++++++++++++++------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/src/components/CompletionCard.tsx b/src/components/CompletionCard.tsx index 6271fb5..373bd8b 100644 --- a/src/components/CompletionCard.tsx +++ b/src/components/CompletionCard.tsx @@ -173,75 +173,89 @@ const CompletionCard: React.FC = ({ const userImg = new Image(); userImg.onload = () => { if (isUsingPixelArt) { - // ===== 拼豆原图模式:极简像素风格 ===== + // ===== 拼豆原图模式:原图占主导 ===== - // 统一的深色背景 - ctx.fillStyle = '#0A0A0A'; + // 深色渐变背景,更有质感 + const gradient = ctx.createLinearGradient(0, 0, 0, cardHeight); + gradient.addColorStop(0, '#1a1a2e'); + gradient.addColorStop(0.3, '#16213e'); + gradient.addColorStop(0.7, '#0f3460'); + gradient.addColorStop(1, '#533483'); + ctx.fillStyle = gradient; ctx.fillRect(0, 0, cardWidth, cardHeight); // 计算拼豆图尺寸,保持原始宽高比 const imgAspectRatio = userImg.naturalWidth / userImg.naturalHeight; - const maxWidth = cardWidth * 0.8; - const maxHeight = cardHeight * 0.65; + const maxWidth = cardWidth * 0.9; + const maxHeight = cardHeight * 0.6; let imageWidth, imageHeight; if (maxWidth / maxHeight > imgAspectRatio) { + // 以高度为准 imageHeight = maxHeight; imageWidth = imageHeight * imgAspectRatio; } else { + // 以宽度为准 imageWidth = maxWidth; imageHeight = imageWidth / imgAspectRatio; } const imageX = (cardWidth - imageWidth) / 2; - const imageY = (cardHeight - imageHeight) / 2 - 60; + const imageY = (cardHeight - imageHeight) / 2 - 80; // 往上偏移更多 - // 像素风格边框 - const pixelBorder = 4; - ctx.fillStyle = '#FFFFFF'; - ctx.fillRect(imageX - pixelBorder, imageY - pixelBorder, - imageWidth + pixelBorder * 2, imageHeight + pixelBorder * 2); + // 绘制主图片的装饰背景和阴影 + ctx.save(); + // 外层光晕效果 + const glowGradient = ctx.createRadialGradient( + imageX + imageWidth/2, imageY + imageHeight/2, Math.min(imageWidth, imageHeight)/2, + imageX + imageWidth/2, imageY + imageHeight/2, Math.min(imageWidth, imageHeight)/2 + 30 + ); + glowGradient.addColorStop(0, 'rgba(255,255,255,0.1)'); + glowGradient.addColorStop(1, 'rgba(255,255,255,0)'); + ctx.fillStyle = glowGradient; + ctx.fillRect(imageX - 30, imageY - 30, imageWidth + 60, imageHeight + 60); - // 内层暗色边框,增加层次 - ctx.fillStyle = '#333333'; - ctx.fillRect(imageX - pixelBorder + 1, imageY - pixelBorder + 1, - imageWidth + (pixelBorder - 1) * 2, imageHeight + (pixelBorder - 1) * 2); + // 白色边框背景 + ctx.fillStyle = '#ffffff'; + ctx.shadowColor = 'rgba(0,0,0,0.3)'; + ctx.shadowBlur = 25; + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 15; + const borderWidth = 12; + ctx.fillRect(imageX - borderWidth, imageY - borderWidth, + imageWidth + borderWidth * 2, imageHeight + borderWidth * 2); + ctx.restore(); // 绘制拼豆原图 ctx.drawImage(userImg, imageX, imageY, imageWidth, imageHeight); - // 底部信息区域 - const infoY = imageY + imageHeight + 60; - - // 创建信息背景条 - const infoBarHeight = 50; - const infoBarWidth = cardWidth * 0.85; - const infoBarX = (cardWidth - infoBarWidth) / 2; - - ctx.fillStyle = '#1A1A1A'; - ctx.fillRect(infoBarX, infoY - 15, infoBarWidth, infoBarHeight); - - // 像素风格装饰线 - ctx.fillStyle = '#00FF88'; - ctx.fillRect(infoBarX, infoY - 15, infoBarWidth, 2); - ctx.fillRect(infoBarX, infoY + infoBarHeight - 17, infoBarWidth, 2); - - // 信息文字 - 现代等宽字体风格 - ctx.fillStyle = '#FFFFFF'; - ctx.font = '16px "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", monospace'; + // 顶部区域:简洁的完成标识 + ctx.fillStyle = '#ffffff'; + ctx.font = 'bold 28px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; ctx.textAlign = 'center'; - - const timeText = `TIME: ${formatTime(totalElapsedTime)}`; - const beadText = `BEADS: ${totalBeads}`; - ctx.fillText(`${timeText} | ${beadText}`, cardWidth / 2, infoY + 15); + ctx.shadowColor = 'rgba(0,0,0,0.3)'; + ctx.shadowBlur = 8; + ctx.fillText('🎉 作品完成 🎉', cardWidth / 2, 80); + ctx.shadowBlur = 0; - // 底部品牌信息 - 极简风格 - ctx.font = '12px "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", monospace'; - ctx.fillStyle = '#666666'; - ctx.fillText('PERLER BEADS GENERATOR', cardWidth / 2, cardHeight - 30); - ctx.font = '10px "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", monospace'; - ctx.fillStyle = '#444444'; - ctx.fillText('perlerbeads.zippland.com', cardWidth / 2, cardHeight - 15); + // 底部信息区域:直接显示文字 + const infoY = imageY + imageHeight + 40; + + // 信息文字 - 一行显示 + ctx.fillStyle = '#ffffff'; + ctx.font = 'bold 22px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; + ctx.textAlign = 'center'; + ctx.shadowColor = 'rgba(0,0,0,0.5)'; + ctx.shadowBlur = 8; + ctx.fillText(`⏱️ ${formatTime(totalElapsedTime)} | 🔗 完成 ${totalBeads} 颗豆子`, cardWidth / 2, infoY + 40); + + // 底部品牌信息 + ctx.font = '14px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; + ctx.fillStyle = 'rgba(255,255,255,0.7)'; + ctx.fillText('七卡瓦拼豆底稿生成器', cardWidth / 2, cardHeight - 50); + ctx.font = '12px system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'; + ctx.fillStyle = 'rgba(255,255,255,0.5)'; + ctx.fillText('perlerbeads.zippland.com', cardWidth / 2, cardHeight - 25); resolve(canvas.toDataURL('image/jpeg', 0.95));