讓你的作品集「活」起來:日式互動粒子背景拆解
很多設計系同學在做作品集網頁時,最頭痛的就是「首頁太死板」。想要一點互動感,但看到程式碼就頭大。
其實,要做出像 TeamLab 那種「有靈魂」的視覺效果,不需要成為工程師,你只需要掌握「粒子系統」這個簡單的邏輯。
今天我想分享如何用 p5.js 做出一個具有日式美學(低飽和、流動感、留白)的互動背景。
🎨 作品拆解:視覺語言的定義
在動手寫 code 之前,我們先把視覺拆解成設計語言。這篇文章追求的不是「科技感」,而是「禪意」。
-
色彩 (Color):
- 背景:使用
#F5F5F0(淡淡的和紙白),避免純白導致的視覺疲勞。 - 粒子:主色用
#2C2C2C(墨黑),點綴色用#E57373(淡櫻紅)。
- 背景:使用
-
動態 (Motion):
- 粒子不應該直線移動,而應該像在水中漂浮。我們使用
noise()函數來達成這種「有機」的流動感。
- 粒子不應該直線移動,而應該像在水中漂浮。我們使用
-
互動 (Interaction):
- 當滑鼠靠近時,粒子不應該直接消失,而是像被溫柔地「推開」。
🛠️ 跟著做:三個階段完成互動視覺
你可以直接將下方的【完整版程式碼】貼進 p5.js Web Editor 立即看到結果,但建議分三個階段來理解它是如何被「疊加」出來的。
階段一:在畫布上種下「粒子」
想像每顆粒子就像一片浮在水面的紙屑。它需要記住自己現在在哪裡(位置),以及接下來要往哪裡飄(速度)。
在程式碼中,我們用 class Particle 來定義這片紙屑的「屬性」。
視覺結果:你會在畫布上看到一群隨機分佈的小圓點,像靜止的星空。
階段二:賦予粒子「生命」(流動感)
要讓粒子像在水中漂浮而非機械抖動,我們使用 noise()。它會產生一種平滑的隨機值,讓粒子在移動時有自然的弧度。
視覺結果:圓點開始輕微地、有機地漂動,畫面產生了一種「呼吸感」。
階段三:建立與使用者的「連結」(滑鼠互動)
最神奇的地方在於:我們計算粒子與滑鼠的距離。如果滑鼠太靠近,就給粒子一個「逃離」的力,把它們溫柔地推開。
視覺結果:當你的滑鼠在螢幕上移動時,粒子會像受驚的魚群一樣自然散開,離開後會繼續順著流場漂動,保持畫面自然的靈動感。
💻 完整實作程式碼 (可以直接複製使用)
let particles = [];
function setup() {
createCanvas(windowWidth, windowHeight);
for (let i = 0; i < 100; i++) {
particles.push(new Particle());
}
}
function draw() {
background('#F5F5F0'); // 和紙白
for (let p of particles) {
p.update();
p.display();
}
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
class Particle {
constructor() {
this.pos = createVector(random(width), random(height));
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.maxspeed = 2;
this.color = random() > 0.9 ? '#E57373' : '#2C2C2C';
}
update() {
// 1. 有機流動感 (Noise)
let angle = noise(this.pos.x * 0.01, this.pos.y * 0.01, frameCount * 0.01) * TWO_PI * 2;
let noiseForce = p5.Vector.fromAngle(angle).mult(0.1);
this.acc.add(noiseForce);
// 2. 滑鼠互動
let mouse = createVector(mouseX, mouseY);
let dir = p5.Vector.sub(this.pos, mouse);
let d = dir.mag();
if (d < 100) {
dir.setMag(1);
dir.mult(map(d, 0, 100, 1, 0));
this.acc.add(dir);
}
this.vel.add(this.acc);
this.vel.limit(this.maxspeed);
this.pos.add(this.vel);
this.acc.mult(0);
// 3. 邊界處理:飄出畫面後從另一側回來 (Wrap)
if (this.pos.x < 0) this.pos.x = width;
if (this.pos.x > width) this.pos.x = 0;
if (this.pos.y < 0) this.pos.y = height;
if (this.pos.y > height) this.pos.y = 0;
}
display() {
fill(this.color);
noStroke();
ellipse(this.pos.x, this.pos.y, 4, 4);
}
}
🗺️ 作品集應用:這個模組還能怎麼用?
你現在已經做出一個可以放進作品集首頁的互動背景了。這個 Canvas 可以直接放在 Hero Section 的最底層作為背景,增加頁面的層次感。接下來,你可以嘗試調整這三個地方,讓它更符合你的風格:
-
改變粒子形狀:把
ellipse改成rect或line,視覺感會從「有機」變成「建築感」。 -
調整互動距離:將
if (d < 100)改成50(更內斂)或300(更激進),改變作品的情緒。 - 結合滾動事件:嘗試讓粒子在頁面滾動時改變顏色或速度,創造更深層的敘事感。
互動設計的核心不是程式碼,而是你想要傳達的「感覺」。
Top comments (0)