JavaScript实现烟花绽放动画效果

下面就是JavaScript实现烟花绽放动画效果的完整攻略。

前置知识

在进行本教程之前,你需要掌握以下的前置知识:

  • HTML、CSS基础
  • JavaScript基础语法
  • Canvas基础

如果你还不熟悉这些,可以先去学习一下。

实现思路

要实现烟花绽放动画效果,我们需要做以下的一些事情:

  1. 在页面中创建一个Canvas元素,用来绘制烟花图案。
  2. 监听鼠标点击事件,当用户点击页面时,在点击位置创建一个烟花。
  3. 在创建的烟花中,随机生成一些花瓣,然后让它们向外扩散。
  4. 在每个扩散的花瓣中再次生成一些小花瓣,让它们向外扩散。
  5. 等到所有花瓣都扩散完毕之后,烟花会变成一个白色的圆,然后逐渐消失。

下面我们就来一步一步实现这个效果。

步骤一:创建Canvas元素

首先在HTML的body中创建一个Canvas元素:

<canvas id="fireworks"></canvas>

然后在JavaScript中获取这个元素,并设置它的大小:

const canvas = document.getElementById('fireworks');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

步骤二:监听鼠标点击事件

接下来我们要监听鼠标点击事件,当用户点击页面时,就在点击位置创建一个烟花。这里我们可以使用canvas的addEventListener方法来实现:

canvas.addEventListener('click', function(event) {
  createFirework(event.clientX, event.clientY);
}, false);

这个方法会在canvas上监听鼠标点击事件,并在点击位置创建一个烟花。

步骤三:随机生成花瓣并扩散

在创建的烟花中,我们需要随机生成一些花瓣,并让它们向外扩散。我们可以先在烟花的构造函数中生成这些花瓣:

function Firework(x, y) {
  this.x = x;
  this.y = y;
  this.age = 0;
  this.lifespan = 100;
  this.particles = [];

  for (let i = 0; i < 100; i++) {
    const particle = {
      x: this.x,
      y: this.y,
      vx: Math.random() * 3 - 1.5,
      vy: Math.random() * 3 - 1.5,
      color: `hsl(${Math.random() * 360}, 50%, 50%)`
    };
    this.particles.push(particle);
  }
}

这段代码会在烟花对象中创建一个particles数组,并在其中生成100个花瓣。

然后,在烟花对象的update方法中,我们需要让每个花瓣向外扩散:

Firework.prototype.update = function() {
  for (let i = 0; i < this.particles.length; i++) {
    const particle = this.particles[i];
    particle.vx *= 0.9;
    particle.vy *= 0.9;
    particle.x += particle.vx;
    particle.y += particle.vy;
    particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;
  }
  this.age++;
};

这段代码会让每个花瓣的速度逐渐减小,并使其向外扩散。

步骤四:生成小花瓣并扩散

接下来我们要在每个扩散的花瓣中再次生成一些小花瓣,并让它们向外扩散。我们可以先在烟花对象的update方法中,检查花瓣是否到达了极限速度,然后在它们的位置生成一些小花瓣:

Firework.prototype.update = function() {
  for (let i = 0; i < this.particles.length; i++) {
    const particle = this.particles[i];
    particle.vx *= 0.9;
    particle.vy *= 0.9;
    particle.x += particle.vx;
    particle.y += particle.vy;
    particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;

    if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
      this.createParticles(particle.x, particle.y);
    }
  }
  this.age++;
};

这段代码会在花瓣速度达到一定程度之后,在当前位置生成一些小花瓣。

然后,我们需要在烟花对象中添加一个方法createParticles,用来生成小花瓣:

Firework.prototype.createParticles = function(x, y) {
  for (let i = 0; i < 50; i++) {
    const particle = {
      x: x,
      y: y,
      vx: Math.random() * 3 - 1.5,
      vy: Math.random() * 3 - 1.5,
      color: `hsl(${Math.random() * 360}, 50%, 50%)`
    };
    this.particles.push(particle);
  }
};

这段代码会在指定位置生成50个小花瓣,并加入到烟花对象的particles数组中。

步骤五:变成白色圆并逐渐消失

等到所有花瓣都扩散完毕之后,烟花会变成一个白色的圆,然后逐渐消失。我们可以在烟花对象的update方法中,检查是否到达了寿命极限,然后将烟花变成一个白色圆:

Firework.prototype.update = function() {
  if (this.age > this.lifespan) {
    this.particles = [{
      x: this.x,
      y: this.y,
      vx: 0,
      vy: 0,
      color: '#ffffff'
    }];
  } else {
    for (let i = 0; i < this.particles.length; i++) {
      const particle = this.particles[i];
      particle.vx *= 0.9;
      particle.vy *= 0.9;
      particle.x += particle.vx;
      particle.y += particle.vy;
      particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;

      if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
        this.createParticles(particle.x, particle.y);
      }
    }
    this.age++;
  }
};

这段代码会在烟花寿命结束之后,将烟花对象的particles数组中只保留一个白色的花瓣。

然后,我们需要在烟花对象的draw方法中,绘制花瓣:

Firework.prototype.draw = function(context) {
  for (let i = 0; i < this.particles.length; i++) {
    const particle = this.particles[i];
    context.beginPath();
    context.fillStyle = particle.color;
    context.arc(particle.x, particle.y, 2, 0, Math.PI * 2, false);
    context.fill();
  }
};

这段代码会将烟花对象的所有花瓣绘制出来。

示例说明一:在火箭上实现烟花绽放

我们可以先在页面中创建一个火箭对象,然后让它在页面上飞行。当火箭到达指定位置时,就在它所在位置创建一个烟花对象。

可以参考以下的示例代码:

const canvas = document.getElementById('fireworks');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const context = canvas.getContext('2d');

class Rocket {
  constructor(x, y, width, height, vx, vy) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.vx = vx;
    this.vy = vy;
    this.exploded = false;
    this.explosion = null;
  }

  move() {
    this.x += this.vx;
    this.y += this.vy;
  }

  draw() {
    if (this.exploded) {
      this.explosion.draw(context);
    } else {
      context.fillStyle = '#000000';
      context.fillRect(this.x, this.y, this.width, this.height);
    }
  }

  checkPosition() {
    if (this.y < window.innerHeight / 2) {
      this.explode();
    }
  }

  explode() {
    this.exploded = true;
    this.explosion = new Firework(this.x + this.width / 2, this.y + this.height);
  }
}

class Firework {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.age = 0;
    this.lifespan = 100;
    this.particles = [];

    for (let i = 0; i < 100; i++) {
      const particle = {
        x: this.x,
        y: this.y,
        vx: Math.random() * 3 - 1.5,
        vy: Math.random() * 3 - 1.5,
        color: `hsl(${Math.random() * 360}, 50%, 50%)`
      };
      this.particles.push(particle);
    }
  }

  createParticles(x, y) {
    for (let i = 0; i < 50; i++) {
      const particle = {
        x: x,
        y: y,
        vx: Math.random() * 3 - 1.5,
        vy: Math.random() * 3 - 1.5,
        color: `hsl(${Math.random() * 360}, 50%, 50%)`
      };
      this.particles.push(particle);
    }
  }

  update() {
    if (this.age > this.lifespan) {
      this.particles = [{
        x: this.x,
        y: this.y,
        vx: 0,
        vy: 0,
        color: '#ffffff'
      }];
    } else {
      for (let i = 0; i < this.particles.length; i++) {
        const particle = this.particles[i];
        particle.vx *= 0.9;
        particle.vy *= 0.9;
        particle.x += particle.vx;
        particle.y += particle.vy;
        particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;

        if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
          this.createParticles(particle.x, particle.y);
        }
      }
      this.age++;
    }
  }

  draw() {
    for (let i = 0; i < this.particles.length; i++) {
      const particle = this.particles[i];
      context.beginPath();
      context.fillStyle = particle.color;
      context.arc(particle.x, particle.y, 2, 0, Math.PI * 2, false);
      context.fill();
    }
  }
}

function animate() {
  requestAnimationFrame(animate);
  context.clearRect(0, 0, window.innerWidth, window.innerHeight);

  rocket.move();
  rocket.draw();
  rocket.checkPosition();

  if (rocket.exploded) {
    rocket.explosion.update();
    rocket.explosion.draw();
  }
}

const rocket = new Rocket(0, window.innerHeight - 50, 50, 50, 2, -5);

animate();

这段代码会创建一个Rocket对象,并让它在页面上飞行。当Rocket对象到达指定位置时,就在它所在位置创建一个烟花对象。

示例说明二:多个烟花同时绽放

我们可以在火箭到达指定位置之后,随机生成一些烟花对象。可以参考以下的示例代码:

const canvas = document.getElementById('fireworks');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const context = canvas.getContext('2d');

class Rocket {
  constructor(x, y, width, height, vx, vy) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.vx = vx;
    this.vy = vy;
    this.exploded = false;
    this.explosions = [];
  }

  move() {
    this.x += this.vx;
    this.y += this.vy;
  }

  draw() {
    if (this.exploded) {
      for (let i = 0; i < this.explosions.length; i++) {
        this.explosions[i].draw(context);
      }
    } else {
      context.fillStyle = '#000000';
      context.fillRect(this.x, this.y, this.width, this.height);
    }
  }

  checkPosition() {
    if (this.y < window.innerHeight / 2) {
      this.explode();
    }
  }

  explode() {
    this.exploded = true;

    for (let i = 0; i < 10; i++) {
      const explosion = new Firework(this.x + this.width / 2, this.y + this.height);
      this.explosions.push(explosion);
    }
  }
}

class Firework {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.age = 0;
    this.lifespan = 100;
    this.particles = [];

    for (let i = 0; i < 100; i++) {
      const particle = {
        x: this.x,
        y: this.y,
        vx: Math.random() * 3 - 1.5,
        vy: Math.random() * 3 - 1.5,
        color: `hsl(${Math.random() * 360}, 50%, 50%)`
      };
      this.particles.push(particle);
    }
  }

  createParticles(x, y) {
    for (let i = 0; i < 50; i++) {
      const particle = {
        x: x,
        y: y,
        vx: Math.random() * 3 - 1.5,
        vy: Math.random() * 3 - 1.5,
        color: `hsl(${Math.random() * 360}, 50%, 50%)`
      };
      this.particles.push(particle);
    }
  }

  update() {
    if (this.age > this.lifespan) {
      this.particles = [{
        x: this.x,
        y: this.y,
        vx: 0,
        vy: 0,
        color: '#ffffff'
      }];
    } else {
      for (let i = 0; i < this.particles.length; i++) {
        const particle = this.particles[i];
        particle.vx *= 0.9;
        particle.vy *= 0.9;
        particle.x += particle.vx;
        particle.y += particle.vy;
        particle.color = `hsl(${Math.random() * 360}, 50%, 50%)`;

        if (Math.abs(particle.vx) < 0.05 && Math.abs(particle.vy) < 0.05) {
          this.createParticles(particle.x, particle.y);
        }
      }
      this.age++;
    }
  }

  draw() {
    for (let i = 0; i < this.particles.length; i++) {
      const particle = this.particles[i];
      context.beginPath();
      context.fillStyle = particle.color;
      context.arc(particle.x, particle.y, 2, 0, Math.PI * 2, false);
      context.fill();
    }
  }
}

function animate() {
  requestAnimationFrame(animate);
  context.clearRect(0, 0, window.innerWidth, window.innerHeight);

  rocket.move();
  rocket.draw();
  rocket.checkPosition();

  if (rocket.exploded) {
    for (let i = 0; i < rocket.explosions.length; i++) {
      rocket.explosions[i].update();
      rocket.explosions[i].draw();
    }
  }
}

const rocket = new Rocket(0, window.innerHeight - 50, 50, 50, 2, -5);

animate();

这段代码会创建一个Rocket对象,并让它在页面上飞行。当Rocket对象到达指定位置时,会随机生成10个烟花对象。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript实现烟花绽放动画效果 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • js针对图片加载失败的处理方法分析

    “js针对图片加载失败的处理方法分析”是前端开发中常见的问题之一。下面我会为大家详细讲解一下如何处理图片加载失败的情况。具体攻略分为以下几步: 1. 在HTML中添加图像元素 我们可以在HTML中通过添加<img>元素来加载图片,通常的写法为: <img src="图片地址" alt="图片描述"&g…

    JavaScript 2023年5月28日
    00
  • JS中对数组元素进行增删改移的方法总结

    下面是JS中对数组元素进行增删改移的方法总结的完整攻略: 一、添加元素 1. push() push() 方法向数组的末尾添加一个或多个元素,并返回新的长度。 let arr = [1, 2, 3]; arr.push(4); console.log(arr); // [1, 2, 3, 4] 2. unshift() unshift() 方法向数组的开头添…

    JavaScript 2023年5月27日
    00
  • JS中使用apply方法通过不同数量的参数调用函数的方法

    JS中的apply方法用于调用函数,并使用指定的参数数组。它是一个方法,可以在任何函数上使用。apply方法的第一个参数是由函数运行的上下文;this指针指向该对象。apply方法的第二个参数是一个数组,代表传递给调用函数的参数。apply方法不能在调用”use strict”的函数上使用,因为在严格模式下,调用一个null或undefined值的函数的th…

    JavaScript 2023年6月10日
    00
  • js 弹出框只弹一次(二次修改之后的)

    下面是“js 弹出框只弹一次(二次修改之后的)”的完整攻略: 1. 先分析问题 在实现弹出框只弹一次之前,我们需要先分析一下问题出在哪里。可能是因为弹框的逻辑写在了循环体内,导致每次循环都会弹出一个弹框,也有可能是因为没有设置弹框只弹一次的标记,导致每次都会弹出弹框。 2. 解决方案 2.1 将弹框逻辑放到循环体外面 let flag = true; for…

    JavaScript 2023年6月11日
    00
  • 用json方式实现在 js 中建立一个map

    在 Javascript 中建立一个 Map,在较早版本的 Javascript 中是无法直接实现的,但我们可以使用 JSON 格式实现一个类似 Map 的数据结构。 具体实现过程: 首先定义一个 JSON 对象来表示 Map,将每个键值对当作 JSON 对象的一个属性,键作为属性名,值作为属性值。例如,要建立一个键为 “key1″,值为 1 的 Map: …

    JavaScript 2023年5月27日
    00
  • javascript代码简写的几种常用方式汇总

    JavaScript代码简写的几种常用方式汇总 本文将介绍 JavaScript 代码简写的几种常用方式,并提供示例说明。 1. 箭头函数 箭头函数是 ES6 中的新特性,可以将函数的定义简写为一个箭头符号(=>)后面跟着表达式的形式,可以很方便地编写简短的函数。 示例: // 传统写法 function add(a, b) { return a + …

    JavaScript 2023年5月18日
    00
  • canvas压缩图片转换成base64格式输出文件流

    下面是使用canvas压缩图片并转换为base64格式输出文件流的完整攻略: 步骤一:html文件部分 首先,我们需要在html文件中添加一个input元素,用于选择要上传的图片。代码如下: <label for="image_upload">选择图片:</label> <input type="f…

    JavaScript 2023年5月19日
    00
  • JavaScript中判断为整数的多种方式及保留两位小数的方法

    JavaScript中判断为整数的多种方式及保留两位小数的方法 判断为整数的多种方式 在JavaScript中,判断一个数是否为整数是经常需要用到的操作。下面列出了常见的几种方法: 取模运算 利用数学中取模运算的特性,即整数x对于任意不等于0的正整数y,x%y的结果只可能是0到y-1之间的整数,如果x % 1等于0,则说明它为整数。具体代码如下: funct…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部