chore: 更新项目配置并添加 p5.js 粒子演示
All checks were successful
/ build-and-deploy-to-vercel (push) Successful in 3m27s
/ surge (push) Successful in 2m54s
/ playwright (push) Successful in 1m3s
/ lint-build-and-check (push) Successful in 4m51s

This commit is contained in:
mini2024
2025-04-06 21:35:58 +08:00
parent aecfd22055
commit 9e8affc52d
10 changed files with 148 additions and 8 deletions

View File

@ -0,0 +1,122 @@
<script setup lang="ts">
import P5 from 'p5';
definePage({
meta: {
title: 'p5.js 粒子效果演示',
},
});
// 用于挂载 p5 canvas 的 DOM 元素的引用
const sketchContainer = ref<HTMLElement | null>(null);
// p5 实例
let instance: null | P5 = null;
// 定义粒子类
class Particle {
x: number;
y: number;
vx: number;
vy: number;
alpha: number;
lifespan: number;
p: P5; // p5 实例引用
constructor(p: P5, x: number, y: number) {
this.p = p;
this.x = x;
this.y = y;
// 随机速度
this.vx = p.random(-1, 1);
this.vy = p.random(-2, 0); // 倾向于向上移动
this.alpha = 255; // 初始透明度
this.lifespan = 255; // 生命周期,与透明度关联
}
// 更新粒子状态
update() {
this.x += this.vx;
this.y += this.vy;
this.lifespan -= 5; // 逐渐消失
this.alpha = this.lifespan;
}
// 绘制粒子
display() {
this.p.noStroke();
// 可以根据速度或生命周期改变颜色
this.p.fill(255, this.alpha); // 白色,逐渐透明
this.p.ellipse(this.x, this.y, 8, 8); // 绘制小圆点
}
// 检查粒子是否存活
isDead() {
return this.lifespan < 0;
}
}
// 粒子数组
const particles: Particle[] = [];
// p5 sketch 定义
const sketch = (p: P5) => {
// setup 函数只运行一次
p.setup = () => {
// 创建一个 600x400 像素的画布
p.createCanvas(600, 400);
p.background(51); // 设置深灰色背景
};
// draw 函数会持续循环执行
p.draw = () => {
p.background(51); // 每帧都重绘背景,以实现动画效果
// 在鼠标位置创建新粒子 (每帧创建 2 个)
for (let i = 0; i < 2; i++) {
particles.push(new Particle(p, p.mouseX, p.mouseY));
}
// 更新和显示所有粒子
// 从后向前遍历数组,这样可以在遍历过程中安全地删除元素
for (let i = particles.length - 1; i >= 0; i--) {
particles[i].update();
particles[i].display();
// 如果粒子生命周期结束,则从数组中移除
if (particles[i].isDead()) {
particles.splice(i, 1);
}
}
};
};
// 组件挂载后初始化 p5 实例
onMounted(() => {
if (sketchContainer.value) {
instance = new P5(sketch, sketchContainer.value);
}
});
// 组件卸载前移除 p5 实例,释放资源
onUnmounted(() => {
instance?.remove();
});
</script>
<template>
<div class="p-4">
<h1 class="text-2xl font-bold mb-4">p5.js 粒子效果演示</h1>
<div class="mb-4">
<h2 class="text-xl font-semibold mb-2">粒子系统</h2>
<p>
这是一个使用 p5.js 创建的简单粒子系统演示粒子会从鼠标指针的位置生成并向上漂浮然后逐渐消失 p5.js
使得创建这类动态和交互式的视觉效果变得相对容易
</p>
</div>
<h2 class="text-xl font-semibold mb-2">演示区域</h2>
<p class="mb-2">在下面的深灰色区域移动鼠标观察粒子效果</p>
<!-- p5 canvas 将会挂载到这个 div -->
<div ref="sketchContainer" class="border border-gray-400 inline-block"></div>
</div>
</template>