//https://www.cnblogs.com/fpcbk/var timer =setInterval(function(){$(".box > div").animate({'marginLeft':1000,},{queue:true, duration:5000,complete:functiona(){$(".box > div").css('transform','rotateY(180deg)');}}).animate({'marginLeft':50,},5000,function(){$(".box > div").css('transform','rotateY(0deg)');});},1000);// when animating on canvas, it is best to use requestAnimationFrame instead of setTimeout or setInterval// not supported in all browsers though and sometimes needs a prefix, so we need a shim
window.requestAnimFrame =(function(){return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||function( callback ){
window.setTimeout( callback,1000/60);};})();// now we will setup our basic variables for the demovar canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),// full screen dimensions
cw = window.innerWidth,
ch = window.innerHeight,// firework collection
fireworks =[],// particle collection
particles =[],// starting hue
hue =120,// when launching fireworks with a click, too many get launched at once without a limiter, one launch per 5 loop ticks
limiterTotal =5,
limiterTick =0,// this will time the auto launches of fireworks, one launch per 80 loop ticks
timerTotal =80,
timerTick =0,
mousedown =false,// mouse x coordinate,
mx,// mouse y coordinate
my;// set canvas dimensions
canvas.width = cw;
canvas.height = ch;// now we are going to setup our function placeholders for the entire demo// get a random number within a rangefunctionrandom( min, max ){return Math.random()*( max - min )+ min;}// calculate the distance between two pointsfunctioncalculateDistance( p1x, p1y, p2x, p2y ){var xDistance = p1x - p2x,yDistance = p1y - p2y;return Math.sqrt( Math.pow( xDistance,2)+ Math.pow( yDistance,2));}// create fireworkfunctionFirework( sx, sy, tx, ty ){// actual coordinatesthis.x = sx;this.y = sy;// starting coordinatesthis.sx = sx;this.sy = sy;// target coordinatesthis.tx = tx;this.ty = ty;// distance from starting point to targetthis.distanceToTarget =calculateDistance( sx, sy, tx, ty );this.distanceTraveled =0;// track the past coordinates of each firework to create a trail effect, increase the coordinate count to create more prominent trailsthis.coordinates =[];this.coordinateCount =3;// populate initial coordinate collection with the current coordinateswhile(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);// circle target indicator radiusthis.targetRadius =1;}// update firework
Firework.prototype.update=function( index ){// remove last item in coordinates arraythis.coordinates.pop();// add current coordinates to the start of the arraythis.coordinates.unshift([this.x,this.y ]);// cycle the circle target indicator radiusif(this.targetRadius <8){this.targetRadius +=0.3;}else{this.targetRadius =1;}// speed up the fireworkthis.speed *=this.acceleration;// get the current velocities based on angle and speedvar 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 the distance traveled, including velocities, is greater than the initial distance to the target, then the target has been reachedif(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 travelingthis.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();
ctx.beginPath();// draw the target for this firework with a pulsing circle
ctx.arc(this.tx,this.ty,this.targetRadius,0, Math.PI*2);
ctx.stroke();}// create particlefunctionParticle( 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 trailsthis.coordinates =[];this.coordinateCount =5;while(this.coordinateCount--){this.coordinates.push([this.x,this.y ]);}// set a random angle in all possible directions, in radiansthis.angle =random(0, Math.PI*2);this.speed =random(1,10);// friction will slow the particle downthis.friction =0.95;// gravity will be applied and pull the particle downthis.gravity =1;// set the hue to a random number +-20 of the overall hue variablethis.hue =random( hue -20, hue +20);this.brightness =random(50,80);this.alpha =1;// set how fast the particle fades outthis.decay =random(0.015,0.03);}// update particle
Particle.prototype.update=function( index ){// remove last item in coordinates arraythis.coordinates.pop();// add current coordinates to the start of the arraythis.coordinates.unshift([this.x,this.y ]);// slow down the particlethis.speed *=this.friction;// apply velocitythis.x += Math.cos(this.angle )*this.speed;this.y += Math.sin(this.angle )*this.speed +this.gravity;// fade out the particlethis.alpha -=this.decay;// remove the particle once the alpha is low enough, based on the passed in indexif(this.alpha <=this.decay ){
particles.splice( index,1);}}// 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/explosionfunctioncreateParticles( x, y ){// increase the particle count for a bigger explosion, beware of the canvas performance hit with the increased particles thoughvar particleCount =30;while( particleCount--){
particles.push(newParticle( x, y ));}}// main demo loopfunctionloop(){// this function will run endlessly with requestAnimationFramerequestAnimFrame( loop );// increase the hue to get different colored fireworks over time
hue +=0.5;// normally, clearRect() would be used to clear the canvas// we want to create a trailing effect though// setting the composite operation to destination-out will allow us to clear the canvas at a specific opacity, rather than wiping it entirely
ctx.globalCompositeOperation ='destination-out';// decrease the alpha property to create more prominent trails
ctx.fillStyle ='rgba(0, 0, 0, 0.5)';
ctx.fillRect(0,0, cw, ch );// change the composite operation back to our main mode// lighter creates bright highlight points as the fireworks and particles overlap each other
ctx.globalCompositeOperation ='lighter';// loop over each firework, draw it, update itvar i = fireworks.length;while( i--){
fireworks[ i ].draw();
fireworks[ i ].update( i );}// loop over each particle, draw it, update itvar i = particles.length;while( i--){
particles[ i ].draw();
particles[ i ].update( i );}// launch fireworks automatically to random coordinates, when the mouse isn't downif( timerTick >= timerTotal ){if(!mousedown ){// 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
fireworks.push(newFirework( cw /2, ch,random(0, cw ),random(0, ch /2)));
timerTick =0;}}else{
timerTick++;}// limit the rate at which fireworks get launched when mouse is downif( limiterTick >= limiterTotal ){if( mousedown ){// start the firework at the bottom middle of the screen, then set the current mouse coordinates as the target
fireworks.push(newFirework( cw /2, ch, mx, my ));
limiterTick =0;}}else{
limiterTick++;}}// mouse event bindings// update the mouse coordinates on mousemove
canvas.addEventListener('mousemove',function( e ){
mx = e.pageX - canvas.offsetLeft;
my = e.pageY - canvas.offsetTop;});// toggle mousedown state and prevent canvas from being selected
canvas.addEventListener('mousedown',function( e ){
e.preventDefault();
mousedown =true;});
canvas.addEventListener('mouseup',function( e ){
e.preventDefault();
mousedown =false;});// once the window loads, we are ready for some fireworks!
window.onload = loop;