From 76934eb094bb5e2e4fa2a0cc69b45707cecf2dc5 Mon Sep 17 00:00:00 2001 From: Poker Design Developer Date: Wed, 3 Jun 2026 22:28:21 +0800 Subject: [PATCH] feat: drawBackSide uses back_design with pattern color tint --- frontend/src/utils/cardRenderer.js | 43 +++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/frontend/src/utils/cardRenderer.js b/frontend/src/utils/cardRenderer.js index 61e146d..ecd611d 100644 --- a/frontend/src/utils/cardRenderer.js +++ b/frontend/src/utils/cardRenderer.js @@ -44,6 +44,7 @@ function loadImage(url) { async function preloadAll(project) { const urls = new Set() if (project.design?.background_image) urls.add(project.design.background_image) + if (project.back_design?.image) urls.add(project.back_design.image) for (const s of Object.keys(project.design?.suit_symbols || {})) { const sym = project.design.suit_symbols[s] if (sym?.type === 'image' && sym.asset_id) { @@ -356,19 +357,30 @@ async function drawJokerBody(ctx, w, h, which, design, project) { ctx.restore() } -async function drawBackSide(ctx, w, h, design, project) { - ctx.fillStyle = design.background_color || '#1A237E' +async function drawBackSide(ctx, w, h, backDesign, project) { + ctx.fillStyle = backDesign.background_color || '#1A237E' ctx.fillRect(0, 0, w, h) + const bw = Number(backDesign.border_width) || 0 + if (bw > 0) { + ctx.save() + ctx.strokeStyle = backDesign.border_color || '#C0A050' + ctx.lineWidth = bw + const half = bw / 2 + drawRoundedRect(ctx, half, half, w - bw, h - bw, 16) + ctx.stroke() + ctx.restore() + } + const padX = Math.round(w * 0.15) const padTop = Math.round(h * 0.18) const padBot = Math.round(h * 0.22) const bodyW = w - 2 * padX const bodyH = h - padTop - padBot - const imageDx = Number(design.image_dx) || 0 - const imageDy = Number(design.image_dy) || 0 - const imageScale = Number(design.image_scale) || 1 + const imageDx = Number(backDesign.image_dx) || 0 + const imageDy = Number(backDesign.image_dy) || 0 + const imageScale = Number(backDesign.image_scale) || 1 const offsetX = bodyW * imageDx const offsetY = bodyH * imageDy @@ -393,17 +405,21 @@ async function drawBackSide(ctx, w, h, design, project) { const drawX = padX + offsetX + (bodyW - finalW) / 2 const drawY = padTop + offsetY + (bodyH - finalH) / 2 ctx.drawImage(img, drawX, drawY, finalW, finalH) + + if (backDesign.pattern_color) { + ctx.save() + ctx.globalCompositeOperation = 'source-atop' + ctx.fillStyle = backDesign.pattern_color + ctx.globalAlpha = 0.3 + ctx.fillRect(0, 0, w, h) + ctx.restore() + } } else { ctx.save() - ctx.strokeStyle = design.border_color || '#FFFFFF' - ctx.lineWidth = 6 - const m = w * 0.06 - drawRoundedRect(ctx, m, m, w - 2 * m, h - 2 * m, 16) - ctx.stroke() - ctx.fillStyle = design.border_color || '#FFFFFF' + ctx.fillStyle = backDesign.border_color || '#C0A050' ctx.textAlign = 'center' ctx.textBaseline = 'middle' - ctx.font = `bold ${Math.round(w * 0.1)}px ${design.font_family || 'Times New Roman'}, serif` + ctx.font = `bold ${Math.round(w * 0.1)}px Times New Roman, serif` ctx.fillText('CARD BACK', w / 2, h / 2) ctx.restore() } @@ -444,7 +460,8 @@ export async function renderCard(canvas, project, cardKey) { await drawJokerBody(ctx, w, h, which, design, project) drawBorder(ctx, w, h, design) } else if (cardKey === 'back') { - await drawBackSide(ctx, w, h, design, project) + const backDesign = getEffectiveBackDesign(project) + await drawBackSide(ctx, w, h, backDesign, project) } else { const [suit, rank] = cardKey.split('-') drawBackground(ctx, w, h, design)