These palette cycle images are breathtaking: http://www.effectgames.com/demos/canvascycle/?sound=0
I'd like to make some (or all) of these into desktop backgrounds.
I could use an animated gif version, but I have no idea how to get that from the canvas "animation". Is there anything available yet that can do something along these lines (speficially for that link and generally speaking).
If you wish to make the user download the file as it is saved you can do the following: var canvas = document. getElementById("mycanvas"); var image = canvas. toDataURL("image/png").
The HTML5 canvas has the potential to become a staple of the web, enjoying ubiquitous browser and platform support in addition to widespread webpage support, as nearly 90% of websites have ported to HTML5.
The HTML <canvas> element is used to draw graphics, on the fly, via JavaScript. The <canvas> element is only a container for graphics. You must use JavaScript to actually draw the graphics. Canvas has several methods for drawing paths, boxes, circles, text, and adding images.
All you have to do is modify your code to look like this: let canvas = document. createElement('canvas'); let video = document. getElementById('my-video'); let image = ''; video.
I have a solution but it is dependent on you being familiar with the Javascript Console in Firefox (install the Firebug plugin), Chrome or Safari.
In case you're not, google it, or try to just right click anywhere on the page, choose "Inspect Element" and look for "Console"...
What the code does:
It allows you to take 10 screen-grabs of the CANVAS
element every 1/10th of a second. Both these values are easily modified since you can tweak to find the number of iterations you'd like to get. For the example you give, the canvas element ID is 'mycanvas'.
Once it has the screen-grabs it outputs the images into the page. At that point you can save the individual images.
Running the code
Paste in the following code into the Javascript Console:
var canvas = document.getElementById("mycanvas"); var shots = []; var grabLimit = 10; // Number of screenshots to take var grabRate = 100; // Miliseconds. 500 = half a second var count = 0; function showResults() { //console.log(shots); for (var i=0; i<shots.length; i++) { document.write('<img src="' + shots[i] + '"/>\n'); } } var grabber = setInterval(function(){ count++; if (count>grabLimit) { clearInterval(grabber); showResults(); } var img = canvas.toDataURL("image/png"); shots.push(img); }, grabRate);
and press CTRL-Enter to execute it.
It should take a few seconds to run so please be patient.
After that you should have all the necessary frames (any maybe more) to create an animated GIF via ImageMagick, this website MakeAGif.com, or other app.
Side Note
If for some reason you need to output as GIF of JPG instead of PNG just update, as needed, this:
var img = canvas.toDataURL("image/png");
to one of these:
var img = canvas.toDataURL("image/gif"); var img = canvas.toDataURL("image/jpg");
Support for output as gif or jpg may not be in all browsers (should be most).
(BIG) UPDATE #1
First, I'm keeping the code above intact rather than updating it because both approaches could be helpful to others.
Second, this new code DOES NOT SOLVE the problem. It kind-of does but one major drawback. It creates an animated GIF (Yipee!) but its in various shades of green (Boooo!). Not sure how/why, but maybe someone can take it from here and see what I've missed.
So here we go... same rules apply - copy and paste it into the Javascript Console of a browser (it lags in Firefox but Google Chrome its pretty fast... 10 seconds or so to run).
var jsf = ["/Demos/b64.js", "LZWEncoder.js", "NeuQuant.js", "GIFEncoder.js"]; var head = document.getElementsByTagName("head")[0]; for (var i=0;i<jsf.length;i++) { var newJS = document.createElement('script'); newJS.type = 'text/javascript'; newJS.src = 'http://github.com/antimatter15/jsgif/raw/master/' + jsf[i]; head.appendChild(newJS); } // 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 = 10; // 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);
It uses some helpful code, pointers and JS files referenced in this blog post JavaScript to (Animated) GIF. I use some JS files directly but you should copy these locally if you're going to use it a lot.
The output for me was this GIF:
So its something, but not what you need...
EDIT: Finally put that code to use, here's the result:
Imagick generated a large image, so I went ahead and optimized with gimp.
The client-side code is a modified version of Michael's code:
var canvas = document.getElementById("mycanvas"); var shots = []; var grabLimit = 30; // Number of screenshots to take var grabRate = 100; // Miliseconds. 500 = half a second var count = 0; function postResults() { console.log("START---------"); for (var i = 0; i < shots.length; i++) { document.write(shots[i]+"<br />"); } console.log("END-----------"); } var grabber = setInterval(function(){ count++; if (count>grabLimit) { clearInterval(grabber); postResults(); } var img = canvas.toDataURL("image/png"); shots.push(img.replace("data:image/png;base64,","")); }, grabRate);
It will write a bunch of base64 strings to the screen. Copy them and save them into a text file and then upload it to your web server. Then run the other script (see below) and it will write the image to your web server. The resulting image will be large and possibly choppy, so open up GIMP and optimize for difference and GIF. When saving, force it to use the same delay for all frames so the animation is smooth.
May not be too hard using PHP.
Since michael already posted a nice JS solution, I'll add the server side code if you wish to automate it:
<?php $imageData = array_map('rtrim', file('data.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)); //base 64 strings separated by newlines $delay = 100; $filename = 'coolmoviebro.gif'; $gif = new Imagick(); for($i = 0; $i < count($imageData); $i++) { $tempImg = new Imagick(); $tempImg->readimageblob(base64_decode($imageData[$i])); $gif->addImage($tempImg); } $gif->setFormat('gif'); $gif->setImageDelay($delay); $gif->writeImages($filename, true); ?>
I haven't written much PHP for a year or two so be sure to double check everything and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With