Recently I have made a little test. I would have like to make a little active-background effect on my project and I have faced a problem with the hardware resources. What you have to know about this project is, that it will be an information panel on my college where I graduated. So, the hardware, the browser and the resolution (and pretty much everything else) is fixed.
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.