利用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日

相关文章

  • JavaScript使用setInterval()函数实现简单轮询操作的方法

    下面是JavaScript使用setInterval()函数实现简单轮询操作的方法的详细攻略。 什么是轮询? 轮询是指在一定时间间隔内不断查询某个状态的变化情况,以便及时的获取最新的状态信息。在Web开发中,轮询通常用于不断更新页面上的数据,例如:社交网络、股票行情等。 在JavaScript中,我们可以使用setInterval()函数来实现轮询功能。 s…

    JavaScript 2023年6月11日
    00
  • 详解JavaScript逻辑And运算符

    详解JavaScript逻辑And运算符 什么是And运算符? And运算符,也叫逻辑与运算符,是JavaScript中的一种逻辑运算符。当两个操作数都为真(truthy)时,And运算符返回真;否则返回假(false)。 And运算符的使用 语法格式为: expression1 && expression2 其中,expression1和e…

    JavaScript 2023年5月28日
    00
  • ES6新语法Object.freeze和Object.seal基本使用

    下面是关于ES6新语法Object.freeze和Object.seal的详细讲解。 Object.freeze和Object.seal简介 ES6新语法Object.freeze和Object.seal是JavaScript语言提供的限制对象属性和方法修改的方法之一。可以让我们创建一个不可改变的对象,并且可以确保对象不被意外修改。Object.freeze…

    JavaScript 2023年6月11日
    00
  • Document.location.href和.replace的区别示例介绍

    Document.location.href和.replace是JavaScript中经常用到的两个方法,它们的作用都是跳转页面,但其实存在着一些区别。接下来我将详细讲解这两个方法的区别,并且分别给出两个示例来说明。 Document.location.href和.replace的区别 Document.location.href 使用Document.lo…

    JavaScript 2023年6月11日
    00
  • 深入理解Ajax的get和post请求

    关于深入理解Ajax的get和post请求,下面是我分享的完整攻略。 理解Ajax 什么是Ajax? Ajax是“Asynchronous JavaScript And XML”的缩写,意思是“异步JavaScript和XML”。 简单来说,Ajax使得Web应用程序可以在不重新加载页面的情况下进行异步通信。 这意味着您可以使用JavaScript向服务器发…

    JavaScript 2023年6月11日
    00
  • JavaScript 程序编码规范

    当编写 JavaScript 代码的时候,良好的编码规范可以提高代码的可读性、减少错误和加快开发速度。本文将详细讲解 JavaScript 程序编码规范的完整攻略。 格式化 JavaScript 程序编码规范中,始终应该遵守一致的代码格式。在不同编码风格之间切换可能会导致不必要的错误,因此在一个团队中必须制定专属的约定。以下是常用的格式化规范: 缩进 Jav…

    JavaScript 2023年5月19日
    00
  • JavaScript你不知道的一些数组方法

    下面是详细讲解“JavaScript你不知道的一些数组方法”的完整攻略。 一、前言 JavaScript 中数组是非常常用的数据结构,JS 对数组的操作也非常丰富。其中一些方法在日常的开发中比较常见,比如push、pop、shift和unshift等等,但是还有一些方法很少被知道或使用,这些方法不仅可以提高效率,还可以让代码更加优美。 本篇攻略主要介绍 Ja…

    JavaScript 2023年5月27日
    00
  • JavaScript函数防抖动debounce

    JavaScript函数防抖动Debounce是一种常用的前端性能优化方式,可以有效地减少频繁触发函数导致的性能问题。下面,我将详细讲解JavaScript函数防抖动Debounce的攻略,包括什么是函数防抖动、如何实现函数防抖动,以及函数防抖动的使用场景。 什么是函数防抖动? 在前端开发中,经常需要对页面元素进行事件绑定,例如监听窗口滚动事件、监听搜索框输…

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