分享几个前端烟花代码

打印 上一主题 下一主题

主题 900|帖子 900|积分 2700

利用caves生成烟花效果

团体计划思路是创建一个动态的烟花效果,通过不断的创建和更新粒子来模拟烟花爆炸和消散的过程。使用canvas举行图形绘制,利用JavaScript的类和对象来管理粒子和烟花的状态,通过requestAnimationFrame实现流畅的动画效果。
分析源码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>随机烟花效果</title>
  7.     <style>
  8.         body {
  9.             margin: 0;
  10.             padding: 0;
  11.             background: black;
  12.             overflow: hidden;
  13.         }
  14.         canvas {
  15.             display: block;
  16.         }
  17.     </style>
  18. </head>
  19. <body>
  20. <canvas id="fireworksCanvas"></canvas>
  21. <script>
  22.     // 获取canvas元素并设置其宽高
  23.     const canvas = document.getElementById('fireworksCanvas');
  24.     const ctx = canvas.getContext('2d');
  25.     canvas.width = window.innerWidth;
  26.     canvas.height = window.innerHeight;
  27.     // 生成随机数
  28.     function random(min, max) {
  29.         return Math.random() * (max - min) + min;
  30.     }
  31.     // 粒子类
  32.     class Particle {
  33.         constructor(x, y, color) {
  34.             this.x = x;
  35.             this.y = y;
  36.             this.color = color;
  37.             this.radius = random(2, 5);// 粒子的半径,随机生成2到5之间
  38.             this.opacity = 1;// 粒子的不透明度
  39.             this.velocity = {// 粒子的速度
  40.                 x: random(-5, 5),
  41.                 y: random(-5, -20)
  42.             };
  43.         }
  44.         // 绘制粒子的方法
  45.         draw() {
  46.             ctx.beginPath();
  47.             ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
  48.             ctx.fillStyle = `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, ${this.opacity})`;
  49.             ctx.fill();
  50.         }
  51.         // 更新粒子状态的方法
  52.         update() {
  53.             this.x += this.velocity.x;
  54.             this.y += this.velocity.y;
  55.             this.velocity.y += 0.1; // 模拟重力效果
  56.             this.opacity -= 0.01;// 粒子逐渐消失的效果
  57.             this.draw();
  58.         }
  59.     }
  60.     // 烟花类
  61.     class Firework {
  62.         constructor(x, y) {
  63.             this.particles = [];
  64.             const colors = ["255,0,0", "0,255,0", "0,0,255", "255,255,0", "0,255,255", "255,0,255"];
  65.             for (let i = 0; i < 100; i++) {
  66.                 // 创建粒子并赋予随机颜色
  67.                 const color = new Color(parseInt(colors[(Math.random() * colors.length) | 0]), 255, 255);
  68.                 this.particles.push(new Particle(x, y, color));
  69.             }
  70.         }
  71.         // 更新烟花中所有粒子的状态
  72.         update() {
  73.             this.particles.forEach(particle => particle.update());
  74.             this.particles = this.particles.filter(particle => particle.opacity > 0);
  75.         }
  76.     }
  77.     // 颜色类
  78.     class Color {
  79.         constructor(r, g, b) {
  80.             this.r = r;
  81.             this.g = g;
  82.             this.b = b;
  83.         }
  84.     }
  85.     // 存储所有烟花的数组
  86.     let fireworks = [];
  87.     // 触发烟花爆炸的方法
  88.     function explodeFirework() {
  89.         const x = random(0, canvas.width);
  90.         const y = canvas.height;
  91.         fireworks.push(new Firework(x, y));
  92.     }
  93.     // 动画渲染的方法
  94.     function animate() {
  95.         ctx.clearRect(0, 0, canvas.width, canvas.height);
  96.         fireworks.forEach(firework => firework.update());
  97.         fireworks = fireworks.filter(firework => firework.particles.length > 0);
  98.         if (Math.random() < 0.05) { // 有5%的概率触发新的烟花
  99.             explodeFirework();
  100.         }
  101.         // 开始动画循环
  102.         requestAnimationFrame(animate);
  103.     }
  104.     animate();
  105. </script>
  106. </body>
  107. </html>
复制代码
计划思路:


  • 初始化环境

    • 使用<canvas>元素作为画布,通过JavaScript来绘制烟花效果。
    • 设置画布的宽高为欣赏器窗口的宽高,以便烟花效果能够覆盖整个可视地区。

  • 定义辅助函数和类

    • random(min, max):一个简单的辅助函数,用于生成指定范围内的随机数,这在创建烟花效果时用于随机化粒子的属性。
    • Particle类:代表烟花爆炸后产生的单个粒子。粒子具有位置、颜色、巨细、速度和不透明度等属性。
    • Firework类:代表一个完备的烟花,由多个Particle实例组成。
    • Color类:用于存储颜色信息。

  • 创建烟花

    • 在一个数组fireworks中存储全部烟花实例。
    • 通过explodeFirework函数在画布的随机位置创建一个新的烟花。

  • 动画循环

    • 使用requestAnimationFrame创建一个动画循环,这个函数会在欣赏器预备好绘制下一帧时调用提供的回调函数。
    • 在每次动画帧中,更新全部烟花的状态,并清除画布上的旧内容。

  • 更新和渲染

    • 在animate函数中,遍历fireworks数组,更新每个烟花中的粒子状态,并绘制到画布上。
    • 粒子状态更新包括位置的改变、速度的调解(模拟重力)、不透明度的淘汰(模拟烟花逐渐消失的效果)。
    • 移除不透明的粒子,以淘汰盘算量并避免内存泄漏。

代码详细讲授:


  • HTML布局

    • <canvas id="fireworksCanvas"></canvas>:定义了一个画布元素,用于绘制烟花效果。

  • CSS样式

    • 设置body和canvas的样式,确保画布覆盖整个窗口,并且没有滚动条。

  • JavaScript代码
    a. 初始化
    1. const canvas = document.getElementById('fireworksCanvas');
    2. const ctx = canvas.getContext('2d');
    3. canvas.width = window.innerWidth;
    4. canvas.height = window.innerHeight;
    复制代码

    • 获取画布元素并设置其宽高。
      b. 辅助函数
    1. function random(min, max) {
    2.     return Math.random() * (max - min) + min;
    3. }
    复制代码
      

    • 生成一个在min和max之间的随机数。
      c. 粒子类
    1. class Particle {
    2.     // ...
    3. }
    复制代码
      

    • 包含粒子的属性和方法,用于绘制和更新粒子状态。
      d. 烟花类
    1. class Firework {
    2.     // ...
    3. }
    复制代码
      

    • 包含一个烟花所需的全部粒子,并负责更新它们。
      e. 颜色类
    1. class Color {
    2.     // ...
    3. }
    复制代码
      

    • 用于表示粒子的颜色。
      f. 动画循环
    1. function animate() {
    2.     // ...
    3.     requestAnimationFrame(animate);
    4. }
    5. animate();
    复制代码
      

    • 清除画布、更新烟花状态、查抄并触发新的烟花,然后请求下一帧。

接下来分享几个基于以上思路实现的烟花代码:

案例1:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>随机烟花效果</title>
  7.     <style>
  8.         body {
  9.             margin: 0;
  10.             padding: 0;
  11.             background: black;
  12.             overflow: hidden;
  13.             display: flex;
  14.             justify-content: center;
  15.             align-items: center;
  16.             height: 100vh;
  17.         }
  18.         canvas {
  19.             display: block;
  20.         }
  21.         #congrats {
  22.             position: absolute;
  23.             top: 50%;
  24.             left: 50%;
  25.             transform: translate(-50%, -50%);
  26.             color: #ff00ff; /* 紫色 */
  27.             font-size: 3em;
  28.             opacity: 0;
  29.             transition: opacity 2s ease-in-out;
  30.             pointer-events: none;
  31.             white-space: nowrap;
  32.             font-family: 'Arial Black', sans-serif;
  33.             text-shadow: 0 0 5px #ffffff, 0 0 10px #ffffff, 0 0 20px #ff00ff, 0 0 30px #ff00ff, 0 0 40px #ff00ff, 0 0 50px #ff00ff, 0 0 75px #ff00ff;
  34.             animation: flash 3s ease-in-out infinite;
  35.         }
  36.         @keyframes flash {
  37.             0%, 100% { opacity: 0; }
  38.             50% { opacity: 1; }
  39.         }
  40.     </style>
  41. </head>
  42. <body>
  43. <canvas id="fireworksCanvas"></canvas>
  44. <div id="congrats">文本</div>
  45. <script>
  46.     const canvas = document.getElementById('fireworksCanvas');
  47.     const ctx = canvas.getContext('2d');
  48.     const congrats = document.getElementById('congrats');
  49.     canvas.width = window.innerWidth;
  50.     canvas.height = window.innerHeight;
  51.     function random(min, max) {
  52.         return Math.random() * (max - min) + min;
  53.     }
  54.     function randomColor() {
  55.         return {
  56.             r: Math.floor(random(0, 255)),
  57.             g: Math.floor(random(0, 255)),
  58.             b: Math.floor(random(0, 255))
  59.         };
  60.     }
  61.     class Particle {
  62.         constructor(x, y, color) {
  63.             this.x = x;
  64.             this.y = y;
  65.             this.color = color;
  66.             this.radius = random(2, 5);
  67.             this.opacity = 1;
  68.             this.velocity = {
  69.                 x: random(-5, 5),
  70.                 y: random(-20, -5)
  71.             };
  72.         }
  73.         draw() {
  74.             ctx.beginPath();
  75.             ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
  76.             ctx.fillStyle = `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, ${this.opacity})`;
  77.             ctx.fill();
  78.         }
  79.         update() {
  80.             this.x += this.velocity.x;
  81.             this.y += this.velocity.y;
  82.             this.velocity.y += 0.1; // gravity
  83.             this.opacity -= 0.01;
  84.             if (this.opacity > 0) {
  85.                 this.draw();
  86.             }
  87.         }
  88.     }
  89.     class Firework {
  90.         constructor(x, y) {
  91.             this.particles = [];
  92.             for (let i = 0; i < 100; i++) {
  93.                 const color = randomColor();
  94.                 this.particles.push(new Particle(x, y, color));
  95.             }
  96.         }
  97.         update() {
  98.             this.particles.forEach(particle => particle.update());
  99.             this.particles = this.particles.filter(particle => particle.opacity > 0);
  100.         }
  101.     }
  102.     let fireworks = [];
  103.     function explodeFirework() {
  104.         const x = random(0, canvas.width);
  105.         const y = canvas.height;
  106.         fireworks.push(new Firework(x, y));
  107.         displayText("写下你想显示的文本");
  108.     }
  109.     function displayText(text) {
  110.         congrats.textContent = text;
  111.         congrats.style.opacity = 1;
  112.         setTimeout(() => {
  113.             congrats.style.opacity = 0;
  114.         }, 2000);
  115.     }
  116.     function animate() {
  117.         ctx.clearRect(0, 0, canvas.width, canvas.height);
  118.         fireworks.forEach(firework => firework.update());
  119.         fireworks = fireworks.filter(firework => firework.particles.length > 0);
  120.         if (Math.random() < 0.05) {
  121.             explodeFirework();
  122.         }
  123.         requestAnimationFrame(animate);
  124.     }
  125.     animate();
  126. </script>
  127. </body>
  128. </html>
复制代码
案例2:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>烟花效果思路原型</title>
  6. <style>
  7.   body, html {
  8.     margin: 0;
  9.     padding: 0;
  10.     overflow: hidden;
  11.     background-color: black;
  12.   }
  13.   .firework {
  14.     position: absolute;
  15.     bottom: 0;
  16.     width: 5px;
  17.     height: 5px;
  18.     background-color: white;
  19.     border-radius: 50%;
  20.   }
  21.   .particle {
  22.     position: absolute;
  23.     border-radius: 50%;
  24.     background-color: white;
  25.   }
  26. </style>
  27. </head>
  28. <body>
  29. <script>
  30.   function launchFirework() {
  31.     const firework = document.createElement('div');
  32.     firework.classList.add('firework');
  33.     firework.style.left = Math.random() * window.innerWidth + 'px';
  34.     document.body.appendChild(firework);
  35.     const height = Math.random() * (window.innerHeight - 100) + 100;
  36.     const duration = Math.random() * 3000 + 2000;
  37.     firework.animate([
  38.       { transform: 'translateY(0px)' },
  39.       { transform: `translateY(-${height}px)` }
  40.     ], {
  41.       duration: duration,
  42.       easing: 'ease-out',
  43.       fill: 'forwards'
  44.     });
  45.     setTimeout(() => {
  46.       explodeFirework(firework, height);
  47.       document.body.removeChild(firework);
  48.     }, duration);
  49.   }
  50.   function explodeFirework(firework, height) {
  51.     const particlesCount = Math.random() * 50 + 20;
  52.     for (let i = 0; i < particlesCount; i++) {
  53.       const particle = document.createElement('div');
  54.       particle.classList.add('particle');
  55.       particle.style.left = firework.offsetLeft + 'px';
  56.       particle.style.bottom = window.innerHeight - height + 'px';
  57.       particle.style.width = particle.style.height = Math.random() * 5 + 'px';
  58.       document.body.appendChild(particle);
  59.       const angle = Math.random() * Math.PI * 2;
  60.       const distance = Math.random() * 100;
  61.       const duration = Math.random() * 2000 + 1000;
  62.       particle.animate([
  63.         { transform: 'translate(0, 0) scale(1)' },
  64.         { transform: `translate(${distance * Math.cos(angle)}px,${distance * Math.sin(angle)}px) scale(0)` }
  65.       ], {
  66.         duration: duration,
  67.         easing: 'ease-out',
  68.         fill: 'forwards'
  69.       });
  70.       setTimeout(() => {
  71.         document.body.removeChild(particle);
  72.       }, duration);
  73.     }
  74.   }
  75.   function randomFireworks() {
  76.     setInterval(() => {
  77.       const delay = Math.random() * 1000;
  78.       setTimeout(launchFirework, delay);
  79.     }, 500);
  80.   }
  81.   randomFireworks();
  82. </script>
  83. </body>
  84. </html>
复制代码
案例3:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>烟花效果原型</title>
  6. <style>
  7.   body, html {
  8.     margin: 0;
  9.     padding: 0;
  10.     overflow: hidden;
  11.   }
  12.   canvas {
  13.     background: black;
  14.   }
  15. </style>
  16. </head>
  17. <body>
  18. <canvas id="fireworks"></canvas>
  19. <script>
  20. // 获取canvas元素并设置其宽高
  21. const canvas = document.getElementById('fireworks');
  22. const ctx = canvas.getContext('2d');
  23. canvas.width = window.innerWidth;
  24. canvas.height = window.innerHeight;
  25. // 烟花粒子类
  26. class Particle {
  27.   constructor(x, y, color) {
  28.     this.x = x;
  29.     this.y = y;
  30.     this.color = color;
  31.     this.velocity = {
  32.       x: (Math.random() - 0.5) * 5,
  33.       y: (Math.random() - 0.5) * 5
  34.     };
  35.     this.alpha = 1;
  36.   }
  37.   draw() {
  38.     ctx.save();
  39.     ctx.globalAlpha = this.alpha;
  40.     ctx.beginPath();
  41.     ctx.fillStyle = this.color;
  42.     ctx.arc(this.x, this.y, 3, 0, Math.PI * 2, false);
  43.     ctx.fill();
  44.     ctx.restore();
  45.   }
  46.   update() {
  47.     this.velocity.y += 0.1; // 加速度模拟重力
  48.     this.x += this.velocity.x;
  49.     this.y += this.velocity.y;
  50.     this.alpha -= 0.015; // 粒子渐隐效果
  51.     // 检查粒子是否超出屏幕
  52.     if (this.x < 0 || this.x > canvas.width || this.y < 0 || this.y > canvas.height) {
  53.       this.alpha = 0; // 将alpha设置为0来移除粒子
  54.     }
  55.   }
  56. }
  57. // 烟花类
  58. class Firework {
  59.   constructor() {
  60.     this.x = Math.random() * canvas.width;
  61.     this.y = canvas.height;
  62.     this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
  63.     const maxInitialVelocity = -Math.sqrt(2 * 0.1 * canvas.height); // 最大初始速度
  64.     // 定义最大高度和最小高度
  65.     const maxHeight = 1;
  66.     const minHeight = 0.4;
  67.     this.velocity = {
  68.       x: (Math.random() - 0.5) * 6,
  69.       y: maxInitialVelocity * (Math.random() * (maxHeight - minHeight) + minHeight) // 随机速度
  70.     };
  71.     this.particles = [];
  72.     this.exploded = false;
  73.   }
  74.   draw() {
  75.     if (!this.exploded) {
  76.       ctx.save();
  77.       ctx.beginPath();
  78.       ctx.fillStyle = this.color;
  79.       ctx.arc(this.x, this.y, 4, 0, Math.PI * 2, false);
  80.       ctx.fill();
  81.       ctx.restore();
  82.     }
  83.     this.particles.forEach(particle => particle.draw());
  84.   }
  85.   update() {
  86.     if (!this.exploded) {
  87.       this.velocity.y += 0.1; // 加速度模拟重力
  88.       this.x += this.velocity.x;
  89.       this.y += this.velocity.y;
  90.       // 确保烟花不会超出屏幕
  91.       if (this.x < 0 || this.x > canvas.width) {
  92.         this.velocity.x *= -1;
  93.       }
  94.       if (this.velocity.y >= 0) {
  95.         this.explode();
  96.       }
  97.     }
  98.     this.particles.forEach((particle, index) => {
  99.       if (particle.alpha <= 0) {
  100.         this.particles.splice(index, 1);
  101.       } else {
  102.         particle.update();
  103.       }
  104.     });
  105.   }
  106.   explode() {
  107.     for (let i = 0; i < Math.random() * 10 + 40; i++) {
  108.       this.particles.push(new Particle(this.x, this.y, this.color));
  109.     }
  110.     this.exploded = true;
  111.   }
  112. }
  113. let fireworks = [];
  114. function createFirework() {
  115.   fireworks.push(new Firework());
  116. }
  117. function animate() {
  118.   requestAnimationFrame(animate);
  119.   ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
  120.   ctx.fillRect(0, 0, canvas.width, canvas.height);
  121.   fireworks.forEach((firework, index) => {
  122.     if (firework.particles.length === 0 && firework.exploded) {
  123.       fireworks.splice(index, 1);
  124.     } else {
  125.       firework.update();
  126.       firework.draw();
  127.     }
  128.   });
  129. }
  130. function launchRandomFireworks() {
  131.   setTimeout(() => {
  132.     createFirework();
  133.     launchRandomFireworks();
  134.   }, Math.random() * 50);
  135. }
  136. launchRandomFireworks();
  137. animate();
  138. </script>
  139. </body>
复制代码
案例4:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>烟花效果原型2</title>
  6. <style>
  7.   body, html {
  8.     margin: 0;
  9.     padding: 0;
  10.     overflow: hidden;
  11.   }
  12.   canvas {
  13.     background: black;
  14.   }
  15. </style>
  16. </head>
  17. <body>
  18. <canvas id="fireworks"></canvas>
  19. <script>
  20. // 获取canvas元素并设置其宽高
  21. const canvas = document.getElementById('fireworks');
  22. const ctx = canvas.getContext('2d');
  23. canvas.width = window.innerWidth;
  24. canvas.height = window.innerHeight;
  25. // 烟花发射时的粒子类
  26. class FireworkParticle {
  27.   constructor(x, y, color) {
  28.     this.x = x;
  29.     this.y = y;
  30.     this.color = color;
  31.     this.velocity = {
  32.       x: (Math.random() - 0.5) * 3,
  33.       y: -(Math.random() * 8 + 5) // 向上的速度
  34.     };
  35.     this.alpha = 1;
  36.   }
  37.   draw() {
  38.     ctx.save();
  39.     ctx.globalAlpha = this.alpha;
  40.     ctx.beginPath();
  41.     ctx.fillStyle = this.color;
  42.     ctx.arc(this.x, this.y, 2, 0, Math.PI * 2, false);
  43.     ctx.fill();
  44.     ctx.restore();
  45.   }
  46.   update() {
  47.     this.velocity.y += 0.05; // 较小的重力影响
  48.     this.x += this.velocity.x;
  49.     this.y += this.velocity.y;
  50.     this.alpha -= 0.01; // 较快的渐隐效果
  51.     if (this.alpha <= 0) {
  52.       this.alpha = 0;
  53.     }
  54.   }
  55. }
  56. // 烟花爆炸时的粒子类
  57. class ExplosionParticle {
  58.   constructor(x, y, color) {
  59.     this.x = x;
  60.     this.y = y;
  61.     this.color = color;
  62.     this.velocity = {
  63.       x: (Math.random() - 0.5) * 6,
  64.       y: (Math.random() - 0.5) * 6
  65.     };
  66.     this.alpha = 1;
  67.   }
  68.   draw() {
  69.     ctx.save();
  70.     ctx.globalAlpha = this.alpha;
  71.     ctx.beginPath();
  72.     ctx.fillStyle = this.color;
  73.     ctx.arc(this.x, this.y, 3, 0, Math.PI * 2, false);
  74.     ctx.fill();
  75.     ctx.restore();
  76.   }
  77.   update() {
  78.     // this.velocity.y += 0.05; // 较小的重力影响
  79.     this.x += this.velocity.x;
  80.     this.y += this.velocity.y;
  81.     this.alpha -= 0.015; // 渐隐效果
  82.     if (this.alpha <= 0) {
  83.       this.alpha = 0;
  84.     }
  85.   }
  86. }
  87. // 烟花类
  88. class Firework {
  89.   constructor() {
  90.     this.x = Math.random() * canvas.width;
  91.     this.y = canvas.height;
  92.     this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
  93.     const maxInitialVelocity = -Math.sqrt(2 * 0.1 * canvas.height);
  94.     const maxHeight = 1;
  95.     const minHeight = 0.4;
  96.     this.velocity = {
  97.       x: (Math.random() - 0.5) * 6,
  98.       y: maxInitialVelocity * (Math.random() * (maxHeight - minHeight) + minHeight) // 随机速度
  99.     };
  100.     this.particles = [];
  101.     this.explosionParticles = [];
  102.     this.exploded = false;
  103.   }
  104.   draw() {
  105.     if (!this.exploded) {
  106.       ctx.save();
  107.       ctx.beginPath();
  108.       ctx.fillStyle = this.color;
  109.       ctx.arc(this.x, this.y, 4, 0, Math.PI * 2, false);
  110.       ctx.fill();
  111.       ctx.restore();
  112.     }
  113.     this.particles.forEach(particle => particle.draw());
  114.     this.explosionParticles.forEach(particle => particle.draw());
  115.   }
  116.   update() {
  117.     this.particles.forEach(particle => {
  118.       particle.update();
  119.       if (particle.alpha <= 0) {
  120.         const index = this.particles.indexOf(particle);
  121.         if (index > -1) {
  122.           this.particles.splice(index, 1);
  123.         }
  124.       }
  125.     });
  126.     this.explosionParticles.forEach(particle => {
  127.       particle.update();
  128.       if (particle.alpha <= 0) {
  129.         const index = this.explosionParticles.indexOf(particle);
  130.         if (index > -1) {
  131.           this.explosionParticles.splice(index, 1);
  132.         }
  133.       }
  134.     });
  135.     if (!this.exploded) {
  136.       this.velocity.y += 0.1; // 加速度模拟重力
  137.       this.x += this.velocity.x;
  138.       this.y += this.velocity.y;
  139.       if (this.x < 0 || this.x > canvas.width) {
  140.         this.velocity.x *= -1;
  141.       }
  142.       if (this.velocity.y >= 0) {
  143.         this.explode();
  144.       }
  145.     }
  146.   }
  147.   explode() {
  148.     for (let i = 0; i < Math.random() * 10 + 40; i++) {
  149.       this.explosionParticles.push(new ExplosionParticle(this.x, this.y, this.color));
  150.     }
  151.     this.exploded = true;
  152.   }
  153. }
  154. let fireworks = [];
  155. function createFirework() {
  156.   fireworks.push(new Firework());
  157. }
  158. function animate() {
  159.   requestAnimationFrame(animate);
  160.   ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
  161.   ctx.fillRect(0, 0, canvas.width, canvas.height);
  162.   fireworks.forEach((firework, index) => {
  163.     if (firework.particles.length === 0 && firework.explosionParticles.length === 0 && firework.exploded) {
  164.       fireworks.splice(index, 1);
  165.     } else {
  166.       firework.update();
  167.       firework.draw();
  168.     }
  169.   });
  170. }
  171. function launchRandomFireworks() {
  172.   setTimeout(() => {
  173.     createFirework();
  174.     launchRandomFireworks();
  175.   }, Math.random() * 50);
  176. }
  177. launchRandomFireworks();
  178. animate();
  179. </script>
  180. </body>
  181. </html>
复制代码
案例5:

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>烟花效果原型</title>
  6. <style>
  7.   body, html {
  8.     margin: 0;
  9.     padding: 0;
  10.     overflow: hidden;
  11.   }
  12.   canvas {
  13.     background: black;
  14.   }
  15. </style>
  16. </head>
  17. <body>
  18. <canvas id="fireworks"></canvas>
  19. <script>
  20. // 获取canvas元素并设置其宽高
  21. const canvas = document.getElementById('fireworks');
  22. const ctx = canvas.getContext('2d');
  23. canvas.width = window.innerWidth;
  24. canvas.height = window.innerHeight;
  25. // 烟花发射时的粒子类
  26. class FireworkParticle {
  27.   constructor(x, y, color) {
  28.     this.x = x;
  29.     this.y = y;
  30.     this.color = color;
  31.     this.velocity = {
  32.       x: (Math.random() - 0.5) * 3,
  33.       y: -(Math.random() * 8 + 5) // 向上的速度
  34.     };
  35.     this.alpha = 1;
  36.   }
  37.   draw() {
  38.     ctx.save();
  39.     ctx.globalAlpha = this.alpha;
  40.     ctx.beginPath();
  41.     ctx.fillStyle = this.color;
  42.     ctx.arc(this.x, this.y, 2, 0, Math.PI * 2, false);
  43.     ctx.fill();
  44.     ctx.restore();
  45.   }
  46.   update() {
  47.     this.velocity.y += 0.05; // 较小的重力影响
  48.     this.x += this.velocity.x;
  49.     this.y += this.velocity.y;
  50.     this.alpha -= 0.01; // 较快的渐隐效果
  51.     if (this.alpha <= 0) {
  52.       this.alpha = 0;
  53.     }
  54.   }
  55. }
  56. // 烟花爆炸时的粒子类
  57. class ExplosionParticle {
  58.     constructor(x, y, color, size) {
  59.     this.x = x;
  60.     this.y = y;
  61.     this.color = color;
  62.     this.velocity = {
  63.       x: (Math.random() - 0.5) * 6,
  64.       y: (Math.random() - 0.5) * 6
  65.     };
  66.     this.alpha = 1;
  67.     this.size = size; // 粒子大小
  68.   }
  69.   draw() {
  70.     ctx.save();
  71.     ctx.globalAlpha = this.alpha;
  72.     ctx.beginPath();
  73.     ctx.fillStyle = this.color;
  74.     ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
  75.     ctx.fill();
  76.     ctx.restore();
  77.   }
  78.   update() {
  79.     this.x += this.velocity.x;
  80.     this.y += this.velocity.y;
  81.     this.alpha -= 0.015; // 渐隐效果
  82.     if (this.alpha <= 0) {
  83.       this.alpha = 0;
  84.     }
  85.   }
  86. }
  87. // 烟花类
  88. class Firework {
  89.   constructor() {
  90.     this.x = Math.random() * canvas.width;
  91.     this.y = canvas.height;
  92.     this.color = this.getRandomColor(); // 使用随机颜色
  93.     const maxInitialVelocity = -Math.sqrt(2 * 0.1 * canvas.height);
  94.     const maxHeight = 1;
  95.     const minHeight = 0.4;
  96.     this.velocity = {
  97.       x: (Math.random() - 0.5) * 6,
  98.       y: maxInitialVelocity * (Math.random() * (maxHeight - minHeight) + minHeight) // 随机速度
  99.     };
  100.     this.particles = [];
  101.     this.explosionParticles = [];
  102.     this.exploded = false;
  103.   }
  104.   getRandomColor() {
  105.     const r = Math.floor(Math.random() * 256);
  106.     const g = Math.floor(Math.random() * 256);
  107.     const b = Math.floor(Math.random() * 256);
  108.     return `rgb(${r}, ${g}, ${b})`;
  109.   }
  110.   draw() {
  111.     if (!this.exploded) {
  112.       ctx.save();
  113.       ctx.beginPath();
  114.       ctx.fillStyle = this.color;
  115.       ctx.arc(this.x, this.y, 4, 0, Math.PI * 2, false);
  116.       ctx.fill();
  117.       ctx.restore();
  118.     }
  119.     this.particles.forEach(particle => particle.draw());
  120.     this.explosionParticles.forEach(particle => particle.draw());
  121.   }
  122.   update() {
  123.     this.particles.forEach(particle => {
  124.       particle.update();
  125.       if (particle.alpha <= 0) {
  126.         const index = this.particles.indexOf(particle);
  127.         if (index > -1) {
  128.           this.particles.splice(index, 1);
  129.         }
  130.       }
  131.     });
  132.     this.explosionParticles.forEach(particle => {
  133.       particle.update();
  134.       if (particle.alpha <= 0) {
  135.         const index = this.explosionParticles.indexOf(particle);
  136.         if (index > -1) {
  137.           this.explosionParticles.splice(index, 1);
  138.         }
  139.       }
  140.     });
  141.     if (!this.exploded) {
  142.       this.velocity.y += 0.1; // 加速度模拟重力
  143.       this.x += this.velocity.x;
  144.       this.y += this.velocity.y;
  145.       if (this.x < 0 || this.x > canvas.width) {
  146.         this.velocity.x *= -1;
  147.       }
  148.       if (this.velocity.y >= 0) {
  149.         this.explode();
  150.       }
  151.     }
  152.   }
  153.   explode() {
  154.     const particleCount = Math.random() * 20 + 30; // 增加粒子数量
  155.     for (let i = 0; i < particleCount; i++) {
  156.       const size = Math.random() * 3 + 1; // 粒子大小变化
  157.       const newColor = this.getRandomColor(); // 每个粒子可能有不同的颜色
  158.       this.explosionParticles.push(new ExplosionParticle(this.x, this.y, newColor, size));
  159.     }
  160.     this.exploded = true;
  161.   }
  162. }
  163. let fireworks = [];
  164. function createFirework() {
  165.   fireworks.push(new Firework());
  166. }
  167. function animate() {
  168.   requestAnimationFrame(animate);
  169.   ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
  170.   ctx.fillRect(0, 0, canvas.width, canvas.height);
  171.   fireworks.forEach((firework, index) => {
  172.     if (firework.particles.length === 0 && firework.explosionParticles.length === 0 && firework.exploded) {
  173.       fireworks.splice(index, 1);
  174.     } else {
  175.       firework.update();
  176.       firework.draw();
  177.     }
  178.   });
  179. }
  180. function launchRandomFireworks() {
  181.   setTimeout(() => {
  182.     createFirework();
  183.     launchRandomFireworks();
  184.   }, Math.random() * 50);
  185. }
  186. launchRandomFireworks();
  187. animate();
  188. </script>
  189. </body>
  190. </html>
复制代码
以上代码是我给我朋友帮忙时写的,但是后来没用上,现分享出来给大家
未完待续。。。文章不定时更新

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表