import path from 'node:path' import { fileURLToPath } from 'node:url' import sharp from 'sharp' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const rootDir = path.resolve(__dirname, '..') const animalDir = path.join(rootDir, 'src/assets/animal') const lightAnimalDir = path.join(rootDir, 'src/assets/light-animal') const columns = 6 const rows = 6 const cellWidth = 446 const cellHeight = 224 const quality = 82 async function generateSprite(sourceDir, outputFileName) { const outputPath = path.join(sourceDir, outputFileName) const composites = await Promise.all( Array.from({ length: columns * rows }, async (_, index) => { const id = index + 1 const input = path.join(sourceDir, `${id}.webp`) const left = (index % columns) * cellWidth const top = Math.floor(index / columns) * cellHeight const buffer = await sharp(input) .resize(cellWidth, cellHeight, { fit: 'cover', position: 'center', }) .webp({ quality }) .toBuffer() return { input: buffer, left, top, } }), ) await sharp({ create: { width: columns * cellWidth, height: rows * cellHeight, channels: 4, background: { r: 0, g: 0, b: 0, alpha: 0 }, }, }) .composite(composites) .webp({ quality }) .toFile(outputPath) console.log( `Generated ${path.relative(rootDir, outputPath)} (${columns}x${rows}, ${cellWidth}x${cellHeight})`, ) } await generateSprite(animalDir, 'animal-sprite.webp') await generateSprite(lightAnimalDir, 'light-animal-sprite.webp')