H5页面自动烟花特效
代码如下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <!-- 引用本地jquery文件 --> 7 <!-- <script src="../js/jquery-1.9.1.min.js"></script> --> 8 <!-- 引用百度jquery文件 --> 9 <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script> 10 <style type="text/css"> 11 .divBody { 12 position: absolute; 13 top: 0; 14 left: 0; 15 width: 100%; 16 height: 100%; 17 background-color: #000000; 18 font-family: "黑体"; 19 color: #292929; 20 } 21 22 canvas { 23 cursor: crosshair; 24 display: block; 25 left: 0; 26 position: absolute; 27 top: 0; 28 z-index: 20; 29 } 30 </style> 31 </head> 32 <body> 33 <div class="divBody"></div> 34 <canvas width="100%" height="100%"></canvas> 35 </body> 36 </html> 37 <script> 38 var Fireworks; 39 $(function() { 40 Fireworks = function() { 41 var self = this; 42 var rand = function(rMi, rMa) { 43 return ~~((Math.random() * (rMa - rMi + 1)) + rMi); 44 } 45 var hitTest = function(x1, y1, w1, h1, x2, y2, w2, h2) { 46 return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1); 47 }; 48 window.requestAnimFrame = function() { 49 return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || 50 window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(a) { 51 window.setTimeout(a, 1E3 / 60) 52 } 53 }(); 54 55 self.init = function() { 56 self.canvas = document.createElement('canvas'); 57 self.canvas.width = self.cw = $(window).innerWidth(); 58 self.canvas.height = self.ch = $(window).innerHeight(); 59 self.particles = []; 60 self.partCount = 150; 61 self.fireworks = []; 62 self.mx = self.cw / 2; 63 self.my = self.ch / 2; 64 self.currentHue = 30; 65 self.partSpeed = 5; 66 self.partSpeedVariance = 10; 67 self.partWind = 50; 68 self.partFriction = 5; 69 self.partGravity = 1; 70 self.hueMin = 0; 71 self.hueMax = 10; //单次最多释放个数 72 self.fworkSpeed = 4; 73 self.fworkAccel = 10; 74 self.hueVariance = 30; 75 self.flickerDensity = 25; 76 self.showShockwave = true; 77 self.showTarget = false; 78 self.clearAlpha = 25; 79 80 $(document.body).append(self.canvas); 81 self.ctx = self.canvas.getContext('2d'); 82 self.ctx.lineCap = 'round'; 83 self.ctx.lineJoin = 'round'; 84 self.lineWidth = 1; 85 self.bindEvents(); 86 self.canvasLoop(); 87 88 self.canvas.onselectstart = function() { 89 return false; 90 }; 91 }; 92 93 self.createParticles = function(x, y, hue) { 94 var countdown = self.partCount; 95 while (countdown--) { 96 var newParticle = { 97 x: x, 98 y: y, 99 coordLast: [{ 100 x: x, 101 y: y 102 }, 103 { 104 x: x, 105 y: y 106 }, 107 { 108 x: x, 109 y: y 110 } 111 ], 112 angle: rand(0, 360), 113 speed: rand(((self.partSpeed - self.partSpeedVariance) <= 0) ? 1 : self.partSpeed - self.partSpeedVariance, 114 (self.partSpeed + self.partSpeedVariance)), 115 friction: 1 - self.partFriction / 100, 116 gravity: self.partGravity / 2, 117 hue: rand(hue - self.hueVariance, hue + self.hueVariance), 118 brightness: rand(50, 80), 119 alpha: rand(40, 100) / 100, 120 decay: rand(10, 50) / 1000, 121 wind: (rand(0, self.partWind) - (self.partWind / 2)) / 25, 122 lineWidth: self.lineWidth 123 }; 124 self.particles.push(newParticle); 125 } 126 }; 127 128 129 self.updateParticles = function() { 130 var i = self.particles.length; 131 while (i--) { 132 var p = self.particles[i]; 133 var radians = p.angle * Math.PI / 180; 134 var vx = Math.cos(radians) * p.speed; 135 var vy = Math.sin(radians) * p.speed; 136 p.speed *= p.friction; 137 138 p.coordLast[2].x = p.coordLast[1].x; 139 p.coordLast[2].y = p.coordLast[1].y; 140 p.coordLast[1].x = p.coordLast[0].x; 141 p.coordLast[1].y = p.coordLast[0].y; 142 p.coordLast[0].x = p.x; 143 p.coordLast[0].y = p.y; 144 145 p.x += vx; 146 p.y += vy; 147 p.y += p.gravity; 148 149 p.angle += p.wind; 150 p.alpha -= p.decay; 151 152 if (!hitTest(0, 0, self.cw, self.ch, p.x - p.radius, p.y - p.radius, p.radius * 2, p.radius * 2) || p.alpha < 153 .05) { 154 self.particles.splice(i, 1); 155 } 156 }; 157 }; 158 159 self.drawParticles = function() { 160 var i = self.particles.length; 161 while (i--) { 162 var p = self.particles[i]; 163 164 var coordRand = (rand(1, 3) - 1); 165 self.ctx.beginPath(); 166 self.ctx.moveTo(Math.round(p.coordLast[coordRand].x), Math.round(p.coordLast[coordRand].y)); 167 self.ctx.lineTo(Math.round(p.x), Math.round(p.y)); 168 self.ctx.closePath(); 169 self.ctx.strokeStyle = 'hsla(' + p.hue + ', 100%, ' + p.brightness + '%, ' + p.alpha + ')'; 170 self.ctx.stroke(); 171 172 if (self.flickerDensity > 0) { 173 var inverseDensity = 50 - self.flickerDensity; 174 if (rand(0, inverseDensity) === inverseDensity) { 175 self.ctx.beginPath(); 176 self.ctx.arc(Math.round(p.x), Math.round(p.y), rand(p.lineWidth, p.lineWidth + 3) / 2, 0, Math.PI * 2, false) 177 self.ctx.closePath(); 178 var randAlpha = rand(50, 100) / 100; 179 self.ctx.fillStyle = 'hsla(' + p.hue + ', 100%, ' + p.brightness + '%, ' + randAlpha + ')'; 180 self.ctx.fill(); 181 } 182 } 183 }; 184 }; 185 186 187 self.createFireworks = function(startX, startY, targetX, targetY) { 188 var newFirework = { 189 x: startX, 190 y: startY, 191 startX: startX, 192 startY: startY, 193 hitX: false, 194 hitY: false, 195 coordLast: [{ 196 x: startX, 197 y: startY 198 }, 199 { 200 x: startX, 201 y: startY 202 }, 203 { 204 x: startX, 205 y: startY 206 } 207 ], 208 targetX: targetX, 209 targetY: targetY, 210 speed: self.fworkSpeed, 211 angle: Math.atan2(targetY - startY, targetX - startX), 212 shockwaveAngle: Math.atan2(targetY - startY, targetX - startX) + (90 * (Math.PI / 180)), 213 acceleration: self.fworkAccel / 100, 214 hue: self.currentHue, 215 brightness: rand(50, 80), 216 alpha: rand(50, 100) / 100, 217 lineWidth: self.lineWidth 218 }; 219 if (self.fireworks.length < self.hueMax) { 220 self.fireworks.push(newFirework); 221 } 222 223 224 }; 225 226 227 self.updateFireworks = function() { 228 var i = self.fireworks.length; 229 230 while (i--) { 231 var f = self.fireworks[i]; 232 self.ctx.lineWidth = f.lineWidth; 233 234 vx = Math.cos(f.angle) * f.speed, 235 vy = Math.sin(f.angle) * f.speed; 236 f.speed *= 1 + f.acceleration; 237 f.coordLast[2].x = f.coordLast[1].x; 238 f.coordLast[2].y = f.coordLast[1].y; 239 f.coordLast[1].x = f.coordLast[0].x; 240 f.coordLast[1].y = f.coordLast[0].y; 241 f.coordLast[0].x = f.x; 242 f.coordLast[0].y = f.y; 243 244 if (f.startX >= f.targetX) { 245 if (f.x + vx <= f.targetX) { 246 f.x = f.targetX; 247 f.hitX = true; 248 } else { 249 f.x += vx; 250 } 251 } else { 252 if (f.x + vx >= f.targetX) { 253 f.x = f.targetX; 254 f.hitX = true; 255 } else { 256 f.x += vx; 257 } 258 } 259 260 if (f.startY >= f.targetY) { 261 if (f.y + vy <= f.targetY) { 262 f.y = f.targetY; 263 f.hitY = true; 264 } else { 265 f.y += vy; 266 } 267 } else { 268 if (f.y + vy >= f.targetY) { 269 f.y = f.targetY; 270 f.hitY = true; 271 } else { 272 f.y += vy; 273 } 274 } 275 276 if (f.hitX && f.hitY) { 277 self.createParticles(f.targetX, f.targetY, f.hue); 278 self.fireworks.splice(i, 1); 279 280 } 281 }; 282 }; 283 284 self.drawFireworks = function() { 285 var i = self.fireworks.length; 286 self.ctx.globalCompositeOperation = 'lighter'; 287 while (i--) { 288 var f = self.fireworks[i]; 289 self.ctx.lineWidth = f.lineWidth; 290 291 var coordRand = (rand(1, 3) - 1); 292 self.ctx.beginPath(); 293 self.ctx.moveTo(Math.round(f.coordLast[coordRand].x), Math.round(f.coordLast[coordRand].y)); 294 self.ctx.lineTo(Math.round(f.x), Math.round(f.y)); 295 self.ctx.closePath(); 296 self.ctx.strokeStyle = 'hsla(' + f.hue + ', 100%, ' + f.brightness + '%, ' + f.alpha + ')'; 297 self.ctx.stroke(); 298 299 if (self.showTarget) { 300 self.ctx.save(); 301 self.ctx.beginPath(); 302 self.ctx.arc(Math.round(f.targetX), Math.round(f.targetY), rand(1, 8), 0, Math.PI * 2, false) 303 self.ctx.closePath(); 304 self.ctx.lineWidth = 1; 305 self.ctx.stroke(); 306 self.ctx.restore(); 307 } 308 309 if (self.showShockwave) { 310 self.ctx.save(); 311 self.ctx.translate(Math.round(f.x), Math.round(f.y)); 312 self.ctx.rotate(f.shockwaveAngle); 313 self.ctx.beginPath(); 314 self.ctx.arc(0, 0, 1 * (f.speed / 5), 0, Math.PI, true); 315 self.ctx.strokeStyle = 'hsla(' + f.hue + ', 100%, ' + f.brightness + '%, ' + rand(25, 60) / 100 + ')'; 316 self.ctx.lineWidth = f.lineWidth; 317 self.ctx.stroke(); 318 self.ctx.restore(); 319 } 320 }; 321 }; 322 323 self.bindEvents = function() { 324 $(window).on('resize', function() { 325 clearTimeout(self.timeout); 326 self.timeout = setTimeout(function() { 327 self.canvas.width = self.cw = $(window).innerWidth(); 328 self.canvas.height = self.ch = $(window).innerHeight(); 329 self.ctx.lineCap = 'round'; 330 self.ctx.lineJoin = 'round'; 331 }, 100); 332 }); 333 //鼠标点击释放烟花 334 $(self.canvas).on('mousedown', function(e) { 335 self.mx = e.pageX - self.canvas.offsetLeft; 336 self.my = e.pageY - self.canvas.offsetTop; 337 self.currentHue = rand(self.hueMin, self.hueMax); 338 self.createFireworks(self.cw / 2, self.ch, self.mx, self.my); 339 340 $(self.canvas).on('mousemove.fireworks', function(e) { 341 self.mx = e.pageX - self.canvas.offsetLeft; 342 self.my = e.pageY - self.canvas.offsetTop; 343 self.currentHue = rand(self.hueMin, self.hueMax); 344 self.createFireworks(self.cw / 2, self.ch, self.mx, self.my); 345 }); 346 }); 347 348 $(self.canvas).on('mouseup', function(e) { 349 $(self.canvas).off('mousemove.fireworks'); 350 }); 351 352 } 353 354 self.clear = function() { 355 self.particles = []; 356 self.fireworks = []; 357 self.ctx.clearRect(0, 0, self.cw, self.ch); 358 }; 359 360 361 self.canvasLoop = function() { 362 requestAnimFrame(self.canvasLoop, self.canvas); 363 self.ctx.globalCompositeOperation = 'destination-out'; 364 self.ctx.fillStyle = 'rgba(0,0,0,' + self.clearAlpha / 100 + ')'; 365 self.ctx.fillRect(0, 0, self.cw, self.ch); 366 self.updateFireworks(); 367 self.updateParticles(); 368 self.drawFireworks(); 369 self.drawParticles(); 370 371 }; 372 373 self.testClick = function() { 374 var eventX = randomNum(0, width); 375 var eventY = randomNum(0, height); 376 self.mx = eventX; 377 self.my = eventY; 378 self.currentHue = rand(self.hueMin, self.hueMax); 379 self.createFireworks(self.cw / 2, self.ch, self.mx, self.my); 380 }; 381 382 self.setInterval = function() { 383 setTimeout(function() { 384 self.testClick(); 385 clearTimeout(self.timeout); 386 setTimeout(function() { 387 self.setInterval(); 388 }, 1000); 389 }, 1000); 390 391 392 393 }; 394 395 self.init(); 396 self.setInterval(); //PS:页面加载后自动执行 397 398 } 399 var fworks = new Fireworks(); 400 401 }); 402 403 404 var width = $(window).width(); 405 var height = $(window).height(); 406 //获取随机数 生成坐标 407 function randomNum(minNum, maxNum) { 408 switch (arguments.length) { 409 case 1: 410 return parseInt(Math.random() * minNum + 1, 10); 411 break; 412 case 2: 413 return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10); 414 break; 415 default: 416 return 0; 417 break; 418 } 419 } 420 </script>