0


分享几个前端烟花代码

利用caves生成烟花效果

整体设计思路是创建一个动态的烟花效果,通过不断的创建和更新粒子来模拟烟花爆炸和消散的过程。使用

  1. canvas

进行图形绘制,利用JavaScript的类和对象来管理粒子和烟花的状态,通过

  1. requestAnimationFrame

实现流畅的动画效果。

剖析源码

  1. <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>随机烟花效果</title><style>body{margin: 0;padding: 0;background: black;overflow: hidden;}canvas{display: block;}</style></head><body><canvasid="fireworksCanvas"></canvas><script>// 获取canvas元素并设置其宽高const canvas = document.getElementById('fireworksCanvas');const ctx = canvas.getContext('2d');
  2. canvas.width = window.innerWidth;
  3. canvas.height = window.innerHeight;// 生成随机数functionrandom(min, max){return Math.random()*(max - min)+ min;}// 粒子类classParticle{constructor(x, y, color){this.x = x;this.y = y;this.color = color;this.radius =random(2,5);// 粒子的半径,随机生成2到5之间this.opacity =1;// 粒子的不透明度this.velocity ={// 粒子的速度x:random(-5,5),y:random(-5,-20)};}// 绘制粒子的方法draw(){
  4. ctx.beginPath();
  5. ctx.arc(this.x,this.y,this.radius,0, Math.PI*2,false);
  6. ctx.fillStyle =`rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, ${this.opacity})`;
  7. ctx.fill();}// 更新粒子状态的方法update(){this.x +=this.velocity.x;this.y +=this.velocity.y;this.velocity.y +=0.1;// 模拟重力效果this.opacity -=0.01;// 粒子逐渐消失的效果this.draw();}}// 烟花类classFirework{constructor(x, y){this.particles =[];const colors =["255,0,0","0,255,0","0,0,255","255,255,0","0,255,255","255,0,255"];for(let i =0; i <100; i++){// 创建粒子并赋予随机颜色const color =newColor(parseInt(colors[(Math.random()* colors.length)|0]),255,255);this.particles.push(newParticle(x, y, color));}}// 更新烟花中所有粒子的状态update(){this.particles.forEach(particle=> particle.update());this.particles =this.particles.filter(particle=> particle.opacity >0);}}// 颜色类classColor{constructor(r, g, b){this.r = r;this.g = g;this.b = b;}}// 存储所有烟花的数组let fireworks =[];// 触发烟花爆炸的方法functionexplodeFirework(){const x =random(0, canvas.width);const y = canvas.height;
  8. fireworks.push(newFirework(x, y));}// 动画渲染的方法functionanimate(){
  9. ctx.clearRect(0,0, canvas.width, canvas.height);
  10. fireworks.forEach(firework=> firework.update());
  11. fireworks = fireworks.filter(firework=> firework.particles.length >0);if(Math.random()<0.05){// 有5%的概率触发新的烟花explodeFirework();}// 开始动画循环requestAnimationFrame(animate);}animate();</script></body></html>

设计思路:

  1. 初始化环境: - 使用<canvas>元素作为画布,通过JavaScript来绘制烟花效果。- 设置画布的宽高为浏览器窗口的宽高,以便烟花效果能够覆盖整个可视区域。
  2. 定义辅助函数和类: - random(min, max):一个简单的辅助函数,用于生成指定范围内的随机数,这在创建烟花效果时用于随机化粒子的属性。- Particle类:代表烟花爆炸后产生的单个粒子。粒子具有位置、颜色、大小、速度和不透明度等属性。- Firework类:代表一个完整的烟花,由多个Particle实例组成。- Color类:用于存储颜色信息。
  3. 创建烟花: - 在一个数组fireworks中存储所有烟花实例。- 通过explodeFirework函数在画布的随机位置创建一个新的烟花。
  4. 动画循环: - 使用requestAnimationFrame创建一个动画循环,这个函数会在浏览器准备好绘制下一帧时调用提供的回调函数。- 在每次动画帧中,更新所有烟花的状态,并清除画布上的旧内容。
  5. 更新和渲染: - 在animate函数中,遍历fireworks数组,更新每个烟花中的粒子状态,并绘制到画布上。- 粒子状态更新包括位置的改变、速度的调整(模拟重力)、不透明度的减少(模拟烟花逐渐消失的效果)。- 移除不透明的粒子,以减少计算量并避免内存泄漏。

代码详细讲解:

  1. HTML结构:- <canvas id="fireworksCanvas"></canvas>:定义了一个画布元素,用于绘制烟花效果。
  2. CSS样式:- 设置bodycanvas的样式,确保画布覆盖整个窗口,并且没有滚动条。
  3. JavaScript代码: a. 初始化const canvas = document.getElementById('fireworksCanvas');const ctx = canvas.getContext('2d');canvas.width = window.innerWidth;canvas.height = window.innerHeight;- 获取画布元素并设置其宽高。 b. 辅助函数functionrandom(min, max){return Math.random()*(max - min)+ min;}- 生成一个在minmax之间的随机数。 c. 粒子类classParticle{// ...}- 包含粒子的属性和方法,用于绘制和更新粒子状态。 d. 烟花类classFirework{// ...}- 包含一个烟花所需的所有粒子,并负责更新它们。 e. 颜色类classColor{// ...}- 用于表示粒子的颜色。 f. 动画循环functionanimate(){// ...requestAnimationFrame(animate);}animate();- 清除画布、更新烟花状态、检查并触发新的烟花,然后请求下一帧。
接下来分享几个基于以上思路实现的烟花代码:
案例1:
  1. <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>随机烟花效果</title><style>body{margin: 0;padding: 0;background: black;overflow: hidden;display: flex;justify-content: center;align-items: center;height: 100vh;}canvas{display: block;}#congrats{position: absolute;top: 50%;left: 50%;transform:translate(-50%, -50%);color: #ff00ff;/* 紫色 */font-size: 3em;opacity: 0;transition: opacity 2s ease-in-out;pointer-events: none;white-space: nowrap;font-family:'Arial Black', sans-serif;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;animation: flash 3s ease-in-out infinite;}@keyframes flash{0%, 100%{opacity: 0;}50%{opacity: 1;}}</style></head><body><canvasid="fireworksCanvas"></canvas><divid="congrats">文本</div><script>const canvas = document.getElementById('fireworksCanvas');const ctx = canvas.getContext('2d');const congrats = document.getElementById('congrats');
  2. canvas.width = window.innerWidth;
  3. canvas.height = window.innerHeight;functionrandom(min, max){return Math.random()*(max - min)+ min;}functionrandomColor(){return{r: Math.floor(random(0,255)),g: Math.floor(random(0,255)),b: Math.floor(random(0,255))};}classParticle{constructor(x, y, color){this.x = x;this.y = y;this.color = color;this.radius =random(2,5);this.opacity =1;this.velocity ={x:random(-5,5),y:random(-20,-5)};}draw(){
  4. ctx.beginPath();
  5. ctx.arc(this.x,this.y,this.radius,0, Math.PI*2,false);
  6. ctx.fillStyle =`rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, ${this.opacity})`;
  7. ctx.fill();}update(){this.x +=this.velocity.x;this.y +=this.velocity.y;this.velocity.y +=0.1;// gravitythis.opacity -=0.01;if(this.opacity >0){this.draw();}}}classFirework{constructor(x, y){this.particles =[];for(let i =0; i <100; i++){const color =randomColor();this.particles.push(newParticle(x, y, color));}}update(){this.particles.forEach(particle=> particle.update());this.particles =this.particles.filter(particle=> particle.opacity >0);}}let fireworks =[];functionexplodeFirework(){const x =random(0, canvas.width);const y = canvas.height;
  8. fireworks.push(newFirework(x, y));displayText("写下你想显示的文本");}functiondisplayText(text){
  9. congrats.textContent = text;
  10. congrats.style.opacity =1;setTimeout(()=>{
  11. congrats.style.opacity =0;},2000);}functionanimate(){
  12. ctx.clearRect(0,0, canvas.width, canvas.height);
  13. fireworks.forEach(firework=> firework.update());
  14. fireworks = fireworks.filter(firework=> firework.particles.length >0);if(Math.random()<0.05){explodeFirework();}requestAnimationFrame(animate);}animate();</script></body></html>
案例2:
  1. <!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>烟花效果思路原型</title><style>body, html{margin: 0;padding: 0;overflow: hidden;background-color: black;}.firework{position: absolute;bottom: 0;width: 5px;height: 5px;background-color: white;border-radius: 50%;}.particle{position: absolute;border-radius: 50%;background-color: white;}</style></head><body><script>functionlaunchFirework(){const firework = document.createElement('div');
  2. firework.classList.add('firework');
  3. firework.style.left = Math.random()* window.innerWidth +'px';
  4. document.body.appendChild(firework);const height = Math.random()*(window.innerHeight -100)+100;const duration = Math.random()*3000+2000;
  5. firework.animate([{transform:'translateY(0px)'},{transform:`translateY(-${height}px)`}],{duration: duration,easing:'ease-out',fill:'forwards'});setTimeout(()=>{explodeFirework(firework, height);
  6. document.body.removeChild(firework);}, duration);}functionexplodeFirework(firework, height){const particlesCount = Math.random()*50+20;for(let i =0; i < particlesCount; i++){const particle = document.createElement('div');
  7. particle.classList.add('particle');
  8. particle.style.left = firework.offsetLeft +'px';
  9. particle.style.bottom = window.innerHeight - height +'px';
  10. particle.style.width = particle.style.height = Math.random()*5+'px';
  11. document.body.appendChild(particle);const angle = Math.random()* Math.PI*2;const distance = Math.random()*100;const duration = Math.random()*2000+1000;
  12. particle.animate([{transform:'translate(0, 0) scale(1)'},{transform:`translate(${distance * Math.cos(angle)}px,${distance * Math.sin(angle)}px) scale(0)`}],{duration: duration,easing:'ease-out',fill:'forwards'});setTimeout(()=>{
  13. document.body.removeChild(particle);}, duration);}}functionrandomFireworks(){setInterval(()=>{const delay = Math.random()*1000;setTimeout(launchFirework, delay);},500);}randomFireworks();</script></body></html>
案例3:
  1. <!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>烟花效果原型</title><style>body, html{margin: 0;padding: 0;overflow: hidden;}canvas{background: black;}</style></head><body><canvasid="fireworks"></canvas><script>// 获取canvas元素并设置其宽高const canvas = document.getElementById('fireworks');const ctx = canvas.getContext('2d');
  2. canvas.width = window.innerWidth;
  3. canvas.height = window.innerHeight;// 烟花粒子类classParticle{constructor(x, y, color){this.x = x;this.y = y;this.color = color;this.velocity ={x:(Math.random()-0.5)*5,y:(Math.random()-0.5)*5};this.alpha =1;}draw(){
  4. ctx.save();
  5. ctx.globalAlpha =this.alpha;
  6. ctx.beginPath();
  7. ctx.fillStyle =this.color;
  8. ctx.arc(this.x,this.y,3,0, Math.PI*2,false);
  9. ctx.fill();
  10. ctx.restore();}update(){this.velocity.y +=0.1;// 加速度模拟重力this.x +=this.velocity.x;this.y +=this.velocity.y;this.alpha -=0.015;// 粒子渐隐效果// 检查粒子是否超出屏幕if(this.x <0||this.x > canvas.width ||this.y <0||this.y > canvas.height){this.alpha =0;// 将alpha设置为0来移除粒子}}}// 烟花类classFirework{constructor(){this.x = Math.random()* canvas.width;this.y = canvas.height;this.color =`hsl(${Math.random()*360}, 100%, 50%)`;const maxInitialVelocity =-Math.sqrt(2*0.1* canvas.height);// 最大初始速度// 定义最大高度和最小高度const maxHeight =1;const minHeight =0.4;this.velocity ={x:(Math.random()-0.5)*6,y: maxInitialVelocity *(Math.random()*(maxHeight - minHeight)+ minHeight)// 随机速度};this.particles =[];this.exploded =false;}draw(){if(!this.exploded){
  11. ctx.save();
  12. ctx.beginPath();
  13. ctx.fillStyle =this.color;
  14. ctx.arc(this.x,this.y,4,0, Math.PI*2,false);
  15. ctx.fill();
  16. ctx.restore();}this.particles.forEach(particle=> particle.draw());}update(){if(!this.exploded){this.velocity.y +=0.1;// 加速度模拟重力this.x +=this.velocity.x;this.y +=this.velocity.y;// 确保烟花不会超出屏幕if(this.x <0||this.x > canvas.width){this.velocity.x *=-1;}if(this.velocity.y >=0){this.explode();}}this.particles.forEach((particle, index)=>{if(particle.alpha <=0){this.particles.splice(index,1);}else{
  17. particle.update();}});}explode(){for(let i =0; i < Math.random()*10+40; i++){this.particles.push(newParticle(this.x,this.y,this.color));}this.exploded =true;}}let fireworks =[];functioncreateFirework(){
  18. fireworks.push(newFirework());}functionanimate(){requestAnimationFrame(animate);
  19. ctx.fillStyle ='rgba(0, 0, 0, 0.1)';
  20. ctx.fillRect(0,0, canvas.width, canvas.height);
  21. fireworks.forEach((firework, index)=>{if(firework.particles.length ===0&& firework.exploded){
  22. fireworks.splice(index,1);}else{
  23. firework.update();
  24. firework.draw();}});}functionlaunchRandomFireworks(){setTimeout(()=>{createFirework();launchRandomFireworks();}, Math.random()*50);}launchRandomFireworks();animate();</script></body>
案例4:
  1. <!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>烟花效果原型2</title><style>body, html{margin: 0;padding: 0;overflow: hidden;}canvas{background: black;}</style></head><body><canvasid="fireworks"></canvas><script>// 获取canvas元素并设置其宽高const canvas = document.getElementById('fireworks');const ctx = canvas.getContext('2d');
  2. canvas.width = window.innerWidth;
  3. canvas.height = window.innerHeight;// 烟花发射时的粒子类classFireworkParticle{constructor(x, y, color){this.x = x;this.y = y;this.color = color;this.velocity ={x:(Math.random()-0.5)*3,y:-(Math.random()*8+5)// 向上的速度};this.alpha =1;}draw(){
  4. ctx.save();
  5. ctx.globalAlpha =this.alpha;
  6. ctx.beginPath();
  7. ctx.fillStyle =this.color;
  8. ctx.arc(this.x,this.y,2,0, Math.PI*2,false);
  9. ctx.fill();
  10. ctx.restore();}update(){this.velocity.y +=0.05;// 较小的重力影响this.x +=this.velocity.x;this.y +=this.velocity.y;this.alpha -=0.01;// 较快的渐隐效果if(this.alpha <=0){this.alpha =0;}}}// 烟花爆炸时的粒子类classExplosionParticle{constructor(x, y, color){this.x = x;this.y = y;this.color = color;this.velocity ={x:(Math.random()-0.5)*6,y:(Math.random()-0.5)*6};this.alpha =1;}draw(){
  11. ctx.save();
  12. ctx.globalAlpha =this.alpha;
  13. ctx.beginPath();
  14. ctx.fillStyle =this.color;
  15. ctx.arc(this.x,this.y,3,0, Math.PI*2,false);
  16. ctx.fill();
  17. ctx.restore();}update(){// this.velocity.y += 0.05; // 较小的重力影响this.x +=this.velocity.x;this.y +=this.velocity.y;this.alpha -=0.015;// 渐隐效果if(this.alpha <=0){this.alpha =0;}}}// 烟花类classFirework{constructor(){this.x = Math.random()* canvas.width;this.y = canvas.height;this.color =`hsl(${Math.random()*360}, 100%, 50%)`;const maxInitialVelocity =-Math.sqrt(2*0.1* canvas.height);const maxHeight =1;const minHeight =0.4;this.velocity ={x:(Math.random()-0.5)*6,y: maxInitialVelocity *(Math.random()*(maxHeight - minHeight)+ minHeight)// 随机速度};this.particles =[];this.explosionParticles =[];this.exploded =false;}draw(){if(!this.exploded){
  18. ctx.save();
  19. ctx.beginPath();
  20. ctx.fillStyle =this.color;
  21. ctx.arc(this.x,this.y,4,0, Math.PI*2,false);
  22. ctx.fill();
  23. ctx.restore();}this.particles.forEach(particle=> particle.draw());this.explosionParticles.forEach(particle=> particle.draw());}update(){this.particles.forEach(particle=>{
  24. particle.update();if(particle.alpha <=0){const index =this.particles.indexOf(particle);if(index >-1){this.particles.splice(index,1);}}});this.explosionParticles.forEach(particle=>{
  25. particle.update();if(particle.alpha <=0){const index =this.explosionParticles.indexOf(particle);if(index >-1){this.explosionParticles.splice(index,1);}}});if(!this.exploded){this.velocity.y +=0.1;// 加速度模拟重力this.x +=this.velocity.x;this.y +=this.velocity.y;if(this.x <0||this.x > canvas.width){this.velocity.x *=-1;}if(this.velocity.y >=0){this.explode();}}}explode(){for(let i =0; i < Math.random()*10+40; i++){this.explosionParticles.push(newExplosionParticle(this.x,this.y,this.color));}this.exploded =true;}}let fireworks =[];functioncreateFirework(){
  26. fireworks.push(newFirework());}functionanimate(){requestAnimationFrame(animate);
  27. ctx.fillStyle ='rgba(0, 0, 0, 0.1)';
  28. ctx.fillRect(0,0, canvas.width, canvas.height);
  29. fireworks.forEach((firework, index)=>{if(firework.particles.length ===0&& firework.explosionParticles.length ===0&& firework.exploded){
  30. fireworks.splice(index,1);}else{
  31. firework.update();
  32. firework.draw();}});}functionlaunchRandomFireworks(){setTimeout(()=>{createFirework();launchRandomFireworks();}, Math.random()*50);}launchRandomFireworks();animate();</script></body></html>
案例5:
  1. <!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>烟花效果原型</title><style>body, html{margin: 0;padding: 0;overflow: hidden;}canvas{background: black;}</style></head><body><canvasid="fireworks"></canvas><script>// 获取canvas元素并设置其宽高const canvas = document.getElementById('fireworks');const ctx = canvas.getContext('2d');
  2. canvas.width = window.innerWidth;
  3. canvas.height = window.innerHeight;// 烟花发射时的粒子类classFireworkParticle{constructor(x, y, color){this.x = x;this.y = y;this.color = color;this.velocity ={x:(Math.random()-0.5)*3,y:-(Math.random()*8+5)// 向上的速度};this.alpha =1;}draw(){
  4. ctx.save();
  5. ctx.globalAlpha =this.alpha;
  6. ctx.beginPath();
  7. ctx.fillStyle =this.color;
  8. ctx.arc(this.x,this.y,2,0, Math.PI*2,false);
  9. ctx.fill();
  10. ctx.restore();}update(){this.velocity.y +=0.05;// 较小的重力影响this.x +=this.velocity.x;this.y +=this.velocity.y;this.alpha -=0.01;// 较快的渐隐效果if(this.alpha <=0){this.alpha =0;}}}// 烟花爆炸时的粒子类classExplosionParticle{constructor(x, y, color, size){this.x = x;this.y = y;this.color = color;this.velocity ={x:(Math.random()-0.5)*6,y:(Math.random()-0.5)*6};this.alpha =1;this.size = size;// 粒子大小}draw(){
  11. ctx.save();
  12. ctx.globalAlpha =this.alpha;
  13. ctx.beginPath();
  14. ctx.fillStyle =this.color;
  15. ctx.arc(this.x,this.y,this.size,0, Math.PI*2,false);
  16. ctx.fill();
  17. ctx.restore();}update(){this.x +=this.velocity.x;this.y +=this.velocity.y;this.alpha -=0.015;// 渐隐效果if(this.alpha <=0){this.alpha =0;}}}// 烟花类classFirework{constructor(){this.x = Math.random()* canvas.width;this.y = canvas.height;this.color =this.getRandomColor();// 使用随机颜色const maxInitialVelocity =-Math.sqrt(2*0.1* canvas.height);const maxHeight =1;const minHeight =0.4;this.velocity ={x:(Math.random()-0.5)*6,y: maxInitialVelocity *(Math.random()*(maxHeight - minHeight)+ minHeight)// 随机速度};this.particles =[];this.explosionParticles =[];this.exploded =false;}getRandomColor(){const r = Math.floor(Math.random()*256);const g = Math.floor(Math.random()*256);const b = Math.floor(Math.random()*256);return`rgb(${r}, ${g}, ${b})`;}draw(){if(!this.exploded){
  18. ctx.save();
  19. ctx.beginPath();
  20. ctx.fillStyle =this.color;
  21. ctx.arc(this.x,this.y,4,0, Math.PI*2,false);
  22. ctx.fill();
  23. ctx.restore();}this.particles.forEach(particle=> particle.draw());this.explosionParticles.forEach(particle=> particle.draw());}update(){this.particles.forEach(particle=>{
  24. particle.update();if(particle.alpha <=0){const index =this.particles.indexOf(particle);if(index >-1){this.particles.splice(index,1);}}});this.explosionParticles.forEach(particle=>{
  25. particle.update();if(particle.alpha <=0){const index =this.explosionParticles.indexOf(particle);if(index >-1){this.explosionParticles.splice(index,1);}}});if(!this.exploded){this.velocity.y +=0.1;// 加速度模拟重力this.x +=this.velocity.x;this.y +=this.velocity.y;if(this.x <0||this.x > canvas.width){this.velocity.x *=-1;}if(this.velocity.y >=0){this.explode();}}}explode(){const particleCount = Math.random()*20+30;// 增加粒子数量for(let i =0; i < particleCount; i++){const size = Math.random()*3+1;// 粒子大小变化const newColor =this.getRandomColor();// 每个粒子可能有不同的颜色this.explosionParticles.push(newExplosionParticle(this.x,this.y, newColor, size));}this.exploded =true;}}let fireworks =[];functioncreateFirework(){
  26. fireworks.push(newFirework());}functionanimate(){requestAnimationFrame(animate);
  27. ctx.fillStyle ='rgba(0, 0, 0, 0.1)';
  28. ctx.fillRect(0,0, canvas.width, canvas.height);
  29. fireworks.forEach((firework, index)=>{if(firework.particles.length ===0&& firework.explosionParticles.length ===0&& firework.exploded){
  30. fireworks.splice(index,1);}else{
  31. firework.update();
  32. firework.draw();}});}functionlaunchRandomFireworks(){setTimeout(()=>{createFirework();launchRandomFireworks();}, Math.random()*50);}launchRandomFireworks();animate();</script></body></html>
  1. 以上代码是我给我朋友帮忙时写的,但是后来没用上,现分享出来给大家
  1. 未完待续。。。文章不定时更新

本文转载自: https://blog.csdn.net/weixin_74905854/article/details/142443212
版权归原作者 韩梓 所有, 如有侵权,请联系我们删除。

“分享几个前端烟花代码”的评论:

还没有评论