This is the DEMO (and a simplified result):
http://jsfiddle.net/FilipFlora/cLByF/10/embedded/result/
The task was:
Create an active-background animation when the tablet is idle. So when you walk by, it'll catch your attention..
The problem:
The hardware is rather energy-efficient and has only a basic graphics-card integrated. The images to move are huge (circa 2000x1600) and they have a 5% opacity on them. (Just as I wrote these lines, I thought that another solution could be to set the opacity value with css and use gifs instead?? But I don't think that this would be better than the solution below)
The attempts to solve the problem: (not in this order, but I was diligent to find the best looking solution :) )
1. attempt: Background-image (for this I used the background-position jQuery plugin)
I tried that..yes. I created 4 layers, I have set the background-image with CSS, and created the animation with jQuery.
HTML:
<div id="index_bg_1"> </div> <div id="index_bg_2"> </div> <div id="index_bg_3"> </div> <div id="index_bg_4"> </div>
CSS:
#index_bg_1, #index_bg_2, #index_bg_3, #index_bg_4 { background-image: url("../images/index-bg-1.png"); background-repeat: no-repeat; background-position: 0px 0px; width: 1680px; height: 1050px; position: absolute; left: 0px; top: 0px; } #index_bg_2 { background-image: url("../images/index-bg-2.png"); background-position: 0px 0px; } #index_bg_3 { background-image: url("../images/index-bg-3.png"); background-position: 0px 0px; } #index_bg_4 { background-image: url("../images/index-bg-4.png"); background-position: 0px 0px; }
Javascript:
jQuery(document).ready(function() { // initiate all background-image animation for( var i = 1; i<5; i++) { animateBackgroundImage("#index_bg_"+i); } }); function animateBackgroundImage(selector) { // new target x coodinate var pos_x = Math.rand(-1200, 1600); // current x coordinate var bg_x = ((jQuery(selector).css("background-position")).replace("px 0px", ""))*1; // animation time var anim_time = Math.abs(pos_x-bg_x)/24*1000; // to do this, you need the backgroundPosition plugin for jQuery jQuery(selector).animate({ backgroundPosition: "("+pos_x+"px 0px)" // to keep it simple, let's animate only the x value }, anim_time, "linear" ); // after the animation is done, create another setTimeout("animateBackgroundImage('"+selector+"')", anim_time); } // this is just a helper function to create php like random number generator Math.rand = function (min, max) { return(Math.round(Math.random() * (max-min)) + min); }
As it turned out, this was too much for the little machine..
2. attempt: with simple images
I don't want to make this post too long so I summarize it briefly. It doesn't went well. It was a little bit faster, but I needed much more.
3. attempt: Javascript Canvas
This has rocked my world again. After I have read Zsolti's article about canvas animations (thank you my dear friend :) ) I was very excited to test it on the real thing (as I was developing on my laptop). Needless to say.. it went perfectly.
Here is the code:
HTML:
<canvas width="1680" height="1050" id="index_canvas"></canvas>
Javascript:
// animation object var indexAnim = { images: [], // here are the image objects positions: [], // the actual positions of the images destPositions: [] // the target coordinates of the image } jQuery(document).ready(function() { // init for( var i = 1; i<=4; i++) { // create a new image to place on canvas var im = new Image(); im.src = 'images/index-bg-'+i+'.png'; indexAnim.images[i-1] = im; // place it randomly on canvas indexAnim.positions[i-1] = Array(Math.rand(-500, 500), Math.rand(-500, 500)); // set it's destination positions indexAnim.destPositions[i-1] = Array(Math.rand(-500, 500), Math.rand( -500, 500)); } // just for a better performance var length = indexAnim.images.length; var canvas = document.getElementById('index_canvas').getContext('2d'); // let the animation begin (... WHA-HA-HAAA) setInterval(function () { // clear the image canvas.clearRect(0,0,1680,1050); // let's redraw all the images for( var i = 0; i<length; i++ ) { // if a new target position is needed (either x or y) if( Math.abs(indexAnim.positions[i][0] - indexAnim.destPositions[i][0]) < i+1 || Math.abs(indexAnim.positions[i][1] - indexAnim.destPositions[i][1]) < i+1 ) { indexAnim.destPositions[i] = Array(Math.rand(0, 1050), Math.rand( -500, 500)); } // set the new position of the image. It's only 1 pixel closer to the destination coordinate (Just like in life...) indexAnim.positions[i][0] = indexAnim.positions[i][0] + (indexAnim.positions[i][0] < indexAnim.destPositions[i][0] ? 1: -1); indexAnim.positions[i][1] = indexAnim.positions[i][1] + (indexAnim.positions[i][1] < indexAnim.destPositions[i][1] ? 1: -1); // draw image on canvas canvas.drawImage(indexAnim.images[i], indexAnim.positions[i][0],indexAnim.positions[i][1]); } }, 41); // 41ms = 1000/24. 24 Frames are needed at least to create a smooth flow.. }); Math.rand = function (min, max) { return(Math.round(Math.random() * (max-min)) + min); }
Maybe the animation needs some fine-tuning, but It's quite good :)
4. possible attempt: Flash
But since I don't do Flash programming, this solution depends on my brother :)
I hope you like my little solution here, and if you have a better idea share it with us.
No comments:
Post a Comment