|
// Make animated webp file from individual frames |
|
|
|
// @ts-ignore: missing type |
|
import { Image } from 'node-webpmux'; |
|
import * as sharp from 'sharp'; |
|
|
|
import { promises as fs } from 'fs'; |
|
|
|
async function getOriginalFrames(inputDirectory: string) { |
|
const filePaths = await fs.readdir(inputDirectory).then(files => |
|
files.flatMap(file => file.endsWith('.png') ? `${inputDirectory}/${file}` : []) |
|
); |
|
filePaths.sort((a, b) => a.localeCompare(b, 'en', { numeric: true, ignorePunctuation: true })); |
|
return filePaths; |
|
} |
|
|
|
async function convertToWebP(inputFilePaths: string[]) { |
|
return await Promise.all(inputFilePaths.map(async filePath => { |
|
const webpFile = `${filePath}.webp`; |
|
await sharp(filePath).toFile(webpFile); |
|
return webpFile; |
|
})); |
|
} |
|
|
|
async function createWebPAnimation(inputDirectory: string, outputPath: string, delay: number): Promise<void> { |
|
const originFilePaths = await getOriginalFrames(inputDirectory); |
|
const framePaths = await convertToWebP(originFilePaths); |
|
|
|
await Image.initLib(); |
|
|
|
const firstFrame = new Image(); |
|
await firstFrame.load(await fs.readFile(framePaths[0])); |
|
firstFrame.convertToAnim(); |
|
|
|
const frames = await Promise.all( |
|
framePaths.map(async (path) => { |
|
const frame = new Image(); |
|
await frame.load(await fs.readFile(path)); |
|
return frame; |
|
}) |
|
); |
|
|
|
await firstFrame.save(outputPath, { |
|
frames: frames.map(frame => ({ |
|
img: frame, |
|
delay, |
|
})) |
|
}); |
|
} |
|
|
|
createWebPAnimation("frames", 'animation.webp', 100); |