利用JavaScript实现绘制2023新年烟花的示例代码

下面是在网页中利用JavaScript实现绘制2023新年烟花的完整攻略。

准备工作

在开始编写代码之前,我们需要准备以下工具和环境:

  • 一个文本编辑器,推荐使用 Visual Studio Code
  • 一个浏览器,推荐使用 Chrome
  • 一些基础的 JavaScript 知识,例如函数、变量、事件等

编写HTML结构

首先,我们需要在HTML文件中添加一个canvas标签,并设置宽高,代码如下:

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

添加样式

为了让烟花能够在页面中居中并占据整个窗口,我们需要为 canvas 标签添加一些样式:

canvas {
  display: block;
  margin: auto;
}

编写 JavaScript 代码

接下来,我们就可以编写 JavaScript 代码来实现绘制烟花的功能了。

创建画布

我们需要创建一个画布,获取画布对象,并将其设置为全屏,并且设置画布的宽高为窗口的宽高,不过需要注意, HTML元素的宽高如果通过css设置,那么实际上元素的宽高仍旧是计算机能识别的默认值:

const canvas = document.getElementById('fireworks');
const ctx = canvas.getContext('2d');

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

创建 Firework

创建一个 Firework 对象,用于描述烟花的基本属性,例如位置、颜色、运动轨迹等,代码如下:

class Firework {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
    this.target = {
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.height
    }
    this.speed = 10;
    this.angle = Math.atan2(this.target.y - this.y, this.target.x - this.x);
    this.gravity = 0.2;
    this.vx = Math.cos(this.angle) * this.speed;
    this.vy = Math.sin(this.angle) * this.speed;
    this.opacity = 1;
    this.trail = [];
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, 5, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.fill();

    // Draw trail
    ctx.globalAlpha = this.opacity;
    for (let i = 0; i < this.trail.length; i++) {
      ctx.beginPath();
      ctx.arc(this.trail[i].x, this.trail[i].y, i * Math.random() * 2, 0, Math.PI * 2);
      ctx.fillStyle = this.color;
      ctx.fill();
    }
  }

  update() {
    // Update position
    this.x += this.vx;
    this.y += this.vy;

    // Update velocity
    this.vy += this.gravity;

    // Update opacity
    this.opacity -= 0.1;

    // Update trail
    this.trail.push({x: this.x, y: this.y});
    if (this.trail.length > 10) {
      this.trail.shift();
    }
  }
}

创建 Explosion

创建一个 Explosion 对象,用于描述烟花爆炸的基本属性,例如位置、颜色、大小等,代码如下:

class Explosion {
  constructor(x, y, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.particles = [];

    for (let i = 0; i < 30; i++) {
      this.particles.push(new Particle(this.x, this.y, this.color));
    }
  }

  draw() {
    for (let i = 0; i < this.particles.length; i++) {
      this.particles[i].draw();
    }
  }

  update() {
    for (let i = 0; i < this.particles.length; i++) {
      this.particles[i].update();
    }
  }
}

创建 Particle

创建一个 Particle 对象,用于描述烟花中的粒子,例如位置、大小、速度等,代码如下:

class Particle {
  constructor(x, y, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.vx = Math.random() * 10 - 5;
    this.vy = Math.random() * 10 - 5;
    this.size = Math.random() * 3;
    this.gravity = 0.2;
    this.opacity = 1;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
    ctx.fillStyle = this.color;
    ctx.fill();
  }

  update() {
    this.x += this.vx;
    this.y += this.vy;
    this.vy += this.gravity;
    this.opacity -= 0.05;
    this.size -= 0.05;
  }
}

创建动画

现在,我们需要创建一个动画,用于在画布上不断绘制烟花,代码如下:

let fireworks = [];

function loop() {
  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Draw fireworks
  for (let i = 0; i < fireworks.length; i++) {
    fireworks[i].draw();
    fireworks[i].update();

    // Explode when reach the target
    if (fireworks[i].y - fireworks[i].target.y > 0) {
      let explosion = new Explosion(fireworks[i].x, fireworks[i].y, fireworks[i].color);
      fireworks.splice(i, 1);
      i--;
      for (let j = 0; j < 10; j++) {
        fireworks.push(new Firework(explosion.x, explosion.y));
      }
    }
  }

  // Generate new firework
  if (Math.random() < 0.2) {
    fireworks.push(new Firework(canvas.width/2, canvas.height));
  }

  requestAnimationFrame(loop);
}

loop();

完整代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>2023 New Year Fireworks</title>
  <style>
    canvas {
      display: block;
      margin: auto;
    }
  </style>
</head>
<body>
  <canvas id="fireworks"></canvas>
  <script>
    const canvas = document.getElementById('fireworks');
    const ctx = canvas.getContext('2d');

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    class Firework {
      constructor(x, y) {
        this.x = x;
        this.y = y;
        this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
        this.target = {
          x: Math.random() * canvas.width,
          y: Math.random() * canvas.height
        }
        this.speed = 10;
        this.angle = Math.atan2(this.target.y - this.y, this.target.x - this.x);
        this.gravity = 0.2;
        this.vx = Math.cos(this.angle) * this.speed;
        this.vy = Math.sin(this.angle) * this.speed;
        this.opacity = 1;
        this.trail = [];
      }

      draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, 5, 0, Math.PI * 2);
        ctx.fillStyle = this.color;
        ctx.fill();

        // Draw trail
        ctx.globalAlpha = this.opacity;
        for (let i = 0; i < this.trail.length; i++) {
          ctx.beginPath();
          ctx.arc(this.trail[i].x, this.trail[i].y, i * Math.random() * 2, 0, Math.PI * 2);
          ctx.fillStyle = this.color;
          ctx.fill();
        }
      }

      update() {
        // Update position
        this.x += this.vx;
        this.y += this.vy;

        // Update velocity
        this.vy += this.gravity;

        // Update opacity
        this.opacity -= 0.1;

        // Update trail
        this.trail.push({x: this.x, y: this.y});
        if (this.trail.length > 10) {
          this.trail.shift();
        }
      }
    }

    class Explosion {
      constructor(x, y, color) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.particles = [];

        for (let i = 0; i < 30; i++) {
          this.particles.push(new Particle(this.x, this.y, this.color));
        }
      }

      draw() {
        for (let i = 0; i < this.particles.length; i++) {
          this.particles[i].draw();
        }
      }

      update() {
        for (let i = 0; i < this.particles.length; i++) {
          this.particles[i].update();
        }
      }
    }

    class Particle {
      constructor(x, y, color) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.vx = Math.random() * 10 - 5;
        this.vy = Math.random() * 10 - 5;
        this.size = Math.random() * 3;
        this.gravity = 0.2;
        this.opacity = 1;
      }

      draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        ctx.fillStyle = this.color;
        ctx.fill();
      }

      update() {
        this.x += this.vx;
        this.y += this.vy;
        this.vy += this.gravity;
        this.opacity -= 0.05;
        this.size -= 0.05;
      }
    }

    let fireworks = [];

    function loop() {
      // Clear canvas
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Draw fireworks
      for (let i = 0; i < fireworks.length; i++) {
        fireworks[i].draw();
        fireworks[i].update();

        // Explode when reach the target
        if (fireworks[i].y - fireworks[i].target.y > 0) {
          let explosion = new Explosion(fireworks[i].x, fireworks[i].y, fireworks[i].color);
          fireworks.splice(i, 1);
          i--;
          for (let j = 0; j < 10; j++) {
            fireworks.push(new Firework(explosion.x, explosion.y));
          }
        }
      }

      // Generate new firework
      if (Math.random() < 0.2) {
        fireworks.push(new Firework(canvas.width/2, canvas.height));
      }

      requestAnimationFrame(loop);
    }

    loop();
  </script>
</body>
</html>

这样,当我们在浏览器中打开该 HTML 文件时,就能看到一个基于 JavaScript 实现的烟花动画效果了。

示例说明

  1. 修改烟花绘制的速度:将代码中的 speed 值调大或调小即可,例如将 speed 调整为 5,表示烟花的速度变慢了,可以让动画变得更加缓慢。

  2. 修改烟花交互方式:在 Demo 中实现的是以随机方式自动弹出一些烟火, 如果希望增加交互性,可以在页面上添加按钮等交互元素,当用户点击按钮时,触发 JavaScript 代码,从而实现相应的动画效果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:利用JavaScript实现绘制2023新年烟花的示例代码 - Python技术站

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

相关文章

  • 详解如何将 Vue-cli 改造成支持多页面的 history 模式

    下面是如何将 Vue-cli 改造成支持多页面的 history 模式的攻略。具体步骤如下: 一、创建多页面应用 首先需要在 Vue-cli 中创建多页面应用。在 src 目录下新建多个 .html 文件,比如 index.html、about.html 等。在 src 目录下还需要新建多个 .js 文件,比如 index.js、about.js 等,这些 …

    JavaScript 2023年6月11日
    00
  • 使用JavaScript获取URL中的参数(两种方法)

    当我们需要从URL中获取特定的参数时,JavaScript是一个非常方便的工具。在JavaScript中,我们可以使用两种方法来获取URL中的参数: 方法一:使用正则表达式 JavaScript中的RegExp对象可用于匹配字符串中的模式。我们可以定义一个正则表达式来匹配URL中的参数,然后从匹配结果中提取出我们需要的参数。 以下是我们可以使用的正则表达式:…

    JavaScript 2023年6月10日
    00
  • JS Array.slice 截取数组的实现方法

    JS Array.slice截取数组常用于从数组中获取一部分数组元素。以下是完整的攻略,包括:定义、参数、返回值、示例说明、应用场景等。 定义 Array.slice是数组的一个方法,用于截取数组的一部分,返回截取后的新数组,而不会修改原数组。 语法 array.slice(start, end) 参数 start:要截取的开始下标,从0开始。 end:要截…

    JavaScript 2023年5月27日
    00
  • JavaScript中的事件循环方式

    JavaScript中的事件循环方式是Web开发中非常重要的一个概念。它决定了JavaScript的执行顺序,是理解异步编程和Promise的重要起点。在本文中,我将逐步介绍JavaScript的事件循环机制。 什么是事件循环 事件循环指的是JavaScript引擎在空闲时,从消息队列中取出一条消息进行处理的过程。在JavaScript中,事件可以是异步操作…

    JavaScript 2023年5月28日
    00
  • 彻底弄懂 JavaScript 执行机制

    彻底弄懂 JavaScript 执行机制 JavaScript 的执行环境 JavaScript 代码的执行必须依赖一个执行环境,该执行环境可以是浏览器、 Node.js 服务器或其它解释器等等,而这些执行环境会为 JavaScript 提供几乎相同的对象和方法,但是在细节上或许会略有不同。 JavaScript 的执行过程 JavaScript 的执行过程…

    JavaScript 2023年5月28日
    00
  • vue element el-form 多级嵌套验证的实现示例

    针对“vue element el-form 多级嵌套验证的实现示例”的完整攻略,我给您提供以下步骤: 步骤一:配置element-ui 首先需要在项目中引入Element-UI组件库,并按照文档要求进行全局和局部组件的注册,具体步骤可以参考官方文档:https://element.eleme.cn/#/zh-CN/component/installatio…

    JavaScript 2023年6月10日
    00
  • JS前端加密算法示例

    下面是JS前端加密算法示例的完整攻略。 什么是前端加密算法? 前端加密算法指的是在客户端对数据进行加密,使得数据在传输过程中更加安全,保障数据的完整性和机密性。前端加密算法通常被应用于用户登录验证和数据传输等方面。 常用的前端加密算法 1. Base64加密 Base64是一种可逆的加密算法,可以将任意类型的数据转换成可读的字符串。常被用于在网页上传输图片、…

    JavaScript 2023年5月19日
    00
  • js实现拖动缓动效果

    实现拖动缓动效果,需要用到JavaScript中的定时器和数学运算等技术。下面我来详细讲解一下整个过程。 第一步:获取元素位置 首先,我们需要获取需要拖动的元素以及它的位置。在代码中,我们通常会使用getBoundingClientRect()方法来获取元素的绝对位置。 const dragElem = document.querySelector(‘.dr…

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