fix(poster) : show fifth base stat
CI / Verify (push) Successful in 1m38s
CI / Build immutable images and deploy (push) Successful in 2m5s

This commit is contained in:
2026-09-27 22:27:43 +07:00 Unverified
parent cb09f1af3e
commit 4d304eea62
2 changed files with 28 additions and 3 deletions
+5 -3
View File
@@ -83,7 +83,9 @@ export function MaterialPoster({
bleeding?: Array<{ id: string; imageUrl: string | null; amount: number; blendMode: PosterBlendMode }>; bleeding?: Array<{ id: string; imageUrl: string | null; amount: number; blendMode: PosterBlendMode }>;
}) { }) {
const dragStart = useRef<{ pointerId: number; x: number; y: number; offsetX: number; offsetY: number } | null>(null); const dragStart = useRef<{ pointerId: number; x: number; y: number; offsetX: number; offsetY: number } | null>(null);
const stats = character.baseStats.slice(0, 4); const stats = character.baseStats.slice(0, 5);
const statBoxCount = Math.max(4, stats.length);
const hasFiveStats = statBoxCount === 5;
const materials = mergePosterMaterials( const materials = mergePosterMaterials(
[...character.ascension, ...character.leveling].flatMap((group) => group.items), [...character.ascension, ...character.leveling].flatMap((group) => group.items),
); );
@@ -191,7 +193,7 @@ export function MaterialPoster({
<div className="absolute inset-x-[4%] top-[5%]" style={{ fontFamily: "Kanit Poster", fontWeight: 800, fontStyle: "italic" }}> <div className="absolute inset-x-[4%] top-[5%]" style={{ fontFamily: "Kanit Poster", fontWeight: 800, fontStyle: "italic" }}>
<h2 className="text-[7cqw] leading-none" style={{ textShadow: "-6px 14px 0 rgba(0,0,0,0.59)" }}>BASE STATS</h2> <h2 className="text-[7cqw] leading-none" style={{ textShadow: "-6px 14px 0 rgba(0,0,0,0.59)" }}>BASE STATS</h2>
<div className="mt-[4%] flex w-[53%] flex-col gap-[1.2cqw]"> <div className="mt-[4%] flex w-[53%] flex-col gap-[1.2cqw]">
{Array.from({ length: 4 }, (_, index) => { {Array.from({ length: statBoxCount }, (_, index) => {
const stat = stats[index]; const stat = stats[index];
const iconName = stat ? statIconName(stat.key) : null; const iconName = stat ? statIconName(stat.key) : null;
return ( return (
@@ -216,7 +218,7 @@ export function MaterialPoster({
</div> </div>
</div> </div>
<div className="absolute inset-x-[4%] top-[49%]" style={{ fontFamily: "Kanit Poster", fontWeight: 800, fontStyle: "italic" }}> <div className={cn("absolute inset-x-[4%]", hasFiveStats ? "top-[57%]" : "top-[49%]")} style={{ fontFamily: "Kanit Poster", fontWeight: 800, fontStyle: "italic" }}>
<h2 className="text-[7cqw] leading-none" style={{ textShadow: "-6px 14px 0 rgba(0,0,0,0.59)" }}>MATERIALS</h2> <h2 className="text-[7cqw] leading-none" style={{ textShadow: "-6px 14px 0 rgba(0,0,0,0.59)" }}>MATERIALS</h2>
<p className="mt-[1%] text-[4.5cqw] leading-none">LV.90</p> <p className="mt-[1%] text-[4.5cqw] leading-none">LV.90</p>
<div className="mt-[5%] grid grid-cols-8 gap-[1.2%]"> <div className="mt-[5%] grid grid-cols-8 gap-[1.2%]">
+23
View File
@@ -140,6 +140,29 @@ describe("material poster text", () => {
expect(html).not.toContain("เลเวล 90"); expect(html).not.toContain("เลเวล 90");
}); });
it("shows a fifth base stat in its own box", () => {
const html = renderToStaticMarkup(
<MaterialPoster
{...props}
character={{
...props.character,
baseStats: [
{ key: "hp", value: 12000 },
{ key: "atk", value: 300 },
{ key: "def", value: 700 },
{ key: "CRIT Rate%", value: 24.2 },
{ key: "Energy Recharge%", value: 132 },
],
}}
/>,
);
expect(html).toContain("Energy Recharge%");
expect(html).toContain("132%");
expect(html).toContain("h-[7cqw]");
expect(html).toContain("top-[57%]");
});
it("optimizes scale-aware character artwork and bleeding layers for export", () => { it("optimizes scale-aware character artwork and bleeding layers for export", () => {
const characterArtUrl = "https://buzz-cdn.astrxl.dev/posters/raiden.png"; const characterArtUrl = "https://buzz-cdn.astrxl.dev/posters/raiden.png";
const html = renderToStaticMarkup( const html = renderToStaticMarkup(