2026-01-28 23:00:58 -05:00

55 lines
1.8 KiB
JavaScript

#!/usr/bin/env node
import puppeteer from 'puppeteer';
import { execSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const outputDir = path.join(__dirname, 'output/stripe-full-frames');
fs.mkdirSync(outputDir, { recursive: true });
async function captureFrames() {
const browser = await puppeteer.launch({
headless: true,
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
args: ['--no-sandbox']
});
const page = await browser.newPage();
await page.setViewport({ width: 1920, height: 1080 });
const filePath = path.resolve(__dirname, 'output/stripe-full-flow.html');
await page.goto(`file://${filePath}`);
// More frames for smoother animation (5 seconds total at 10fps = 50 frames)
const totalFrames = 55;
const frameInterval = 100; // 100ms between frames = 10fps
for (let i = 0; i < totalFrames; i++) {
const frameNum = String(i + 1).padStart(3, '0');
await page.screenshot({
path: path.join(outputDir, `frame-${frameNum}.png`),
type: 'png'
});
console.log(`Captured frame ${frameNum}/${totalFrames}`);
await new Promise(r => setTimeout(r, frameInterval));
}
await browser.close();
// Create GIF
console.log('Creating GIF...');
const gifPath = path.join(__dirname, 'output/stripe-full-flow.gif');
try {
execSync(`ffmpeg -y -framerate 10 -i "${outputDir}/frame-%03d.png" -vf "scale=960:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=256[p];[s1][p]paletteuse=dither=bayer" "${gifPath}"`, { stdio: 'inherit' });
console.log(`GIF created: ${gifPath}`);
} catch (e) {
console.error('FFmpeg error:', e.message);
}
}
captureFrames().catch(console.error);