mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-15 18:12:30 +00:00
9ddca18f54
The resize to 192px isn't worthwhile now that sprites are only downloaded when viewed or saved on request, and then kept forever. Restore the original files and the script's no-resize default, drop the detail view size cap, and regenerate the sprite manifest with the original sizes.
75 lines
2.3 KiB
JavaScript
75 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
import path from 'node:path';
|
|
import process from 'node:process';
|
|
import { mkdir, readdir, rename } from 'node:fs/promises';
|
|
import sharp from 'sharp';
|
|
import { writeSpriteManifest } from './sprite-manifest.mjs';
|
|
|
|
const inputDir = process.env.SPRITE_INPUT_DIR ?? path.join(process.cwd(), 'static', 'sprites');
|
|
const outputDir =
|
|
process.env.SPRITE_OUTPUT_DIR ?? path.join(process.cwd(), 'static', 'sprites-small');
|
|
const format = (process.env.SPRITE_FORMAT ?? 'webp').toLowerCase();
|
|
const quality = Number(process.env.SPRITE_QUALITY ?? 80);
|
|
const maxSize = Number(process.env.SPRITE_MAX_SIZE ?? 0);
|
|
|
|
if (!['png', 'webp'].includes(format)) {
|
|
console.error(`Unsupported SPRITE_FORMAT "${format}". Use "png" or "webp".`);
|
|
process.exit(1);
|
|
}
|
|
|
|
async function walk(dir, files = []) {
|
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
for (const entry of entries) {
|
|
const fullPath = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
await walk(fullPath, files);
|
|
continue;
|
|
}
|
|
if (entry.isFile() && entry.name.toLowerCase().endsWith('.png')) {
|
|
files.push(fullPath);
|
|
}
|
|
}
|
|
return files;
|
|
}
|
|
|
|
const files = await walk(inputDir);
|
|
console.log(`Optimizing ${files.length} sprite images from ${inputDir}`);
|
|
|
|
for (const [index, file] of files.entries()) {
|
|
const relative = path.relative(inputDir, file);
|
|
const baseName = path.basename(file, path.extname(file));
|
|
const targetDir = path.join(outputDir, path.dirname(relative));
|
|
await mkdir(targetDir, { recursive: true });
|
|
|
|
const targetExt = format === 'png' ? '.png' : '.webp';
|
|
const targetPath = path.join(targetDir, `${baseName}${targetExt}`);
|
|
const tempPath = format === 'png' && outputDir === inputDir ? `${targetPath}.tmp` : targetPath;
|
|
|
|
const pipeline = sharp(file);
|
|
if (maxSize > 0) {
|
|
pipeline.resize({
|
|
width: maxSize,
|
|
height: maxSize,
|
|
fit: 'inside',
|
|
withoutEnlargement: true
|
|
});
|
|
}
|
|
|
|
if (format === 'png') {
|
|
await pipeline.png({ compressionLevel: 9, palette: true, quality }).toFile(tempPath);
|
|
} else {
|
|
await pipeline.webp({ quality }).toFile(tempPath);
|
|
}
|
|
|
|
if (tempPath !== targetPath) {
|
|
await rename(tempPath, targetPath);
|
|
}
|
|
|
|
if ((index + 1) % 250 === 0) {
|
|
console.log(`Processed ${index + 1}/${files.length}`);
|
|
}
|
|
}
|
|
|
|
const manifest = await writeSpriteManifest(outputDir);
|
|
console.log(`Sprite optimization complete. Manifest lists ${manifest.files.length} sprites.`);
|