js canvas实现随机粒子特效

下面我来详细讲解一下“js canvas实现随机粒子特效”的完整攻略。

1. 前言

在介绍如何使用canvas实现随机粒子特效之前,我们需要了解几个基本的概念。

  • HTML5 Canvas:HTML5中的一个重要新特性,允许直接在浏览器中使用JavaScript绘制2D图形。
  • requestAnimationFrame:在浏览器重绘之前执行指定的函数,以使动画效果更加平滑流畅。
  • 粒子系统:一种用于模拟物体运动的技术,可以用来创建各种不同的动态效果,如烟雾、火焰、雨滴等。

了解以上基本概念之后,我们就可以开始使用canvas创建随机粒子特效了。

2. 创建Canvas画布

首先,我们需要在HTML中创建一个canvas标签,用来作为我们绘制粒子系统的画布。

<canvas id="myCanvas"></canvas>

接着,在JavaScript中获取到该canvas元素,并为其设置画布的宽高。

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

3. 创建粒子对象

接下来,我们需要创建一个Particle对象,用来代表粒子的属性和行为。

class Particle {
  constructor(x, y, radius, color, speed) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speed = speed;
    this.direction = Math.random() * Math.PI * 2;
  }

  move() {
    this.x += Math.cos(this.direction) * this.speed;
    this.y += Math.sin(this.direction) * this.speed;
  }
}

Particle对象的构造函数中,我们传入了粒子的初始位置、半径、颜色和移动速度,同时生成一个随机运动方向。

然后,在Particle对象中添加一个move方法,用于更新粒子的位置。

4. 绘制粒子系统

现在,我们可以开始在画布上绘制我们的粒子系统了。

首先,我们需要创建一个数组,用于存放所有的粒子对象。

const particles = [];

然后,我们需要编写一个函数,用于在画布上绘制所有的粒子。

function drawParticles() {
  // 清空画布
  context.clearRect(0, 0, canvas.width, canvas.height);

  // 遍历粒子数组,绘制每一个粒子
  particles.forEach(particle => {
    context.beginPath();
    context.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2, false);
    context.fillStyle = particle.color;
    context.fill();
    context.closePath();
  });
}

该函数中,我们首先使用clearRect方法清空画布,避免上一次绘制的粒子残留在画布上。

然后,遍历所有粒子对象,使用arc方法绘制一个圆形,并设置其颜色。最后,使用fill方法填充该圆形,完成绘制。

5. 动画效果

到这一步,我们已经完成了粒子系统的绘制,但是粒子并不会动起来。下面,我们需要实现一个动画效果,使粒子随机运动起来。

function animate() {
  // 使用requestAnimationFrame方法循环调用animate函数
  requestAnimationFrame(animate);

  // 遍历所有粒子对象,更新其位置
  particles.forEach(particle => {
    particle.move();

    // 如果粒子位置超出画布范围,则将其放回画布内部
    if (particle.x < 0 || particle.x > canvas.width || particle.y < 0 || particle.y > canvas.height) {
      particle.x = Math.random() * canvas.width;
      particle.y = Math.random() * canvas.height;
    }
  });

  // 绘制所有粒子
  drawParticles();
}

animate函数中,我们首先使用requestAnimationFrame方法循环调用自身。然后,遍历所有粒子对象,并执行其move方法进行位置更新。在更新粒子位置之后,我们需要判断粒子是否超出了画布范围,如果是则将其重新放回画布内部。

最后,使用drawParticles函数绘制所有的粒子。

6. 示例说明

下面,我将介绍两个使用canvas实现的随机粒子特效的示例。

示例一:彩色粒子

这个示例中,我们将以随机颜色绘制彩色粒子,并让它们不断在画布内部随机运动。

const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

class Particle {
  constructor(x, y, radius, color, speed) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speed = speed;
    this.direction = Math.random() * Math.PI * 2;
  }

  move() {
    this.x += Math.cos(this.direction) * this.speed;
    this.y += Math.sin(this.direction) * this.speed;
  }
}

const particles = [];

for (let i = 0; i < 100; i++) {
  const particle = new Particle(
    Math.random() * canvas.width,   // x坐标
    Math.random() * canvas.height,  // y坐标
    Math.random() * 5 + 5,          // 半径
    `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`, // 随机颜色
    2                              // 移动速度
  );

  particles.push(particle);
}

function drawParticles() {
  context.clearRect(0, 0, canvas.width, canvas.height);

  particles.forEach(particle => {
    context.beginPath();
    context.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2, false);
    context.fillStyle = particle.color;
    context.fill();
    context.closePath();
  });
}

function animate() {
  requestAnimationFrame(animate);

  particles.forEach(particle => {
    particle.move();

    if (particle.x < 0 || particle.x > canvas.width || particle.y < 0 || particle.y > canvas.height) {
      particle.x = Math.random() * canvas.width;
      particle.y = Math.random() * canvas.height;
    }
  });

  drawParticles();
}

animate();

示例二:粒子互动效果

这个示例中,我们将为粒子之间添加互动效果,让它们在一定范围内相互吸引,并形成一个动态的“星空”效果。

const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

class Particle {
  constructor(x, y, radius, color, speed) {
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speed = speed;
    this.direction = Math.random() * Math.PI * 2;
  }

  move() {
    this.x += Math.cos(this.direction) * this.speed;
    this.y += Math.sin(this.direction) * this.speed;
  }

  interact(particles) {
    // 遍历所有粒子,计算与当前粒子的距离
    particles.forEach(particle => {
      const distance = Math.sqrt((this.x - particle.x) ** 2 + (this.y - particle.y) ** 2);

      // 当距离小于一定范围时,相互吸引
      if (distance < 100) {
        const lineWidth = (100 - distance) / 20;
        context.beginPath();
        context.lineWidth = lineWidth;
        context.moveTo(this.x, this.y);
        context.lineTo(particle.x, particle.y);
        context.strokeStyle = '#ffffff';
        context.stroke();
        context.closePath();

        const dx = particle.x - this.x;
        const dy = particle.y - this.y;
        const angle = Math.atan2(dy, dx);

        this.direction += angle / 100;
        particle.direction -= angle / 100;
      }
    });
  }
}

const particles = [];

for (let i = 0; i < 50; i++) {
  const particle = new Particle(
    Math.random() * canvas.width,   // x坐标
    Math.random() * canvas.height,  // y坐标
    Math.random() * 2 + 1,          // 半径
    '#ffffff',                      // 颜色
    Math.random() * 2 + 1           // 移动速度
  );

  particles.push(particle);
}

function drawParticles() {
  context.clearRect(0, 0, canvas.width, canvas.height);

  // 对每个粒子进行互动计算
  particles.forEach(particle => {
    particle.interact(particles);
  });

  // 绘制所有粒子
  particles.forEach(particle => {
    context.beginPath();
    context.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2, false);
    context.fillStyle = particle.color;
    context.fill();
    context.closePath();
  });
}

function animate() {
  requestAnimationFrame(animate);

  particles.forEach(particle => {
    particle.move();

    if (particle.x < 0 || particle.x > canvas.width || particle.y < 0 || particle.y > canvas.height) {
      particle.x = Math.random() * canvas.width;
      particle.y = Math.random() * canvas.height;
    }
  });

  drawParticles();
}

animate();

在这个示例中,我们首先为每个粒子对象添加了一个interact方法,用于计算与其他粒子的距离,并实现相互间的吸引效果。

然后,我们在drawParticles函数中,调用每个粒子对象的interact方法,并且在粒子间绘制了白色的线条。这样,当两个粒子距离较近时就可以呈现出互动效果。

最后,加入了requestAnimationFrame来实现动画效果。

总之,以上便是“js canvas实现随机粒子特效”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js canvas实现随机粒子特效 - Python技术站

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

相关文章

  • 微信小程序 时间格式化(util.formatTime(new Date))详解

    为了实现微信小程序的时间格式化,我们可以使用util.formatTime()函数。这个函数将一个Date对象转换为对应的字符串形式,具体格式化方式由传入的参数进行控制。 以下是“微信小程序 时间格式化(util.formatTime(new Date))详解”攻略的详细实现过程: 1. 引入util模块 在微信小程序中使用util模块需要先引入该模块,使用…

    JavaScript 2023年5月27日
    00
  • 微信小程序:数据存储、传值、取值详解

    微信小程序:数据存储、传值、取值详解 一、数据存储 微信小程序中数据存储可分为两部分,一部分是本地存储,即存储在用户的本地缓存中,另一部分是云存储,即存储在微信开发者工具提供的云服务器中。 1. 本地存储 本地存储使用wx.setStorage和wx.getStorage进行数据的存储和获取。 1.1 存储数据 使用wx.setStorage函数可以将数据存…

    JavaScript 2023年6月11日
    00
  • JS公共小方法之判断对象是否为domElement的实例

    接下来我将为大家详细讲解JS公共小方法之判断对象是否为domElement的实例的完整攻略,包含以下几个部分: 介绍如何判断对象是否为domElement的实例 提供两条示例说明 总结 1. 判断对象是否为domElement的实例 在JavaScript中,有时候我们需要判断一个对象是否为DOM元素的实例。这是因为DOM元素是一种独特类型的对象,它们是浏览…

    JavaScript 2023年6月10日
    00
  • JS数组array元素的添加和删除方法代码实例

    下面我将为你详细讲解“JS数组array元素的添加和删除方法代码实例”的完整攻略。 一、数组元素的添加 1. push()方法 push() 方法可以在数组的末尾添加一个或多个元素,并返回该数组的新长度。语法如下: array.push(element1, element2, …, elementN) 示例: let arr = [1, 2, 3]; a…

    JavaScript 2023年5月27日
    00
  • javascript遍历json对象的key和任意js对象属性实例

    我们来详细讲解JavaScript如何遍历JSON对象的key和任意JS对象属性实例。 遍历JSON对象的key 在JavaScript中,我们可以使用for-in循环来遍历JSON对象的key。示例如下: const obj = {name: ‘张三’, age: 20, gender: ‘男’}; for (let key in obj) { conso…

    JavaScript 2023年5月27日
    00
  • 使用jquery的cookie实现登录页记住用户名和密码的方法

    使用jQuery的cookie插件可以方便地实现记住用户名和密码功能。接下来,我将为您提供完整的攻略,以实现此功能。 在HTML中添加相关代码 首先,在登录页面的表单中添加两个复选框,一个用于记住用户名,一个用于记住密码。这些复选框应该具有唯一的ID,以便在jQuery中引用它们。 <label for="rememberUsername&q…

    JavaScript 2023年6月11日
    00
  • 超实用的javascript时间处理总结

    超实用的JavaScript时间处理总结 时间处理在前端开发中具有重要的作用,常常需要对时间进行格式化、比较、加减、转换等操作。此篇文章总结了JavaScript中对时间的常用操作,希望对大家的开发工作有所帮助。 获取当前时间 获取当前时间可以使用JavaScript内置的Date()方法,如下所示: const now = new Date(); 获取到的…

    JavaScript 2023年5月27日
    00
  • JS常用正则表达式及验证时间的正则表达式

    JS常用正则表达式及验证时间的正则表达式 一、常用正则表达式 1. 邮箱验证正则表达式 /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/ 该正则表达式验证邮箱是否合法,以多段分别用@和.连接。 [a-zA-Z0-9_-]+表示特殊字符_-、数字、大小写字母可以重复出现一次或多次。 (\.[a-zA-Z0…

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