Saving HTML canvas animation from browser console - lmmx/devnotes GitHub Wiki
...but otherwise only a slightly modified version of this wonderful answer to a StackOverflow question on how to reproduce a HTML canvas locally using javascript.
Below gisted here is the same code, with actual JS in place of cross-site calls to raw.github...
links, which Google Chrome is blocking. Anyone else using this should probably verify their contents (see original question) rather than take my word though! :-) For my own reference.
Click here to jump down to code for saving the images
var jsf = ["/Demos/b64.js", "LZWEncoder.js", "NeuQuant.js", "GIFEncoder.js"];
/*
Edit: I've removed the cross-origin call to get github files, and entered here.
You may want to verify their contents!
*/
// JSF JAVASCRIPT BEGINS HERE
// truncated for readability: see https://gist.github.com/lmmx/04a87c473df61d2f3696
// JSF JAVASCRIPT ENDS HERE
// This post was very helpful!
// http://antimatter15.com/wp/2010/07/javascript-to-animated-gif/
var w = setTimeout(function() { // give external JS 1 second of time to load
console.log('Starting');
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext('2d');
var shots = [];
var grabLimit = 100; // Number of screenshots to take
var grabRate = 100; // Miliseconds. 500 = half a second
var count = 0;
function showResults() {
console.log('Finishing');
encoder.finish();
var binary_gif = encoder.stream().getData();
var data_url = 'data:image/gif;base64,'+encode64(binary_gif);
document.write('<img src="' +data_url + '"/>\n');
}
var encoder = new GIFEncoder();
encoder.setRepeat(0); //0 -> loop forever, 1+ -> loop n times then stop
encoder.setDelay(500); //go to next frame every n milliseconds
encoder.start();
var grabber = setInterval(function(){
console.log('Grabbing '+count);
count++;
if (count>grabLimit) {
clearInterval(grabber);
showResults();
}
var imdata = context.getImageData(0,0,canvas.width,canvas.height);
encoder.addFrame(context);
}, grabRate);
}, 1000);
- Use
Ctrl
+C
in Chrome to select the elements (find the first in the sequence, remove all others, same for the end to give a full sequence)
Run a loop over these elements, open them in new tabs with OpenList and save with (my extension!) TabSave 😃
Actually there's no need to open the images in tabs, just go straight to saving by clicking the pencil icon in TabSave
// process the resultant images by pasting into OneList, then let TabSave do the downloading
imgs = document.querySelectorAll('img');
imglinks = [];
for (i=0;i<imgs.length;i++) {
imglinks.push(imgs[i].src);
}
If you've got ∞ RAM and/or just a few frames, just copy(imglinks.join('\n'))
, else slice the array into manageable windows (opening too many tabs in a window can make Chrome croak)
imglinks1 = imglinks.slice(0,20);
imglinks2 = imglinks.slice(21,40);
imglinks3 = imglinks.slice(41,60);
imglinks4 = imglinks.slice(61,80);
imglinks5 = imglinks.slice(81,100);
imglinks6 = imglinks.slice(101,imglinks.length);
copy(imglinks1.join('\n'));
// etc.
Paste into OpenList TabSave (OpenList actually Googles the data-uri...) to have all images download (on my computer the default filename for these data-uri images is download
).
GIMP: Ctrl
+ Alt
+ O
to add on top of an original layer 👍
Example animation generated this way, from this canvas