Last active
November 16, 2021 18:39
-
-
Save abigpotostew/858ed102690f492d5800ea4e61a25900 to your computer and use it in GitHub Desktop.
Gradis to GIF script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Gradis Token to GIF | |
* Install: | |
* * npm i puppeteer gifencoder png-js | |
* Run: | |
* * node index.js 102402010402011602011606 | |
* * node index.js 10360308020202100302110304,10350503030202000202140003,10160116030200020302040506 | |
* tested on node v14.17.6 | |
* For best results close all other apps and do not use your computer while this script loads. | |
* Make sure you have a couple GB of free memory and no other CPU intensive processes running. | |
*/ | |
const fs = require('fs'); | |
const puppeteer = require('puppeteer'); | |
const GIFEncoder = require('gifencoder'); | |
const PNG = require('png-js'); | |
// Configuration: | |
// size can be 400 or 800 | |
const size = 800; | |
const factor = size === 400 ? 1 : 1.5; | |
function decode(png) { | |
return new Promise(r => { | |
png.decode(pixels => r(pixels)) | |
}); | |
} | |
async function gifAddFrame(page, encoder) { | |
let viewportOffset = 0; | |
if (size === 800) { | |
viewportOffset = 130; // center the gradis in the screenshot | |
} | |
const pngBuffer = await page.screenshot({ | |
clip: { | |
width: size / factor, | |
height: size / factor, | |
x: viewportOffset, | |
y: 0, | |
} | |
}); | |
const png = new PNG(pngBuffer); | |
await decode(png).then(pixels => encoder.addFrame(pixels)); | |
} | |
const run = async (tokenId) => { | |
const browser = await puppeteer.launch({ | |
headless: true, slowMo: 0, | |
}); | |
const page = await browser.newPage(); | |
await page.setViewport({ | |
width: size, | |
height: size, | |
deviceScaleFactor: factor | |
}); | |
await page.goto('https://nft.gradis.art/index2.html?tokenid=' + tokenId, { | |
waitUntil: ['domcontentloaded', 'networkidle0'] | |
}); | |
// Pause the animation before it starts | |
const anim = '#toggle-play' | |
const sleep = m => new Promise(r => setTimeout(r, m)); | |
const button = await page.waitForSelector(anim); | |
await sleep(2500) // extra wait for gradis to load. Should be increased on a slow network. | |
// record gif | |
var encoder = new GIFEncoder(size, size); | |
encoder.createWriteStream() | |
.pipe(fs.createWriteStream(tokenId + '.gif')); | |
// setting gif encoder | |
encoder.start(); | |
encoder.setRepeat(0); // loop forever | |
encoder.setDelay(17); // 17 ms per frame for 60 fps | |
encoder.setQuality(10); // default | |
// capture frames at 60fps for 0.5 seconds == 30 frames. | |
const fpsMs = 1 / 60 * 1000; | |
for (let i = 0; i < 30; i++) { | |
await gifAddFrame(page, encoder); | |
await page.evaluate(frameTime => players.forEach((p) => p.getLottie().goToAndStop(frameTime, false)), fpsMs * (i + 1)) | |
} | |
encoder.finish(); | |
await browser.close(); | |
} | |
(async () => { | |
const args = process.argv.slice(2) | |
if (args.length !== 1) { | |
console.log("Usage: node index.js <tokenIds>") | |
process.exit(1) | |
} | |
const tokenIds = args[0].split(',') | |
for (let tokenId of tokenIds) { | |
await run(tokenId.trim()) | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment