1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 </head> 6 <body style=" background-color: #000;"> 7 <canvas id="canvas"></canvas> 8 9 <script> 10 window.requestAnimFrame = ( function() { 11 return window.requestAnimationFrame || 12 window.webkitRequestAnimationFrame || 13 window.mozRequestAnimationFrame || 14 function( callback ) { 15 window.setTimeout( callback, 1000 / 60 ); 16 }; 17 })(); 18 var canvas = document.getElementById( ‘canvas‘ ), 19 ctx = canvas.getContext( ‘2d‘ ), 20 cw = window.innerWidth, 21 ch = window.innerHeight, 22 fireworks = [], 23 particles = [], 24 hue = 120, 25 limiterTotal = 5, 26 limiterTick = 0, 27 timerTotal = 80, 28 timerTick = 0, 29 mousedown = false, 30 mx, 31 my; 32 33 canvas.width = cw; 34 canvas.height = ch; 35 36 function random( min, max ) { 37 return Math.random() * ( max - min ) + min; 38 } 39 40 function calculateDistance( p1x, p1y, p2x, p2y ) { 41 var xDistance = p1x - p2x, 42 yDistance = p1y - p2y; 43 return Math.sqrt( Math.pow( xDistance, 2 ) + Math.pow( yDistance, 2 ) ); 44 } 45 46 function Firework( sx, sy, tx, ty ) { 47 48 this.x = sx; 49 this.y = sy; 50 51 this.sx = sx; 52 this.sy = sy; 53 54 this.tx = tx; 55 this.ty = ty; 56 57 this.distanceToTarget = calculateDistance( sx, sy, tx, ty ); 58 this.distanceTraveled = 0; 59 60 this.coordinates = []; 61 this.coordinateCount = 3; 62 63 while( this.coordinateCount-- ) { 64 this.coordinates.push( [ this.x, this.y ] ); 65 } 66 this.angle = Math.atan2( ty - sy, tx - sx ); 67 this.speed = 2; 68 this.acceleration = 1.05; 69 this.brightness = random( 50, 70 ); 70 71 this.targetRadius = 1; 72 } 73 74 75 Firework.prototype.update = function( index ) { 76 77 this.coordinates.pop(); 78 79 this.coordinates.unshift( [ this.x, this.y ] ); 80 81 if( this.targetRadius < 8 ) { 82 this.targetRadius += 0.3; 83 } else { 84 this.targetRadius = 1; 85 } 86 87 this.speed *= this.acceleration; 88 89 var vx = Math.cos( this.angle ) * this.speed, 90 vy = Math.sin( this.angle ) * this.speed; 91 92 this.distanceTraveled = calculateDistance( this.sx, this.sy, this.x + vx, this.y + vy ); 93 94 if( this.distanceTraveled >= this.distanceToTarget ) { 95 createParticles( this.tx, this.ty ); 96 fireworks.splice( index, 1 ); 97 } else { 98 this.x += vx; 99 this.y += vy; 100 } 101 } 102 103 Firework.prototype.draw = function() { 104 ctx.beginPath(); 105 ctx.moveTo( this.coordinates[ this.coordinates.length - 1][ 0 ], this.coordinates[ this.coordinates.length - 1][ 1 ] ); 106 ctx.lineTo( this.x, this.y ); 107 ctx.strokeStyle = ‘hsl(‘ + hue + ‘, 100%, ‘ + this.brightness + ‘%)‘; 108 ctx.stroke(); 109 110 ctx.beginPath(); 111 ctx.arc( this.tx, this.ty, this.targetRadius, 0, Math.PI * 2 ); 112 ctx.stroke(); 113 } 114 115 function Particle( x, y ) { 116 this.x = x; 117 this.y = y; 118 119 this.coordinates = []; 120 this.coordinateCount = 5; 121 while( this.coordinateCount-- ) { 122 this.coordinates.push( [ this.x, this.y ] ); 123 } 124 125 this.angle = random( 0, Math.PI * 2 ); 126 this.speed = random( 1, 10 ); 127 128 this.friction = 0.95; 129 this.gravity = 1; 130 131 this.hue = random( hue - 20, hue + 20 ); 132 this.brightness = random( 50, 80 ); 133 this.alpha = 1; 134 this.decay = random( 0.015, 0.03 ); 135 //this.decay = 0; 136 } 137 138 Particle.prototype.update = function( index ) { 139 140 this.coordinates.pop(); 141 this.coordinates.unshift( [ this.x, this.y ] ); 142 this.speed *= this.friction; 143 this.x += Math.cos( this.angle ) * this.speed; 144 this.y += Math.sin( this.angle ) * this.speed + this.gravity; 145 this.alpha -= this.decay; 146 147 if( this.alpha <= this.decay ) { 148 particles.splice( index, 1 ); 149 } 150 } 151 152 Particle.prototype.draw = function() { 153 ctx. beginPath(); 154 ctx.moveTo( this.coordinates[ this.coordinates.length - 1 ][ 0 ], this.coordinates[ this.coordinates.length - 1 ][ 1 ] ); 155 ctx.lineTo( this.x, this.y ); 156 ctx.strokeStyle = ‘hsla(‘ + this.hue + ‘, 100%, ‘ + this.brightness + ‘%, ‘ + this.alpha + ‘)‘; 157 ctx.stroke(); 158 } 159 160 function createParticles( x, y ) { 161 var particleCount = 30; 162 while( particleCount-- ) { 163 particles.push( new Particle( x, y ) ); 164 } 165 } 166 167 168 function loop() { 169 requestAnimFrame( loop ); 170 171 hue += 0.5; 172 173 ctx.globalCompositeOperation = ‘destination-out‘; 174 ctx.fillStyle = ‘rgba(0, 0, 0, 0.5)‘; 175 ctx.fillRect( 0, 0, cw, ch ); 176 ctx.globalCompositeOperation = ‘lighter‘; 177 178 var i = fireworks.length; 179 while( i-- ) { 180 fireworks[ i ].draw(); 181 fireworks[ i ].update( i ); 182 } 183 184 var i = particles.length; 185 while( i-- ) { 186 particles[ i ].draw(); 187 particles[ i ].update( i ); 188 } 189 190 if( timerTick >= timerTotal ) { 191 if( !mousedown ) { 192 fireworks.push( new Firework( cw / 2, ch, random( 0, cw ), random( 0, ch / 2 ) ) ); 193 timerTick = 0; 194 } 195 } else { 196 timerTick++; 197 } 198 199 if( limiterTick >= limiterTotal ) { 200 if( mousedown ) { 201 fireworks.push( new Firework( cw / 2, ch, mx, my ) ); 202 limiterTick = 0; 203 } 204 } else { 205 limiterTick++; 206 } 207 } 208 209 canvas.addEventListener( ‘mousemove‘, function( e ) { 210 mx = e.pageX - canvas.offsetLeft; 211 my = e.pageY - canvas.offsetTop; 212 }); 213 214 canvas.addEventListener( ‘mousedown‘, function( e ) { 215 e.preventDefault(); 216 mousedown = true; 217 }); 218 219 canvas.addEventListener( ‘mouseup‘, function( e ) { 220 e.preventDefault(); 221 mousedown = false; 222 }); 223 224 window.onload = loop; 225 </script> 226 </body> 227 </html>
时间: 2024-11-05 22:35:42