Skip to content

Instantly share code, notes, and snippets.

@btn0s
Created January 22, 2026 03:55
Show Gist options
  • Select an option

  • Save btn0s/5344917d4164eada7ff67846c60ca2ad to your computer and use it in GitHub Desktop.

Select an option

Save btn0s/5344917d4164eada7ff67846c60ca2ad to your computer and use it in GitHub Desktop.
(async function() {
const sm = window.__VARIABLE_MANAGER?.sceneManager;
const vp = sm?.scenegraph?.viewportNode;
if (!vp?.children?.length) {
console.error("No frames found");
return;
}
const getName = (node) => node?.properties?.name || node?.id;
const frames = vp.children.map((node, i) => ({
node,
name: getName(node),
id: node.id
}));
console.log(`Found ${frames.length} frames:`);
frames.forEach((f, i) => console.log(` ${i}: "${f.name}"`));
async function exportFrame(frame, dpi, maxResolution) {
const renderer = sm.skiaRenderer;
console.log(`Exporting "${frame.name}" at ${dpi}x...`);
try {
return await renderer.exportToPNG([frame.node], { dpi, maxResolution });
} catch (e) {
console.error(`Failed: ${e.message}`);
return null;
}
}
function download(data, filename) {
const blob = new Blob([data], { type: 'image/png' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
console.log(`Saved: ${filename}`);
}
window.exportAllFrames = async function(dpi = 2, maxRes = 4096) {
for (let i = 0; i < frames.length; i++) {
const f = frames[i];
const safeName = f.name.replace(/[^a-z0-9]/gi, '_').toLowerCase();
const filename = `roy_${String(i + 1).padStart(2, '0')}_${safeName}.png`;
const data = await exportFrame(f, dpi, maxRes);
if (data) {
download(data, filename);
await new Promise(r => setTimeout(r, 300));
}
}
console.log("Done!");
};
window.exportFrame = async function(index, dpi = 2, maxRes = 4096) {
const f = frames[index];
if (!f) { console.error(`Invalid index 0-${frames.length-1}`); return; }
const safeName = f.name.replace(/[^a-z0-9]/gi, '_').toLowerCase();
const filename = `roy_${String(index + 1).padStart(2, '0')}_${safeName}.png`;
const data = await exportFrame(f, dpi, maxRes);
if (data) download(data, filename);
};
window.listFrames = () => frames.forEach((f, i) => console.log(`${i}: ${f.name}`));
console.log("\nCommands:");
console.log(" listFrames() - List all frames");
console.log(" exportFrame(0) - Export single frame at 2x");
console.log(" exportFrame(0, 3) - Export at 3x DPI");
console.log(" exportAllFrames() - Export all at 2x");
console.log(" exportAllFrames(3) - Export all at 3x");
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment