diff --git a/assets/js/gif.js b/assets/js/gif.js new file mode 100644 index 0000000..2510a12 --- /dev/null +++ b/assets/js/gif.js @@ -0,0 +1,33 @@ +function loadImage(src) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.crossOrigin = "anonymous"; + img.onload = () => resolve(img); + img.onerror = reject; + img.src = src; + }); +} + +export async function buildGifFromFrames(frames, fps = 6) { + if (!frames?.length) throw new Error("No frames to build GIF."); + + const delay = Math.max(40, Math.floor(1000 / Math.max(1, fps))); + const images = await Promise.all(frames.map(loadImage)); + + const gif = new GIF({ + workers: 2, + quality: 10, + workerScript: "https://cdn.jsdelivr.net/npm/gif.js.optimized/dist/gif.worker.js", + width: images[0].naturalWidth, + height: images[0].naturalHeight + }); + + for (const img of images) gif.addFrame(img, { delay }); + + const blob = await new Promise((resolve) => { + gif.on("finished", resolve); + gif.render(); + }); + + return URL.createObjectURL(blob); +}