window . requestAnimFrame = ( function ( ) {
return window . requestAnimationFrame ||
window . webkitRequestAnimationFrame ||
window . mozRequestAnimationFrame ||
function ( callback ) {
window . setTimeout ( callback , 1000 / 60 ) ;
} ;
} ) ( ) ;
var canvas = null ,
ctx = null ,
cw = window . innerWidth ,
ch = window . innerHeight ,
fireworksLimit = 15 ,
fireworksShown = 0 ,
fireworks = [ ] ,
particles = [ ] ,
hue = 180 ,
timerTotal = 10 ,
timerTick = 0 ,
animationEnd = true ;
function random ( min , max ) {
return Math . random ( ) * ( max - min ) + min ;
}
/* To sprawdzic... */
function calculateDistance ( p1x , p1y , p2x , p2y ) {
var xDistance = p1x - p2x ,
yDistance = p1y - p2y ;
return Math . sqrt ( Math . pow ( xDistance , 2 ) + Math . pow ( yDistance , 2 ) ) ;
}
function Firework ( sx , sy , tx , ty ) {
this . x = sx ;
this . y = sy ;
this . sx = sx ;
this . sy = sy ;
this . tx = tx ;
this . ty = ty ;
this . distanceToTarget = calculateDistance ( sx , sy , tx , ty ) ;
this . distanceTraveled = 0 ;
this . coordinates = [ ] ;
this . coordinateCount = 3 ;
while ( this . coordinateCount -- ) {
this . coordinates . push ( [ this . x , this . y ] ) ;
}
this . angle = Math . atan2 ( ty - sy , tx - sx ) ;
this . speed = 2 ;
this . acceleration = 1.05 ;
this . brightness = random ( 50 , 70 ) ;
this . targetRadius = 1 ;
}
Firework . prototype . update = function ( index ) {
this . coordinates . pop ( ) ;
this . coordinates . unshift ( [ this . x , this . y ] ) ;
if ( this . targetRadius < 8 ) {
this . targetRadius += 0.3 ;
} else {
this . targetRadius = 1 ;
}
// speed up the firework
this . speed *= this . acceleration ;
// get the current velocities based on angle and speed
var vx = Math . cos ( this . angle ) * this . speed ,
vy = Math . sin ( this . angle ) * this . speed ;
// how far will the firework have traveled with velocities applied?
this . distanceTraveled = calculateDistance ( this . sx , this . sy , this . x + vx , this . y + vy ) ;
if ( this . distanceTraveled >= this . distanceToTarget ) {
createParticles ( this . tx , this . ty ) ;
// remove the firework, use the index passed into the update function to determine which to remove
fireworks . splice ( index , 1 ) ;
} else {
// target not reached, keep traveling
this . x += vx ;
this . y += vy ;
}
}
// draw firework
Firework . prototype . draw = function ( ) {
ctx . beginPath ( ) ;
// move to the last tracked coordinate in the set, then draw a line to the current x and y
ctx . moveTo ( this . coordinates [ this . coordinates . length - 1 ] [ 0 ] , this . coordinates [ this . coordinates . length - 1 ] [ 1 ] ) ;
ctx . lineTo ( this . x , this . y ) ;
ctx . strokeStyle = 'hsl(' + hue + ', 100%, ' + this . brightness + '%)' ;
ctx . stroke ( ) ;
}
function Particle ( x , y ) {
this . x = x ;
this . y = y ;
// track the past coordinates of each particle to create a trail effect, increase the coordinate count to create more prominent trails
this . coordinates = [ ] ;
this . coordinateCount = 5 ;
while ( this . coordinateCount -- ) {
this . coordinates . push ( [ this . x , this . y ] ) ;
}
// set a random angle in all possible directions, in radians
this . angle = random ( 0 , Math . PI * 2 ) ;
this . speed = random ( 1 , 10 ) ;
// friction will slow the particle down
this . friction = 0.98 ;
// gravity will be applied and pull the particle down
this . gravity = 1 ;
// set the hue to a random number +-50 of the overall hue variable
this . hue = random ( hue - 50 , hue + 50 ) ;
this . brightness = random ( 50 , 80 ) ;
this . alpha = 1 ;
// set how fast the particle fades out
this . decay = random ( 0.015 , 0.03 ) ;
}
// update particle
Particle . prototype . update = function ( index ) {
// remove last item in coordinates array
this . coordinates . pop ( ) ;
// add current coordinates to the start of the array
this . coordinates . unshift ( [ this . x , this . y ] ) ;
// slow down the particle
this . speed *= this . friction ;
// apply velocity
this . x += Math . cos ( this . angle ) * this . speed ;
this . y += Math . sin ( this . angle ) * this . speed + this . gravity ;
// fade out the particle
this . alpha -= this . decay ;
// remove the particle once the alpha is low enough, based on the passed in index
if ( this . alpha <= this . decay ) {
particles . splice ( index , 1 ) ;
}
if ( particles . length === 0 ) {
if ( fireworksShown === fireworksLimit ) {
animationEnd = true ;
}
}
}
// draw particle
Particle . prototype . draw = function ( ) {
ctx . beginPath ( ) ;
// move to the last tracked coordinates in the set, then draw a line to the current x and y
ctx . moveTo ( this . coordinates [ this . coordinates . length - 1 ] [ 0 ] , this . coordinates [ this . coordinates . length - 1 ] [ 1 ] ) ;
ctx . lineTo ( this . x , this . y ) ;
ctx . strokeStyle = 'hsla(' + this . hue + ', 100%, ' + this . brightness + '%, ' + this . alpha + ')' ;
ctx . stroke ( ) ;
}
// create particle group/explosion
function createParticles ( x , y ) {
// increase the particle count for a bigger explosion, beware of the canvas performance hit with the increased particles though
var particleCount = 500 ;
while ( particleCount -- ) {
particles . push ( new Particle ( x , y ) ) ;
}
}
function loop ( ) {
if ( animationEnd === true ) {
animationFinish ( ) ;
return true ;
}
requestAnimationFrame ( loop ) ;
hue = random ( 0 , 360 ) ;
ctx . globalCompositeOperation = 'destination-out' ;
ctx . fillStyle = 'rgba(0, 0, 0, 0.5)' ;
ctx . fillRect ( 0 , 0 , cw , ch ) ;
ctx . globalCompositeOperation = 'lighter' ;
var i = fireworks . length ;
while ( i -- ) {
fireworks [ i ] . draw ( ) ;
fireworks [ i ] . update ( i ) ;
}
var i = particles . length ;
while ( i -- ) {
particles [ i ] . draw ( ) ;
particles [ i ] . update ( i ) ;
}
if ( timerTick >= timerTotal ) {
// start the firework at the bottom middle of the screen, then set the random target coordinates, the random y coordinates will be set within the range of the top half of the screen
if ( fireworksShown < fireworksLimit ) {
fireworks . push ( new Firework ( cw / 2 , ch , random ( 0 , cw ) , random ( 0 , ch / 2 ) ) ) ;
fireworksShown ++ ;
timerTick = 0 ;
}
} else {
timerTick ++ ;
}
}
//window.onload = loop;
window . fireworks . start = function ( ) {
/* Prevent multiple animations */
if ( animationEnd === false ) {
return false ;
}
fireworksShown = 0 ;
animationEnd = false ;
canvas = document . createElement ( 'canvas' ) ;
document . body . appendChild ( canvas ) ;
ctx = canvas . getContext ( '2d' ) ;
canvas . style . zIndex = 100 ;
canvas . style . top = 0 ;
canvas . style . left = 0 ;
canvas . style . position = 'fixed' ;
canvas . width = cw ;
canvas . height = ch ;
//canvas.style.background = "rgba(0,0,0,0.7)";
loop ( ) ;
//setTimeout(function(){animationEnd = true;}, 4500);
}
animationFinish = function ( ) {
document . body . removeChild ( canvas ) ;
} ;