I created drifting animation for my friend’s website the other day.
GOAL
To create animation of drifting items.
Source Code
<style type="text/css">
#canvas-area {
width: 100%;
height: 100%;
position: relative;
}
#canvas-container{
width: 1000px;
height: 500px;
}
</style>
<div id="canvas-area">
<canvas id="canvas-container"></canvas>
</div>
<script type="text/javascript">
//set canvas
var canvasArea = document.querySelector('#canvas-area');
var canvas = document.querySelector('#canvas-container');
var ctx = canvas.getContext('2d');
var canvas_width = canvas.width;
var canvas_height = canvas.height;
var last_time;
//settings
var item_num = 20;
var img_src_array = ['img1.png', 'img2.png', 'img3.png', 'img4.png', 'img5.png'];
var first_start_x = canvas_width - 100;
var first_start_y = canvas_height - 100;
//Item Object
var Item = function(input_img){
img_width = input_img.width;
img_height = input_img.height;
this.alpha = 1.0;
this.img = input_img;
this.start_x = first_start_x;
this.start_y = first_start_y;
this.x = this.start_x ;
this.y = this.start_y;
this.rotate = Math.random()*Math.PI*2;
console.log(img.src)
this.speed=[parseInt((Math.random())*10), parseInt(Math.random()+2)];
};
Item.prototype.update = function(){
this.x -= this.speed[0];
this.y -= this.speed[1];
this.alpha *= 0.9;
if(this.alpha < 0.1 ){
this.alpha = 0;
}
if(this.x+this.img.width < 0 || this.x > canvas_width || this.y + this.img.height < 0){
this.speed=[parseInt((Math.random())*10), parseInt(Math.random()+2)];
console.log(`${this.start_x}:${this.start_y}`)
this.x = this.start_x;
this.y = this.start_y;
this.rotate = Math.random()*Math.PI*2;
this.alpha =1.0;
}
};
Item.prototype.display = function(){
ctx.globalAlpha = this.alpha;
ctx.translate(this.x + img_width/2, this.y+ img_height/2);
ctx.rotate(this.rotate);
ctx.drawImage(this.img, -img_width/2, -img_height/2, img_width/2, img_height/2);
ctx.rotate(-this.rotate);
ctx.translate(-this.x - img_width/2, -this.y - img_height/2);
};
//create item array
var items = [];
var item_add = function(img){
img.width = 100;
img.height = 100;
items.push(new Item(img));
initialize();
};
for(var i=0; i<item_num; i++){
img = new Image();
img.src = img_src_array[parseInt(Math.random()*img_src_array.length)];
img.onload = item_add(img);
}
function initialize(){
if(items.length == item_num){
last_time = new Date().getTime();
animation();
}
}
//animation
function animation(){
//callback
window.requestAnimationFrame(animation);
now_time = new Date().getTime();
//clear window
if((now_time - last_time) > 100){
last_time = now_time
ctx.clearRect(0, 0, canvas_width, canvas_height);
for(var i=0; i<item_num; i++){
items[i].display();
items[i].update();
}
}
}
</script>
Item Object
Item Object has local variables.
alpha | alpha channel value of this Item |
img | HTMLImageElement of this Item |
start_x, start_y | the position where this Item appears |
x, y | the position where this Item exists |
rotate | the rotation angle of this Item |
speed | the moving speed of this Item |
//Item Object
var Item = function(input_img){
img_width = input_img.width;
img_height = input_img.height;
this.alpha = 1.0;
this.img = input_img;
this.start_x = first_start_x;
this.start_y = first_start_y;
this.x = this.start_x ;
this.y = this.start_y;
this.rotate = Math.random()*Math.PI*2;
this.speed=[parseInt((Math.random())*10), parseInt(Math.random()+2)];
};
Item Object has 2 functions.
update() | update position and alpha channel |
display() | Rotation and movement by coordinate transformation translate->rotate->draw->rotate(reverse)->translate(reverse) |
Item.prototype.update = function(){
this.x -= this.speed[0];
this.y -= this.speed[1];
this.alpha *= 0.9;
if(this.alpha < 0.1 ){
this.alpha = 0;
}
if(this.x + this.img.width < 0 || this.x > canvas_width || this.y + this.img.height < 0){
this.speed=[parseInt((Math.random())*10), parseInt(Math.random()+2)];
console.log(`${this.start_x}:${this.start_y}`)
this.x = this.start_x;
this.y = this.start_y;
this.rotate = Math.random()*Math.PI*2;
this.alpha =1.0;
}
};
Item.prototype.display = function(){
ctx.globalAlpha = this.alpha;
ctx.translate(this.x + img_width/2, this.y+ img_height/2);
ctx.rotate(this.rotate);
ctx.drawImage(this.img, -img_width/2, -img_height/2, img_width/2, img_height/2);
ctx.rotate(-this.rotate);
ctx.translate(-this.x - img_width/2, -this.y - img_height/2);
};
Create Item instances
Each image is assigned to the Item object randomly.
for(var i=0; i<item_num; i++){
img = new Image();
img.src = img_src_array[parseInt(Math.random()*img_src_array.length)];
img.onload = item_add(img);
}
Animation function
Update() and display() each Items at regular intervals.
//animation
function animation(){
//callback
window.requestAnimationFrame(animation);
now_time = new Date().getTime();
//clear window
if((now_time - last_time) > 100){
last_time = now_time
ctx.clearRect(0, 0, canvas_width, canvas_height);
for(var i=0; i<item_num; i++){
items[i].display();
items[i].update();
}
}
}