经常在一些网页上看到这样效果,移动的粒子,动态的连线,跟随鼠标。
下面我们可以通过p5.js来实现这个效果。并实现鼠标与粒子之间的交互效果。
在代码中每个粒子都具有随机的位置、大小、速度和颜色,并可以与其他粒子之间进行连接。
js
// 定义粒子类
class Particle {
constructor() {
// 随机生成粒子的位置和大小
this.x = random(0, width);
this.y = random(0, height);
this.r = random(1, 8);
// 随机生成粒子的速度
this.xSpeed = random(-2, 2);
this.ySpeed = random(-1, 1.5);
}
// 画粒子
createParticle() {
noStroke();
fill('rgba(200,169,169,0.5)');
circle(this.x, this.y, this.r);
}
// 移动粒子
moveParticle() {
// 判断粒子是否碰到了边界,如果是,则反弹
if (this.x < 0 || this.x > width)
this.xSpeed *= -1;
if (this.y < 0 || this.y > height)
this.ySpeed *= -1;
this.x += this.xSpeed;
this.y += this.ySpeed;
}
// 连接粒子
joinParticles(particles) {
particles.forEach((element,i) => {
let dis = dist(this.x, this.y, element.x, element.y);
// 如果是第一个粒子,则连接距离为 140 像素,线条颜色为鼠标的位置和宽度
if(this.id == 0){
if (dis < 140) {
stroke(mouseX,width,100);
line(this.x, this.y, element.x, element.y);
}
}else{
// 如果不是第一个粒子,则连接距离为 70 像素,线条颜色为白色
if (dis < 70) {
stroke('rgba(255,255,255,0.1)');
line(this.x, this.y, element.x, element.y);
}
}
});
}
}
// 创建粒子数组
let particles = [];
function setup() {
// 创建画布
createCanvas(windowWidth, 300);
// 设置颜色模式
colorMode(HSB, width, height, 100);
// 随机生成粒子并添加到数组中
for (let i = 0; i < width / 5; i++) {
particles.push(new Particle());
}
// 将第一个粒子的速度设置为 0,大小设置为 10,id 设置为 0
particles[0].xSpeed = 0;
particles[0].ySpeed = 0;
particles[0].r = 10
particles[0].id = 0;
}
function draw() {
// 绘制背景
background('#0f0f0f');
// 遍历所有的粒子
for (let i = 0; i < particles.length; i++) {
// 画粒子
particles[i].createParticle();
// 移动粒子
particles[i].moveParticle();
// 连接粒子
particles[i].joinParticles(particles.slice(i));
}
// 将第一个粒子的位置设置为鼠标位置
particles[0].x = mouseX;
particles[0].y = mouseY;
}
这个代码主要分为两个部分,一个是粒子类 Particle
,一个是 setup()
和 draw()
函数。
在 Particle
类中,我们定义了三个方法:
-
constructor()
方法:在创建粒子对象时,随机生成粒子的位置、大小和速度。 -
createParticle()
方法:用于画出粒子,使用circle()
函数画出圆形粒子。 -
joinParticles()
方法:用于连接粒子,遍历所有的粒子对象,计算每个粒子之间的距离,如果距离小于设定的连接距离,则使用line()
函数画出粒子之间的连线。
在 setup()
函数中,我们完成了以下工作:
-
创建画布。
-
设置颜色模式。
-
随机生成粒子并添加到粒子数组中。
-
将第一个粒子的速度设置为 0,大小设置为 10,id 设置为 0。
在 draw()
函数中,我们完成了以下工作:
-
绘制背景。
-
遍历所有的粒子,依次画出每个粒子,移动每个粒子,并连接每个粒子。
-
将第一个粒子的位置设置为鼠标位置,实现了鼠标与粒子之间的交互效果。
在这个粒子系统中,我们主要使用了以下技术:
-
面向对象编程:我们使用 ES6 中的类来创建
Particle
类,将粒子的属性和方法封装在一个类中,使粒子对象更加可维护和可扩展。 -
Canvas 绘图:我们使用 p5.js 库提供的
createCanvas()
函数来创建画布,并使用circle()
和line()
函数来画圆和线条。 -
随机数生成:我们使用 p5.js 库提供的
random()
函数来生成随机的粒子位置、大小、速度和颜色。 -
鼠标交互:我们使用
mouseX
和mouseY
变量来获取鼠标的位置,并将第一个粒子的位置设置为鼠标位置,实现了鼠标与粒子之间的交互效果。
扩展:
-
可以通过增加粒子之间的连接距离和粒子之间的连线宽度,来改变粒子系统的外观和行为。
-
可以使用更复杂的算法来计算粒子之间的连接关系,例如使用 k-means 或者 DBSCAN 等算法来聚类粒子,然后在同一类中的粒子之间进行连接。
-
可以使用更多的交互效果来增强用户体验,例如在鼠标移动时,让粒子系统产生更复杂的运动轨迹,或者使用鼠标点击事件来切换不同的粒子系统。