性能比直接操作 div 好很多, 放 10 个烟花也不是很卡, 也可能是我写的比较挫, 动画执行那块我自己看着都醉了 div 实现烟花效果
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width">
- <title>Fireworks</title>
- <style>
- html,body,canvas {
- width: 100vw;
- height: 100vh;
- background: black;
- overflow: hidden;
- }
- </style>
- </head>
- <body>
- <canvas><canvas>
- <script>
- window.onload = function() {
- var width = window.innerWidth;
- var height = window.innerHeight;
- var count = 0;
- var limit = 10;
- var bigFireworks = [];
- var fireworkStyles = [1.01, 1.02, 1.03, 6, 9];// 烟花样式
- var canvas = document.querySelector("canvas");
- var ctx = canvas.getContext("2d");
- canvas.width = width;
- canvas.height = height;
- window.onresize = function() {
- width = window.innerWidth;
- height = window.innerHeight;
- canvas.width = width;
- canvas.height = height;
- }
- function randomNUM(min, max) {
- return Math.floor(Math.random() * (max - min) + min);
- }
- function Firework(x, y) {
- this.x = x;
- this.y = y;
- this.vx = 0;//4 * (Math.random() - 0.5);// 设置了垂直上升
- this.vy = 6 * (Math.random() - 1.5);
- this.radius = 4;
- this.g = Math.ceil(Math.random() * 255);
- this.b = Math.ceil(Math.random() * 255);
- this.style = fireworkStyles[randomNUM(0, fireworkStyles.length)];
- this.opacity = 1;
- this.count1 = 0;
- this.count2 = 0;
- this.limit = 5;
- this.bigFrieballs = [];
- this.isMove = true;
- this.isFirst = true;
- this.isBloom = false;
- this.isReset = false;
- }
- Firework.prototype.move = function() {
- this.x += this.vx;
- this.y += this.vy;
- if (this.y <height / randomNUM(2, 12)) {
- this.isMove = false;
- this.isBloom = true;
- if (!this.isFirst) this.isReset = true;
- this.bloomX = this.x;
- this.bloomY = this.y;
- this.x = randomNUM(width / 4, width / 4 * 3);
- this.y = height;
- this.vx = 0;//4 * (Math.random() - 0.5);
- this.vy = 6 * (Math.random() - 1.5);
- this.g = Math.ceil(Math.random() * 255);
- this.b = Math.ceil(Math.random() * 255);
- this.style = fireworkStyles[randomNUM(0, fireworkStyles.length)];
- this.count2 = 0;
- }
- }
- function Fireball(firework) {
- this.x = firework.bloomX;
- this.y = firework.bloomY;
- this.vx = 2;
- this.vy = 2;
- this.angle = Math.ceil(Math.random() * 360) * Math.PI / 180;
- this.radius = 2;
- this.opacity = 1;
- this.g = firework.g;
- this.b = firework.b;
- }
- function drawFBW(fbw) {
- ctx.fillStyle = "rgba(255," + fbw.g + "," + fbw.b + "," + fbw.opacity + ")";
- ctx.beginPath();
- ctx.arc(fbw.x, fbw.y, fbw.radius, 0, Math.PI * 2, false);
- ctx.closePath();
- ctx.fill();
- }
- function makeFireball(firework) {
- var fireballs = [];
- for (var i = 0; i < 50; i++) {
- fireballs[i] = new Fireball(firework);
- }
- fireballs.isOver = false;
- return fireballs;
- }
- function resetFireball(fireballs, firework) {
- for (var i = 0; i < fireballs.length; i++) {
- var fireball = fireballs[i];
- fireball.x = firework.bloomX;
- fireball.y = firework.bloomY;
- fireball.vx = 2;
- fireball.vy = 2;
- fireball.angle = Math.ceil(Math.random() * 360) * Math.PI / 180;
- fireball.opacity = 1;
- fireball.g = firework.g;
- fireball.b = firework.b;
- }
- fireballs.isOver = false;
- }
- function moveFireball(fireballs, firework) {
- for (var i = 0; i < fireballs.length; i++) {
- var fireball = fireballs[i];
- fireball.x += fireball.vx * Math.cos(fireball.angle);
- fireball.y += fireball.vy * Math.sin(fireball.angle);
- fireball.opacity -= 0.015;
- fireball.angle *= 1.01;//firework.style;// 可以设置成随机的样式, 现在是固定的样式
- fireball.vx += 0.1;
- fireball.vy += 0.1;
- drawFBW(fireball);
- }
- if (fireballs.every(function(fireball) {
- return fireball.opacity <= 0;})) {
- fireballs.isOver = true;
- }
- }
- (function animate() {
- ctx.clearRect(0, 0, width, height);
- if (count < limit) {
- bigFireworks[count] = new Firework(randomNUM(width / 4, width / 4 * 3), height);
- count += 1;
- }
- bigFireworks.forEach(function(firework) {
- if (firework.isMove) {
- firework.move();
- drawFBW(firework);
- }
- if (firework.isBloom) {
- if (firework.count1 < firework.limit) {
- firework.bigFrieballs[firework.count1] = (makeFireball(firework));
- firework.count1 += 1;
- }
- if (firework.isReset) {
- if (firework.count2 < firework.limit) {
- resetFireball(firework.bigFrieballs[firework.count2], firework);
- firework.count2 += 1;
- }
- }
- firework.bigFrieballs.forEach(function(fireballs) {
- moveFireball(fireballs, firework);
- })
- if (firework.bigFrieballs.every(function(fireballs) {
- return fireballs.isOver === true;
- })) {
- firework.isBloom = false;
- firework.isMove = true;
- firework.isFirst = false;
- }
- }
- })
- requestAnimationFrame(animate);
- })()
- }
- </script>
- </body>
- </html>
来源: http://www.qdfuns.com/article/45516/7d49ea503fe3feb55749616a846247eb.html