From 5a2e2e4829f964319171f085238cc8b66a5f0c5b Mon Sep 17 00:00:00 2001 From: gunshiz Date: Wed, 2 Sep 2026 07:59:49 +0700 Subject: [PATCH] fix(weapon-export) : align image with public layout --- .../guides/[guideId]/weapons/image/route.tsx | 131 ++++++++++++------ 1 file changed, 85 insertions(+), 46 deletions(-) diff --git a/app/api/guides/[guideId]/weapons/image/route.tsx b/app/api/guides/[guideId]/weapons/image/route.tsx index c8b6f37..066d775 100644 --- a/app/api/guides/[guideId]/weapons/image/route.tsx +++ b/app/api/guides/[guideId]/weapons/image/route.tsx @@ -10,6 +10,10 @@ const anuphanFonts = Promise.all( [ { subset: "latin", weight: 400 as const }, { subset: "thai", weight: 400 as const }, + { subset: "latin", weight: 500 as const }, + { subset: "thai", weight: 500 as const }, + { subset: "latin", weight: 600 as const }, + { subset: "thai", weight: 600 as const }, { subset: "latin", weight: 700 as const }, { subset: "thai", weight: 700 as const }, ].map(async ({ subset, weight }) => { @@ -33,12 +37,21 @@ function metric(value: string): string { : `${Number(value).toLocaleString("en-US", { maximumFractionDigits: 2 })}%`; } +function wrappedLineCount(value: string, lineLength: number): number { + return value + .split(/\r?\n/u) + .reduce( + (lines, line) => lines + Math.max(1, Math.ceil(line.length / lineLength)), + 0, + ); +} + async function pngDataUrl(url: string): Promise { try { const response = await fetch(url); if (!response.ok) return null; const png = await sharp(Buffer.from(await response.arrayBuffer())) - .resize(120, 120, { fit: "contain" }) + .resize(80, 80, { fit: "contain" }) .png() .toBuffer(); return `data:image/png;base64,${png.toString("base64")}`; @@ -59,18 +72,19 @@ export async function GET( anuphanFonts, Promise.all(guide.weapons.map((row) => pngDataUrl(row.weapon.imageUrl))), ]); - const weaponHeights = guide.weapons.map((row) => - Math.max(126, 126 + (row.note ? Math.ceil(row.note.length / 52) * 22 : 0)), - ); - const noteHeight = guide.note - ? Math.max(24, Math.ceil(guide.note.length / 70) * 22) - : 0; + const weaponHeights = guide.weapons.map((row) => { + const noteLines = row.note ? wrappedLineCount(row.note, 58) : 0; + return Math.max(112, noteLines ? 64 + noteLines * 22 : 112); + }); + const noteLines = guide.note ? wrappedLineCount(guide.note, 70) : 0; + const headerHeight = 72 + (noteLines ? 12 + noteLines * 24 : 0); const height = Math.max( 360, - 190 + - noteHeight + + 64 + + headerHeight + + 24 + weaponHeights.reduce((sum, rowHeight) => sum + rowHeight, 0) + - Math.max(0, guide.weapons.length - 1) * 14, + Math.max(0, guide.weapons.length - 1) * 12, ); return new ImageResponse( @@ -80,22 +94,18 @@ export async function GET( height: "100%", display: "flex", flexDirection: "column", - gap: 14, - color: "#f7f7f7", - background: "#05060a", + color: "#f2eee6", + background: "#06070c", padding: "32px 36px", fontFamily: "Anuphan", - position: "relative", }} >
อาวุธที่แนะนำ
-
+
Weapons
{guide.note ? ( @@ -125,10 +143,11 @@ export async function GET( style={{ display: "flex", maxWidth: 760, - color: "#b9b9c2", + color: "#9b9eaa", fontSize: 16, - lineHeight: 1.4, + lineHeight: 1.5, textAlign: "center", + whiteSpace: "pre-wrap", }} > {guide.note} @@ -142,18 +161,17 @@ export async function GET( display: "flex", minHeight: weaponHeights[index], overflow: "hidden", - border: "1px solid rgba(247, 247, 247, 0.1)", + border: "1px solid rgba(242, 238, 230, 0.1)", borderRadius: 14, background: "#ffffff", }} >
{weaponImages[index] ? ( ) : (
)}
{index + 1}. {row.weapon.name} R{row.refinement}
@@ -205,7 +235,8 @@ export async function GET( style={{ display: "flex", fontSize: 14, - lineHeight: 1.55, + lineHeight: 1.43, + whiteSpace: "pre-wrap", }} > {row.note} @@ -220,9 +251,9 @@ export async function GET( flex: 1, alignItems: "center", justifyContent: "space-around", - gap: 12, - color: "#17171c", - padding: "12px 16px", + gap: 16, + color: "#000000", + padding: "20px 16px", }} > {row.overallPercent ? ( @@ -238,13 +269,17 @@ export async function GET( style={{ display: "flex", color: rarityTextColor(row.weapon.rarity), - fontSize: 36, + fontSize: 48, fontWeight: 700, + lineHeight: 1, + whiteSpace: "nowrap", }} > {metric(row.overallPercent)}
-
+
ดาเมททั้งทีม
@@ -262,13 +297,17 @@ export async function GET( style={{ display: "flex", color: rarityTextColor(row.weapon.rarity), - fontSize: 36, + fontSize: 48, fontWeight: 700, + lineHeight: 1, + whiteSpace: "nowrap", }} > {metric(row.personalPercent)}
-
+
ดาเมจส่วนตัว