style: a lot of tweaks
Build and Deploy / build-and-deploy (push) Successful in 3m11s

This commit is contained in:
2026-07-10 07:08:43 +07:00 Unverified
parent 68ce40d51e
commit b5d5124e7c
6 changed files with 64 additions and 20 deletions
+1
View File
@@ -26,6 +26,7 @@
"patchedDependencies": { "patchedDependencies": {
"@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]", "@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]",
"@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]", "@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]",
"[email protected]": "patches/[email protected]",
}, },
"packages": { "packages": {
"@borewit/text-codec": ["@borewit/[email protected]", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="], "@borewit/text-codec": ["@borewit/[email protected]", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="],
+2 -1
View File
@@ -26,6 +26,7 @@
}, },
"patchedDependencies": { "patchedDependencies": {
"@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]", "@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]",
"@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]" "@takumi-rs/[email protected]": "patches/@takumi-rs%[email protected]",
"[email protected]": "patches/[email protected]"
} }
} }
+17
View File
@@ -0,0 +1,17 @@
diff --git a/dist/index.js b/dist/index.js
index 9be58624ef149017b5974099ca0a654310ed54d0..225d5a144bb3eeb5cd44e19dae82f3241f24151e 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -915,10 +915,10 @@ async function ensureStore() {
return { avatars: cachedAvatars, locs: cachedLocs };
const [avatarsRes, locsRes] = await Promise.all([
fetch(
- "https://github.com/EnkaNetwork/API-docs/raw/refs/heads/master/store/gi/avatars.json"
+ "https://api.enka.network/store/gi/avatars.json"
),
fetch(
- "https://github.com/EnkaNetwork/API-docs/raw/refs/heads/master/store/gi/locs.json"
+ "https://api.enka.network/store/gi/locs.json"
)
]);
const avatars = await avatarsRes.json();
+3 -3
View File
@@ -205,10 +205,10 @@ export async function generateBackground({
ctx.drawImage( ctx.drawImage(
texture, texture,
(texture.width - canvas.width) / 2,
0, 0,
0, canvas.width,
texture.width, canvas.height,
texture.height,
0, 0,
0, 0,
canvas.width, canvas.width,
+6 -1
View File
@@ -618,6 +618,8 @@ export function card(app: App) {
public: boolean; public: boolean;
settings?: { settings?: {
caption?: string; caption?: string;
artSource?: string;
adaptiveColor?: boolean;
}; };
image?: string; image?: string;
hoyo_type: number; hoyo_type: number;
@@ -673,7 +675,10 @@ export function card(app: App) {
avatarStore, avatarStore,
weaponStore, weaponStore,
relicStore, relicStore,
caption: avatar.settings?.caption, // caption: avatar.settings?.caption,
// artSource: avatar.settings?.artSource,
// adaptiveColor: avatar.settings?.adaptiveColor,
...avatar.settings,
locs, locs,
affixes, affixes,
customImage: avatar.image, customImage: avatar.image,
+35 -15
View File
@@ -55,7 +55,9 @@ type CharacterPageOptions = {
locs: EnkaLocs; locs: EnkaLocs;
affixes: EnkaAffixes; affixes: EnkaAffixes;
customImage?: string; customImage?: string;
artSource?: string;
caption?: string; caption?: string;
adaptiveColor?: boolean;
lang?: keyof EnkaLocs; lang?: keyof EnkaLocs;
height: number; height: number;
debug?: "none" | "render" | "dump"; debug?: "none" | "render" | "dump";
@@ -78,6 +80,8 @@ export async function CharacterPage({
height, height,
caption, caption,
customImage, customImage,
adaptiveColor,
artSource,
debug = "none", debug = "none",
enableSubstat = false, enableSubstat = false,
enableRollQuality = false, enableRollQuality = false,
@@ -180,24 +184,21 @@ export async function CharacterPage({
: assets.fnCache(`${avatarArtPath}-avatar`, async () => : assets.fnCache(`${avatarArtPath}-avatar`, async () =>
featherAvatar(await artBytesRes), featherAvatar(await artBytesRes),
); );
const backgroundRes = customImage const backgroundRes = adaptiveColor
? artBytesRes.then((artSource) => ? artBytesRes.then((artSource) =>
generateBackground({ generateBackground({
artSource, artSource,
element: avatar.Element, element: avatar.Element,
width: 1218, width: 1218,
height: 508, height: 508,
}).then((r) => r.canvas.toBuffer("image/webp")), }),
) )
: assets.fnCache( : assets.fnCache(`bg-${avatar.Element}`, async () =>
`bg-${avatar.Element}-${avatarArtPath}-1218x508`, generateBackground({
async () => element: avatar.Element,
generateBackground({ width: 1218,
artSource: await artBytesRes, height: 508,
element: avatar.Element, }).then((r) => r.canvas.toBuffer("image/webp")),
width: 1218,
height: 508,
}).then((r) => r.canvas.toBuffer("image/webp")),
); );
const resources = await Promise.all([ const resources = await Promise.all([
@@ -228,7 +229,15 @@ export async function CharacterPage({
), ),
})), })),
avatarRes.then((data) => ({ src: "/avatar", data })), avatarRes.then((data) => ({ src: "/avatar", data })),
backgroundRes.then((data) => ({ src: `/bg-${avatar.Element}`, data })), backgroundRes.then((data) => ({
src: `/bg-${avatar.Element}`,
data:
data instanceof Buffer || data instanceof ArrayBuffer
? data
: (
data as Awaited<ReturnType<typeof generateBackground>>
).canvas.toBuffer("image/webp"),
})),
] satisfies Promise<{ src: string; data: ArrayBuffer | Buffer }>[]); ] satisfies Promise<{ src: string; data: ArrayBuffer | Buffer }>[]);
log`Image resources loaded\n${resources.map((r) => `- ${r.src} ${(r.data.byteLength / 1000).toFixed(2)}Kb`).join("\n")}`; log`Image resources loaded\n${resources.map((r) => `- ${r.src} ${(r.data.byteLength / 1000).toFixed(2)}Kb`).join("\n")}`;
@@ -260,7 +269,11 @@ export async function CharacterPage({
return new ImageResponse( return new ImageResponse(
<div tw={`flex text-[${30.466 * (height / 1024)}px] font-[ShinShin]`}> <div tw={`flex text-[${30.466 * (height / 1024)}px] font-[ShinShin]`}>
<SubstatDisplay substat={rollSummary} element={avatar.Element}> <SubstatDisplay
substat={rollSummary}
element={avatar.Element}
accent={((await backgroundRes) as { accent: string }).accent}
>
<div <div
tw={`flex relative text-white rounded-[.5em] overflow-hidden aspect-[1218/508] h-[${height}px]`} tw={`flex relative text-white rounded-[.5em] overflow-hidden aspect-[1218/508] h-[${height}px]`}
> >
@@ -386,11 +399,15 @@ export async function CharacterPage({
</div> </div>
); );
})} })}
<div tw="text-[0.9em] -mb-[1.3em] mt-[1.3em] right-[.8em] opacity-70">
{" "}
{artSource}
</div>
</div> </div>
{/* caption */} {/* caption */}
{caption && ( {caption && (
<div tw="absolute bottom-[6%] left-[7%] right-[9.5%] z-10 flex justify-center"> <div tw="absolute bottom-[10%] left-[7%] right-[9.5%] z-10 flex justify-center">
<div tw="max-w-lg text-[0.95em] text-center bg-black/40 p-[0.5em_0.7em] border-[0.4em]"> <div tw="max-w-[19.5em] text-[0.95em] text-center bg-black/40 p-[0.5em_0.7em] border-[0.4em] leading-[1.55] rounded-[.5em]">
{caption} {caption}
</div> </div>
</div> </div>
@@ -660,11 +677,13 @@ export async function CharacterPage({
function SubstatDisplay({ function SubstatDisplay({
substat, substat,
element, element,
accent,
children, children,
}: { }: {
substat: RollSummary[] | undefined; substat: RollSummary[] | undefined;
element: string; element: string;
children?: React.ReactNode; children?: React.ReactNode;
accent?: string;
}) { }) {
if (!substat) return children; if (!substat) return children;
@@ -673,6 +692,7 @@ function SubstatDisplay({
<div <div
tw="flex h-[2.3em] bg-current relative -top-[.5em] pt-[.5em] -mb-[.5em] rounded-b-[.5em]" tw="flex h-[2.3em] bg-current relative -top-[.5em] pt-[.5em] -mb-[.5em] rounded-b-[.5em]"
className={`Talents ${element}`} className={`Talents ${element}`}
style={{ background: accent }}
> >
<div tw="text-white w-full flex items-center flex-wrap justify-end bg-black/25"> <div tw="text-white w-full flex items-center flex-wrap justify-end bg-black/25">
{substat.map((s) => ( {substat.map((s) => (