Support custom character image folders and document structure

This commit is contained in:
Pandipipas
2026-02-12 02:02:07 +01:00
parent f38d15c681
commit de11a1dea7
2 changed files with 56 additions and 7 deletions
+35 -7
View File
@@ -24,11 +24,11 @@ const paletteByGame: Record<string, [string, string]> = {
'2XKO': ['#22d3ee', '#0f766e'],
};
const toCharacterValue = (character: string) => character.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
const toSlug = (value: string) => value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '');
const toDataUrl = (svg: string) => `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
const buildCharacterImage = (game: string, character: string) => {
const buildCharacterPlaceholder = (game: string, character: string) => {
const [startColor, endColor] = paletteByGame[game] ?? ['#334155', '#0f172a'];
const initials = character
.split(/\s+/)
@@ -55,14 +55,42 @@ const buildCharacterImage = (game: string, character: string) => {
return toDataUrl(svg.trim());
};
const characterImageModules = import.meta.glob('/src/shared/character-images/**/*.{png,jpg,jpeg,webp,avif,svg}', {
eager: true,
import: 'default',
query: '?url',
}) as Record<string, string>;
const characterImageByKey = Object.entries(characterImageModules).reduce<Record<string, string>>((acc, [path, url]) => {
const segments = path.split('/');
const gameFolder = segments.at(-2);
const filename = segments.at(-1);
if (!gameFolder || !filename) {
return acc;
}
const characterSlug = filename.replace(/\.[^.]+$/, '');
acc[`${gameFolder}/${characterSlug}`] = url;
return acc;
}, {});
const getCharacterImage = (game: string, character: string, characterValue: string) => {
const gameSlug = toSlug(game);
const key = `${gameSlug}/${characterValue}`;
return characterImageByKey[key] ?? buildCharacterPlaceholder(game, character);
};
export const fightingCharactersByGame: Record<string, FightingCharacterOption[]> = Object.fromEntries(
Object.entries(characterNamesByGame).map(([game, characterNames]) => [
game,
characterNames.map((character) => ({
label: character,
value: toCharacterValue(character),
image: buildCharacterImage(game, character),
})),
characterNames.map((character) => {
const value = toSlug(character);
return {
label: character,
value,
image: getCharacterImage(game, character, value),
};
}),
]),
);