[JavaScript] Drifting Effect
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(); } } }