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

相关文章

  • 常用JS加密编码算法代码第2/2页

    “常用JS加密编码算法代码第2/2页”是一篇介绍常用JS加密和编码算法的文章,其中包含了完整的代码示例。为了更好地理解和使用这些算法,可以按照以下步骤进行操作: 阅读文章,理解各种加密和编码算法的原理和用途。文章中提到了几种常用的算法,包括Base64编码、MD5加密、SHA1加密、AES加密等,在使用这些算法之前,需要先理解其基本原理。 下载代码示例,并在…

    JavaScript 2023年5月20日
    00
  • Dom 学习总结以及实例的使用介绍

    DOM 学习总结以及实例的使用介绍 DOM是什么? DOM(Document Object Model)即文档对象模型,是一种用于处理HTML或XML文档的标准编程接口。它将整个HTML或XML文档表示为一个树形结构,您可以使用DOM API来访问、操纵或更新各个部分。 DOM相关属性和方法 1. getElementById() 该方法返回一个具有指定 I…

    JavaScript 2023年6月10日
    00
  • Javascript生成器(Generator)的介绍与使用

    Javascript生成器(Generator)的介绍与使用 简介 Javascript生成器是一种特殊类型的函数,它允许我们暂停函数的执行并返回一个中间结果,稍后再继续执行并返回更多的中间结果。在实际应用中,生成器通常用于处理大量数据或者生成一系列的异步任务。 定义 我们可以使用函数声明或函数表达式来定义一个生成器。当定义一个生成器时,我们需要在函数名后面…

    JavaScript 2023年5月27日
    00
  • 面向对象的Javascript之三(封装和信息隐藏)

    我会详细讲解“面向对象的Javascript之三(封装和信息隐藏)”的完整攻略。 面向对象的Javascript之三(封装和信息隐藏) 什么是封装? 封装是一种面向对象的编程思想,通过将数据和对数据的操作(即方法)封装在一个对象内部,以实现对对象的控制和保护。 封装可以分为两个方面: 将数据隐藏在对象内部,以避免外部对数据的不当操作。 将方法隐藏在对象内部,…

    JavaScript 2023年6月10日
    00
  • javascript的正则匹配方法学习

    JavaScript的正则匹配方法学习 正则表达式是一种用于匹配字符串的模式,它在JavaScript中非常常见。在本文中,我们将介绍怎样在JavaScript中使用正则表达式进行字符串匹配。 1. 创建正则表达式 在JavaScript中,可以使用正则表达式字面量或RegExp对象来创建正则表达式。正则表达式字面量可以使用斜杠”/”包围,其中间为正则表达式…

    JavaScript 2023年6月10日
    00
  • JS中如何比较两个Json对象是否相等实例代码

    在JS中比较两个JSON对象是否相等,可以使用深度比较(deep comparison)算法。这是一种递归地比较对象的方式,直到找到两个属性的值不同为止。 以下是比较两个JSON对象的完整攻略: 步骤1:编写比较函数 以下是一个比较两个JSON对象的函数: function compareJSON(obj1, obj2) { // Check if both…

    JavaScript 2023年5月27日
    00
  • JS实现线性表的链式表示方法示例【经典数据结构】

    标题:JS实现线性表的链式表示方法示例【经典数据结构】 简介:本篇文章将讲解JavaScript实现线性表的链式存储结构的方法和示例。通过本文的学习,读者将会掌握线性表的链式存储结构和如何使用JavaScript来实现。 什么是线性表? 线性表是指数据元素之间存在一种线性关系的数据结构。线性表中的数据元素按照顺序排列,每个数据元素都只有一个前驱元素和一个后继…

    JavaScript 2023年5月28日
    00
  • JavaScript中常见的字符串操作函数及用法汇总

    JavaScript中常见的字符串操作函数及用法汇总 JavaScript中有很多字符串操作函数,这篇攻略将会讲解其中常见的一些函数及其用法。我们来详细了解一下吧。 字符串的创建 字符串可以通过两种方式创建,分别是双引号和单引号。 var str1 = "JavaScript"; // 使用双引号创建字符串 var str2 = ‘Jav…

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