
React TsParticles 是一個流行的開源庫,能讓您輕鬆地將粒子動畫整合到 React 應用程式中。它構建於 TsParticles 庫之上,後者提供了一種靈活、可定製的方式來建立各種粒子效果和動畫。React TsParticles 簡化了將這些粒子動畫整合到 React 專案中的過程,使其成為為網站或網路應用程式新增動態和視覺吸引力元素的強大工具,本文將向您展示幾個使用示例。
在 Web 專案中新增粒子動畫可以增強整體使用者體驗,使網站或 Web 應用程式更具吸引力和視覺吸引力。以下是將粒子動畫融入網頁專案的一些主要優勢:
- 視覺吸引力:粒子動畫可以通過新增動態和吸引眼球的元素,使網站更具視覺吸引力。它們可以創造出一種深度感和互動性,使你的網站在競爭中脫穎而出。
- 使用者參與:動畫能吸引使用者的注意力,並能讓使用者參與到您的內容中來。互動顆粒可以鼓勵使用者與網站互動,探索網站功能。
- 使用者互動:互動式粒子動畫可以響應使用者的操作,如滑鼠移動或觸控,從而使網站更具響應性和互動性。這可以改善整體使用者體驗。
- 背景效果:粒子動畫通常用於背景效果,為內容提供有吸引力的背景。這對登陸頁面、作品集和其他視覺導向型網站都很有效。
安裝和設定 React TsParticles
在您的 React 應用程式專案目錄下,您可以使用以下 bash 指令碼通過您喜歡的軟體包安裝程式安裝 TsParticles 依賴項:
對於 npm
:
npm install react-tsparticles tsparticles
npm install react-tsparticles tsparticles
npm install react-tsparticles tsparticles
對於 yarn
:
yarn add react-tsparticles tsparticles
yarn add react-tsparticles tsparticles
yarn add react-tsparticles tsparticles
使用 TsParticles 建立動畫
在本節中,我們將討論 TsParticles 提供的各種動畫,以及如何將它們整合到網路應用中。
彩紙效果
在第一個動畫中,我們將使用 TsParticles 在網路應用程式中生成紙屑。紙屑是一種五顏六色的小塊材料,通常在特殊的慶祝場合投擲。在網路應用程式中,當使用者完成一項任務時,例如在電子學習網站上完成一門課程,可以用它來描繪一種慶祝形式。
要建立該動畫,請按照以下步驟進行:
- 首先,在
src/App.js
目錄中,我們將清除 boiler 模板程式碼並匯入必要的 TsParticle
依賴項:
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
- 接下來,我們將定義動畫配置和初始化 TsParticles 動畫的函式:
//Here we define the animation type, properties and behavior
const particlesInit = useCallback(async (engine) => {
// here we initialize the particles animation
//...
function App() {
const config = {
//Here we define the animation type, properties and behavior
};
const particlesInit = useCallback(async (engine) => {
// here we initialize the particles animation
await loadFull(engine);
}, []);
//...
function App() {
const config = {
//Here we define the animation type, properties and behavior
};
const particlesInit = useCallback(async (engine) => {
// here we initialize the particles animation
await loadFull(engine);
}, []);
我們將使用 useCallback
來記憶 particleInit
函式,因此由於依賴關係陣列為空 []
,React 不會在每次呈現時建立新函式,而只會在元件掛載時的第一次呈現時建立。
在 App.js
元件的 return
塊中,我們可以使用 config
和初始化函式訪問動畫:
<Particles options={config} init={particlesInit} />
//...
return (
<div className="App">
<Particles options={config} init={particlesInit} />
</div>
);
export default App;
//...
return (
<div className="App">
<Particles options={config} init={particlesInit} />
</div>
);
export default App;
對於彩紙動畫,我們將在 config
中定義以下屬性:
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
type: ["circle", "square"],
const config = {
fullScreen: {
zIndex: 1,
},
background: {
color: "#000",
},
emitters: {
position: {
x: 50,
y: 100,
},
rate: {
quantity: 5,
delay: 0.15,
},
},
particles: {
color: {
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
},
move: {
decay: 0.05,
direction: "top",
enable: true,
gravity: {
enable: true,
},
outModes: {
top: "none",
default: "destroy",
},
speed: {
min: 50,
max: 100,
},
},
number: {
value: 0,
},
opacity: {
value: 1,
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
animation: {
enable: true,
speed: 30,
},
},
tilt: {
direction: "random",
enable: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 30,
},
},
size: {
value: 10,
animation: {
enable: true,
startValue: "min",
count: 1,
speed: 16,
sync: true,
},
},
shape: {
type: ["circle", "square"],
options: {},
},
},
};
const config = {
fullScreen: {
zIndex: 1,
},
background: {
color: "#000",
},
emitters: {
position: {
x: 50,
y: 100,
},
rate: {
quantity: 5,
delay: 0.15,
},
},
particles: {
color: {
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
},
move: {
decay: 0.05,
direction: "top",
enable: true,
gravity: {
enable: true,
},
outModes: {
top: "none",
default: "destroy",
},
speed: {
min: 50,
max: 100,
},
},
number: {
value: 0,
},
opacity: {
value: 1,
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
animation: {
enable: true,
speed: 30,
},
},
tilt: {
direction: "random",
enable: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 30,
},
},
size: {
value: 10,
animation: {
enable: true,
startValue: "min",
count: 1,
speed: 16,
sync: true,
},
},
shape: {
type: ["circle", "square"],
options: {},
},
},
};
我們可以定義上述每個屬性的功能:
- Fullscreen:在該屬性中,我們使用
z-index
屬性將預期動畫的堆疊順序設為 “1”。
- Emitters:在這裡,我們使用
position
屬性指定了粒子動畫的初始 X 和 Y 原點。我們還使用 rate
指定了每次發射的數量以及每次建立粒子之間的延遲。
- Particles:通過該屬性,我們定義了發射粒子的質量和行為。
- Color:如上圖所示,可以是單一顏色,也可以是不同顏色的集合。這將為動畫中建立的每個粒子設定顏色。
- Move:該屬性定義:
- 粒子動畫的
direction
。
使用 decay
屬性指定粒子開始失去速度的時間。
我們還將 gravity
屬性設定為 true,以啟用重力對粒子的影響。
- Number:這是動畫中粒子的初始數量。
opacity
, rotate
, tilt
, size
, 和 shape
均執行其名稱所暗示的功能。要執行應用程式,請在工作目錄的終端環境中使用 npm start
命令,然後在瀏覽器中開啟結果。您將看到與下面 GIF 類似的頁面:

通過修改 config
屬性,我們可以在 TsParticles 中建立獨特的動畫形式。例如,我們可以用下面的程式碼獲得紙屑彈出動畫:
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
type: ["circle", "square"],
const config = {
fullScreen: {
zIndex: 1,
},
background: {
color: "#000",
},
emitters: {
life: {
count: 0,
duration: 0.1,
delay: 0.4,
},
rate: {
delay: 0.1,
quantity: 150,
},
size: {
width: 0,
height: 0,
},
},
particles: {
color: {
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
},
move: {
enable: true,
gravity: {
enable: true,
acceleration: 10,
},
speed: {
min: 10,
max: 20,
},
decay: 0.1,
direction: "none",
straight: false,
outModes: {
default: "destroy",
top: "none",
},
},
number: {
value: 0,
},
opacity: {
value: 1,
animation: {
enable: true,
minimumValue: 0,
speed: 2,
startValue: "max",
destroy: "min",
},
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
animation: {
enable: true,
speed: 30,
},
},
tilt: {
direction: "random",
enable: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 30,
},
},
size: {
value: 10,
random: {
enable: true,
minimumValue: 2,
},
},
shape: {
type: ["circle", "square"],
options: {},
},
},
};
const config = {
fullScreen: {
zIndex: 1,
},
background: {
color: "#000",
},
emitters: {
life: {
count: 0,
duration: 0.1,
delay: 0.4,
},
rate: {
delay: 0.1,
quantity: 150,
},
size: {
width: 0,
height: 0,
},
},
particles: {
color: {
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
},
move: {
enable: true,
gravity: {
enable: true,
acceleration: 10,
},
speed: {
min: 10,
max: 20,
},
decay: 0.1,
direction: "none",
straight: false,
outModes: {
default: "destroy",
top: "none",
},
},
number: {
value: 0,
},
opacity: {
value: 1,
animation: {
enable: true,
minimumValue: 0,
speed: 2,
startValue: "max",
destroy: "min",
},
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
animation: {
enable: true,
speed: 30,
},
},
tilt: {
direction: "random",
enable: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 30,
},
},
size: {
value: 10,
random: {
enable: true,
minimumValue: 2,
},
},
shape: {
type: ["circle", "square"],
options: {},
},
},
};
執行應用程式將產生以下結果:

煙花效果
在本節中,我們將使用 TsParticles 按以下步驟建立煙花效果:
- 首先,我們將設定黑色背景和全屏屬性,以便煙花清晰可見。此外,我們還將定義
fpsLimit
(幀速率限制),使動畫效果更佳,不會出現不流暢的情況,並將 detectRetina
值設為 “true”,以改善粒子外觀:
const config = {
fullScreen: {
enable: true,
},
detectRetina: true,
background: {
color: "#000",
},
fpsLimit: 60,
};
const config = {
fullScreen: {
enable: true,
},
detectRetina: true,
background: {
color: "#000",
},
fpsLimit: 60,
};
- 接下來,我們將定義粒子的發射器屬性。為了模模擬實的煙花,我們需要在建立爆炸效果之前,將粒子向上移動到不同的 x 座標和 y 座標上:
//...
emitters: {
direction: "top",
position: {
y: 100,
x: 50,
},
rate: {
delay: 0.03,
quantity: 1,
},
life: {
count: 0,
duration: 0.1,
delay: 0.1,
},
size: {
width: 80,
height: 0,
},
//...
//...
emitters: {
direction: "top",
position: {
y: 100,
x: 50,
},
rate: {
delay: 0.03,
quantity: 1,
},
life: {
count: 0,
duration: 0.1,
delay: 0.1,
},
size: {
width: 80,
height: 0,
},
//...
我們還定義了粒子的 rate
, life
, 和 size
屬性。接下來,我們將建立粒子並製作動畫:
// still within the emitters property
mode: "split", // using splits we will achieve a firework effect
value: 100, //number of splits to be created
// Splitted practicle properties
//color of particles after explosion
startValue: "max", // create multiple fireworks
// pattern of the explosion
count: 1, //amount of time
value: { min: 1, max: 100 },
// color of the fireworks stroke
value: ["#00FFFF", "#FF8000", "#0080FF"],
speed: { min: 10, max: 20 },
// trail for split particles
// still within the emitters property
particles: {
number: {
value: 0,
},
destroy: {
mode: "split", // using splits we will achieve a firework effect
split: {
rate: {
value: 100, //number of splits to be created
},
particles: {
// Splitted practicle properties
color: {
//color of particles after explosion
value: [
"#FF0000" /*Red */,
"#0000FF" /*blue */,
"#FFFF00" /*yellow*/,
],
},
opacity: {
value: 1,
animation: {
enable: true,
speed: 0.2,
minimumValue: 0.1,
sync: false,
startValue: "max", // create multiple fireworks
destroy: "min",
},
},
shape: {
// pattern of the explosion
type: "star",
},
size: {
value: 3,
animation: {
enable: false,
},
},
life: {
count: 1, //amount of time
duration: {
value: {
min: 1,
max: 2,
},
},
},
move: {
enable: true,
gravity: {
enable: false,
},
speed: 3,
direction: "none",
outMode: "destroy",
},
},
},
},
life: {
count: 1,
},
shape: {
type: "line",
},
size: {
value: { min: 1, max: 100 },
animation: {
enable: true,
sync: true,
speed: 150,
startValue: "random",
destroy: "min",
},
},
stroke: {
color: {
// color of the fireworks stroke
value: ["#00FFFF", "#FF8000", "#0080FF"],
},
width: 1,
},
rotate: {
path: true,
},
move: {
enable: true,
gravity: {
acceleration: 15,
enable: true,
inverse: true,
maxSpeed: 100,
},
speed: { min: 10, max: 20 },
outModes: {
default: "destroy",
},
trail: {
// trail for split particles
enable: true,
length: 10,
},
},
},
// still within the emitters property
particles: {
number: {
value: 0,
},
destroy: {
mode: "split", // using splits we will achieve a firework effect
split: {
rate: {
value: 100, //number of splits to be created
},
particles: {
// Splitted practicle properties
color: {
//color of particles after explosion
value: [
"#FF0000" /*Red */,
"#0000FF" /*blue */,
"#FFFF00" /*yellow*/,
],
},
opacity: {
value: 1,
animation: {
enable: true,
speed: 0.2,
minimumValue: 0.1,
sync: false,
startValue: "max", // create multiple fireworks
destroy: "min",
},
},
shape: {
// pattern of the explosion
type: "star",
},
size: {
value: 3,
animation: {
enable: false,
},
},
life: {
count: 1, //amount of time
duration: {
value: {
min: 1,
max: 2,
},
},
},
move: {
enable: true,
gravity: {
enable: false,
},
speed: 3,
direction: "none",
outMode: "destroy",
},
},
},
},
life: {
count: 1,
},
shape: {
type: "line",
},
size: {
value: { min: 1, max: 100 },
animation: {
enable: true,
sync: true,
speed: 150,
startValue: "random",
destroy: "min",
},
},
stroke: {
color: {
// color of the fireworks stroke
value: ["#00FFFF", "#FF8000", "#0080FF"],
},
width: 1,
},
rotate: {
path: true,
},
move: {
enable: true,
gravity: {
acceleration: 15,
enable: true,
inverse: true,
maxSpeed: 100,
},
speed: { min: 10, max: 20 },
outModes: {
default: "destroy",
},
trail: {
// trail for split particles
enable: true,
length: 10,
},
},
},
執行應用程式將得到以下效果:

使用預設
雖然建立粒子配置為控制動畫屬性提供了更大的靈活性,但也需要一定的時間才能完成。為了快速提供粒子動畫,TsParticles 引入了預設粒子的使用。預設允許使用者匯入並使用預先配置好的粒子動畫。例如,我們可以使用 TsParticles 提供的煙花預設,如下圖所示。
首先,我們在 CLI 中使用以下命令安裝預設:
npm install tsparticles-preset-fireworks
npm install tsparticles-preset-fireworks
npm install tsparticles-preset-fireworks
然後,我們就可以匯入並使用它,如下所示:
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
import { loadFireworksPreset } from "tsparticles-preset-fireworks";
const fireworkInit = useCallback(async (engine) => {
await loadFireworksPreset(engine);
<Particles options={options} init={fireworkInit} />
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
import { loadFireworksPreset } from "tsparticles-preset-fireworks";
const fireworkInit = useCallback(async (engine) => {
await loadFireworksPreset(engine);
}, []);
const options = {
preset: "fireworks",
};
return (
<div className="App">
<Particles options={options} init={fireworkInit} />
</div>
);
}
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
import { loadFireworksPreset } from "tsparticles-preset-fireworks";
const fireworkInit = useCallback(async (engine) => {
await loadFireworksPreset(engine);
}, []);
const options = {
preset: "fireworks",
};
return (
<div className="App">
<Particles options={options} init={fireworkInit} />
</div>
);
}
最終效果:

利用粒子實現互動
在本節中,我們將學習如何根據使用者互動(如點選和懸停事件)生成 TsParticle 動畫。如下程式碼所示,滑鼠點選事件可觸發粒子 emitter
動作:
background: {
color: "#000",
},
interactivity: {
events: {
onClick: {
enable: true,
mode: "emitter",
},
},
// emitter and mode here
},
background: {
color: "#000",
},
interactivity: {
events: {
onClick: {
enable: true,
mode: "emitter",
},
},
// emitter and mode here
},
接下來,我們定義一個包含 emitter
屬性的 mode
,然後新增其餘的動畫屬性:
//....
modes: {
emitters: {
direction: "top",
spawnColor: {
value: "#FF8000",
animation: {
h: {
enable: true,
offset: {
min: -1.4,
max: 1.4,
},
speed: 0.1,
sync: false,
},
l: {
enable: true,
offset: {
min: 20,
max: 80,
},
speed: 0,
sync: false,
},
},
},
life: {
count: 1,
duration: 0.1,
delay: 0.6,
},
rate: {
delay: 0.1,
quantity: 100,
},
size: {
width: 0,
height: 0,
},
},
},
//....
modes: {
emitters: {
direction: "top",
spawnColor: {
value: "#FF8000",
animation: {
h: {
enable: true,
offset: {
min: -1.4,
max: 1.4,
},
speed: 0.1,
sync: false,
},
l: {
enable: true,
offset: {
min: 20,
max: 80,
},
speed: 0,
sync: false,
},
},
},
life: {
count: 1,
duration: 0.1,
delay: 0.6,
},
rate: {
delay: 0.1,
quantity: 100,
},
size: {
width: 0,
height: 0,
},
},
},
最後,我們定義粒子的屬性:
type: ["circle", "square", "triangle"],
value: { min: 0, max: 1 },
value: { min: 6, max: 12 },
speed: { min: 10, max: 30 },
particles: {
number: {
value: 0,
},
color: {
value: "#0080FF",
},
shape: {
type: ["circle", "square", "triangle"],
},
opacity: {
value: { min: 0, max: 1 },
animation: {
enable: true,
speed: 1,
startValue: "max",
destroy: "min",
},
},
size: {
value: { min: 6, max: 12 },
},
life: {
duration: {
sync: true,
value: 7,
},
count: 1,
},
move: {
enable: true,
gravity: {
enable: true,
},
drift: {
min: -2,
max: 2,
},
speed: { min: 10, max: 30 },
decay: 0.1,
direction: "none",
random: false,
straight: false,
outModes: {
default: "destroy",
top: "none",
},
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
move: true,
animation: {
enable: true,
speed: 60,
},
},
tilt: {
direction: "random",
enable: true,
move: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 60,
},
},
roll: {
darken: {
enable: true,
value: 25,
},
enable: true,
speed: {
min: 15,
max: 25,
},
},
wobble: {
distance: 30,
enable: true,
move: true,
speed: {
min: -15,
max: 15,
},
},
},
particles: {
number: {
value: 0,
},
color: {
value: "#0080FF",
},
shape: {
type: ["circle", "square", "triangle"],
},
opacity: {
value: { min: 0, max: 1 },
animation: {
enable: true,
speed: 1,
startValue: "max",
destroy: "min",
},
},
size: {
value: { min: 6, max: 12 },
},
life: {
duration: {
sync: true,
value: 7,
},
count: 1,
},
move: {
enable: true,
gravity: {
enable: true,
},
drift: {
min: -2,
max: 2,
},
speed: { min: 10, max: 30 },
decay: 0.1,
direction: "none",
random: false,
straight: false,
outModes: {
default: "destroy",
top: "none",
},
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
move: true,
animation: {
enable: true,
speed: 60,
},
},
tilt: {
direction: "random",
enable: true,
move: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 60,
},
},
roll: {
darken: {
enable: true,
value: 25,
},
enable: true,
speed: {
min: 15,
max: 25,
},
},
wobble: {
distance: 30,
enable: true,
move: true,
speed: {
min: -15,
max: 15,
},
},
},
在上面的程式碼中,我們建立了一個向上彈出的紙屑效果,其原點位於滑鼠點選的位置:

以類似的模式,我們還可以定義懸停動畫,當滑鼠在螢幕上懸停時,動畫會發出微粒。為此,我們還將使用 interactivity
屬性:
const config = {
background: {
color: "#000",
},
interactivity: {
detectsOn: "window",
events: {
onhover: {
enable: true,
mode: "trail"
},
//...
const config = {
background: {
color: "#000",
},
interactivity: {
detectsOn: "window",
events: {
onhover: {
enable: true,
mode: "trail"
},
//...
在這裡,我們定義了檢測滑鼠事件的區域(即視窗)和要檢測的事件型別。我們將使用 onhover
效果建立滑鼠軌跡:
type: ["circle", "square", "triangle"],
value: { min: 0, max: 1 },
value: { min: 6, max: 12 },
//...
resize: true,
},
modes: {
grab: {
distance: 400,
line_linked: {
opacity: 1,
},
},
bubble: {
distance: 400,
size: 40,
duration: 2,
opacity: 0.8,
speed: 3,
},
repulse: {
distance: 200,
},
push: {
particles_nb: 4,
},
remove: {
particles_nb: 2,
},
trail: {
delay: 0.005,
quantity: 5,
pauseOnStop: true,
},
},
},
retina_detect: true,
fullScreen: {
enable: true,
zIndex: 100,
},
fpsLimit: 60,
particles: {
number: {
value: 0,
density: {
enable: true,
value_area: 800,
},
},
color: {
value: "#0080FF",
},
shape: {
type: ["circle", "square", "triangle"],
},
opacity: {
value: { min: 0, max: 1 },
animation: {
enable: true,
speed: 1,
startValue: "max",
destroy: "min",
},
},
size: {
value: { min: 6, max: 12 },
},
links: {
enable: false,
},
move: {
enable: true,
speed: 3.5,
direction: "none",
random: false,
straight: false,
outMode: "destroy",
attract: {
enable: false,
rotateX: 600,
rotateY: 1200,
},
},
},
//...
//...
resize: true,
},
modes: {
grab: {
distance: 400,
line_linked: {
opacity: 1,
},
},
bubble: {
distance: 400,
size: 40,
duration: 2,
opacity: 0.8,
speed: 3,
},
repulse: {
distance: 200,
},
push: {
particles_nb: 4,
},
remove: {
particles_nb: 2,
},
trail: {
delay: 0.005,
quantity: 5,
pauseOnStop: true,
},
},
},
retina_detect: true,
fullScreen: {
enable: true,
zIndex: 100,
},
fpsLimit: 60,
particles: {
number: {
value: 0,
density: {
enable: true,
value_area: 800,
},
},
color: {
value: "#0080FF",
},
shape: {
type: ["circle", "square", "triangle"],
},
opacity: {
value: { min: 0, max: 1 },
animation: {
enable: true,
speed: 1,
startValue: "max",
destroy: "min",
},
},
size: {
value: { min: 6, max: 12 },
},
links: {
enable: false,
},
move: {
enable: true,
speed: 3.5,
direction: "none",
random: false,
straight: false,
outMode: "destroy",
attract: {
enable: false,
rotateX: 600,
rotateY: 1200,
},
},
},
//...
執行應用程式將得到以下效果:

處理響應速度
通過 TsParticles,我們還可以定義粒子在不同螢幕尺寸下的行為,如下圖所示:
responsive: [
{
maxWidth: 1024,
options: {
particles: {
move: {
speed: {
min: 33,
max: 66,
},
},
},
},
},
],
responsive: [
{
maxWidth: 1024,
options: {
particles: {
move: {
speed: {
min: 33,
max: 66,
},
},
},
},
},
],
在上面的程式碼塊中,我們為 maxWidth
= 1024px 的螢幕定義了移動速度的最小值為 33,最大值為 66。因此,所有尺寸小於 1024px 的螢幕都將在定義的斷點範圍內對粒子應用屬性。
與其他 React 元件整合
在本節中,我們將學習如何通過其他元件執行的操作來切換粒子動畫。按鈕或完成進度條等操作都可以觸發這些動畫。
使用動畫,我們可以為簡單的使用者互動注入活力,例如點選訂閱按鈕或完成表單註冊。要通過按鈕觸發粒子動畫,請按照以下步驟操作:
- 首先,我們將建立一個新檔案
Button.jsx
,其中包含一個按鈕元件,新增必要的匯入,然後建立一個按鈕:
import React, { useState } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
const [subscribed, setSubscribed] = useState(false);
// confetti particles animation here
justifyContent: "center",
border: "1px solid black",
background: subscribed ? "red" : "white",
color: subscribed ? "white" : "black",
onClick={() => setSubscribed(!subscribed)}
{subscribed ? "Unsubscribe" : "Subscribe"}
<p style={{ fontSize: "40px", color: "white" }}>
{/* subscription caption */}
? "Subscribe to my news letter to get regular updates"
: "Thank you for subscribing. Cheers!!!"}
// return particles component when subscribed is true
import React, { useState } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
const Button = () => {
const [subscribed, setSubscribed] = useState(false);
// confetti particles animation here
return (
<div
style={{
display: "flex",
height: "100vh",
width: "100vw",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
gap: "23px",
background: "black"
}}
>
<button
id="#myButton"
style={{
padding: "10px 23px",
fontWeight: 700,
width: "max-content",
border: "1px solid black",
borderRadius: "12px",
background: subscribed ? "red" : "white",
color: subscribed ? "white" : "black",
transform: "scale(2)",
}}
onClick={() => setSubscribed(!subscribed)}
>
{subscribed ? "Unsubscribe" : "Subscribe"}
</button>
<p style={{ fontSize: "40px", color: "white" }}>
{/* subscription caption */}
{!subscribed
? "Subscribe to my news letter to get regular updates"
: "Thank you for subscribing. Cheers!!!"}
</p>
// return particles component when subscribed is true
</div>
);
};
export default Button;
import React, { useState } from "react";
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
const Button = () => {
const [subscribed, setSubscribed] = useState(false);
// confetti particles animation here
return (
<div
style={{
display: "flex",
height: "100vh",
width: "100vw",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
gap: "23px",
background: "black"
}}
>
<button
id="#myButton"
style={{
padding: "10px 23px",
fontWeight: 700,
width: "max-content",
border: "1px solid black",
borderRadius: "12px",
background: subscribed ? "red" : "white",
color: subscribed ? "white" : "black",
transform: "scale(2)",
}}
onClick={() => setSubscribed(!subscribed)}
>
{subscribed ? "Unsubscribe" : "Subscribe"}
</button>
<p style={{ fontSize: "40px", color: "white" }}>
{/* subscription caption */}
{!subscribed
? "Subscribe to my news letter to get regular updates"
: "Thank you for subscribing. Cheers!!!"}
</p>
// return particles component when subscribed is true
</div>
);
};
export default Button;
之後,我們就可以建立 TsParticles
配置,並設定 Particles
元件在 subscribe
狀態為 true 時顯示:
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
type: ["circle", "square"],
const particlesInit = useCallback(async (engine) => {
// pop confetti
const config = {
fullScreen: {
zIndex: 1,
},
emitters: {
position: {
x: 50,
y: 100,
},
rate: {
quantity: 25,
delay: 0.15,
},
spawnColor: {
value: "#FF8000",
animation: {
h: {
enable: true,
offset: {
min: -1.4,
max: 1.4,
},
speed: 0.1,
sync: false,
},
l: {
enable: true,
offset: {
min: 20,
max: 80,
},
speed: 0,
sync: false,
},
},
},
life: {
count: 1,
duration: 7,
delay: 0.6,
},
size: {
width: 0,
height: 0,
},
},
particles: {
color: {
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
},
move: {
decay: 0.05,
direction: "top",
enable: true,
gravity: {
enable: true,
},
outModes: {
top: "none",
default: "destroy",
},
speed: {
min: 50,
max: 100,
},
},
number: {
value: 0,
},
opacity: {
value: 1,
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
animation: {
enable: true,
speed: 30,
},
},
tilt: {
direction: "random",
enable: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 30,
},
},
size: {
value: 8,
animation: {
enable: true,
startValue: "min",
count: 1,
speed: 16,
sync: true,
},
},
roll: {
darken: {
enable: true,
value: 25,
},
enlighten: {
enable: true,
value: 25,
},
enable: true,
speed: {
min: 5,
max: 15,
},
},
wobble: {
distance: 30,
enable: true,
speed: {
min: -7,
max: 7,
},
},
shape: {
type: ["circle", "square"],
options: {},
},
},
};
const particlesInit = useCallback(async (engine) => {
await loadFull(engine);
}, []);
// pop confetti
const config = {
fullScreen: {
zIndex: 1,
},
emitters: {
position: {
x: 50,
y: 100,
},
rate: {
quantity: 25,
delay: 0.15,
},
spawnColor: {
value: "#FF8000",
animation: {
h: {
enable: true,
offset: {
min: -1.4,
max: 1.4,
},
speed: 0.1,
sync: false,
},
l: {
enable: true,
offset: {
min: 20,
max: 80,
},
speed: 0,
sync: false,
},
},
},
life: {
count: 1,
duration: 7,
delay: 0.6,
},
size: {
width: 0,
height: 0,
},
},
particles: {
color: {
value: ["#1E00FF", "#FF0061", "#E1FF00", "#00FF9E"],
},
move: {
decay: 0.05,
direction: "top",
enable: true,
gravity: {
enable: true,
},
outModes: {
top: "none",
default: "destroy",
},
speed: {
min: 50,
max: 100,
},
},
number: {
value: 0,
},
opacity: {
value: 1,
},
rotate: {
value: {
min: 0,
max: 360,
},
direction: "random",
animation: {
enable: true,
speed: 30,
},
},
tilt: {
direction: "random",
enable: true,
value: {
min: 0,
max: 360,
},
animation: {
enable: true,
speed: 30,
},
},
size: {
value: 8,
animation: {
enable: true,
startValue: "min",
count: 1,
speed: 16,
sync: true,
},
},
roll: {
darken: {
enable: true,
value: 25,
},
enlighten: {
enable: true,
value: 25,
},
enable: true,
speed: {
min: 5,
max: 15,
},
},
wobble: {
distance: 30,
enable: true,
speed: {
min: -7,
max: 7,
},
},
shape: {
type: ["circle", "square"],
options: {},
},
},
};
const particlesInit = useCallback(async (engine) => {
await loadFull(engine);
}, []);
在上面的程式碼塊中,我們建立了一個 subscribed
狀態,用於管理要顯示的文字以及按鈕的 CSS 屬性。在 return
程式碼塊的末尾,新增
{subscribed ? <Particles options={config} init={particlesInit} /> : null}
{subscribed ? <Particles options={config} init={particlesInit} /> : null}
{subscribed ? <Particles options={config} init={particlesInit} /> : null}
這樣,我們就可以在點選按鈕時切換 subscribed
值。它會顯示粒子:

進度條指示器
進度條指示器是使用者完成任務進度的標誌。這可以是完成課程,甚至是滾動到頁面底部。通過使用動畫,我們可以為使用者提供一個完成任務的標誌,讓他們感到放鬆。與上一節中的按鈕示例類似,我們可以在滑塊達到 “100%” 值時觸發粒子動畫:
import React, { useState, useEffect } from "react";
const [scrolled, setScrolled] = useState(0);
window.onscroll = function () {
document.body.scrollTop || document.documentElement.scrollTop;
document.documentElement.scrollHeight -
document.documentElement.clientHeight;
setScrolled((winScroll / height) * 100);
{/* Page content. For this example, I am using random AI generated text */}
import React, { useState, useEffect } from "react";
const Slider = () => {
const [scrolled, setScrolled] = useState(0);
useEffect(() => {
window.onscroll = function () {
var winScroll =
document.body.scrollTop || document.documentElement.scrollTop;
var height =
document.documentElement.scrollHeight -
document.documentElement.clientHeight;
setScrolled((winScroll / height) * 100);
};
}, []);
return (
<div
style={{
display: "flex",
minHeight: "100vh",
flexDirection: "column",
alignItems: "center",
position: "relative",
padding: "0 120px",
background: "#333"
}}
>
<progress
value={scrolled}
max={100}
style={{
width: "80%",
height: "30px",
marginTop: "15px",
position: "fixed",
top: "0",
}}
></progress>
<h1
style={{
marginTop: "80px",
color:"white",
}}
>
{/* content */}
{/* Page content. For this example, I am using random AI generated text */}
</h1>
</div>
);
};
export default Slider;
import React, { useState, useEffect } from "react";
const Slider = () => {
const [scrolled, setScrolled] = useState(0);
useEffect(() => {
window.onscroll = function () {
var winScroll =
document.body.scrollTop || document.documentElement.scrollTop;
var height =
document.documentElement.scrollHeight -
document.documentElement.clientHeight;
setScrolled((winScroll / height) * 100);
};
}, []);
return (
<div
style={{
display: "flex",
minHeight: "100vh",
flexDirection: "column",
alignItems: "center",
position: "relative",
padding: "0 120px",
background: "#333"
}}
>
<progress
value={scrolled}
max={100}
style={{
width: "80%",
height: "30px",
marginTop: "15px",
position: "fixed",
top: "0",
}}
></progress>
<h1
style={{
marginTop: "80px",
color:"white",
}}
>
{/* content */}
{/* Page content. For this example, I am using random AI generated text */}
</h1>
</div>
);
};
export default Slider;
在上面的程式碼塊中,我們建立了一個進度指示器,顯示使用者滾動了頁面的多少部分。當使用者滾動到頁面底部時,我們將觸發粒子動畫:
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
// config and particles init function
//properties of the main firework particle
value: 0, //to randomiser the number of particles
mode: "split", //to get the fireworks effect
value: 100, //amount of splits
// setting properties of those particles formed after splitting
startValue: "max", //multiple fireworks
enable: false, //to get the sparkly feeling
count: 1, //amount of time
//all about firework showers
enable: true, // to get the fireworks effect
enable: false, //stops gravity from pulling them up
speed: 3, //speed of the fireworks
direction: "none", //direction of the fireworks
outMode: "destroy", // avoids overlapping of fireworks
value: { min: 1, max: 100 },
value: ["#00FFFF", "#FF8000", "#0080FF"],
path: true, //single path
inverse: true, //to avoid projectiles and follow a st line
speed: { min: 10, max: 20 },
// to give the split particle a trail so that we can see its dirn
const particlesInit = useCallback(async (engine) => {
// dependencies
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
// config and particles init function
const config = {
fullScreen: {
enable: true,
},
detectRetina: true,
fpsLimit: 60,
emitters: {
direction: "top",
position: {
y: 100,
x: 50,
},
rate: {
delay: 0.03,
quantity: 1,
},
life: {
count: 0,
duration: 0.1,
delay: 0.1,
},
size: {
width: 100,
height: 0,
},
particles: {
//properties of the main firework particle
number: {
value: 0, //to randomiser the number of particles
},
destroy: {
mode: "split", //to get the fireworks effect
split: {
rate: {
value: 100, //amount of splits
},
particles: {
// setting properties of those particles formed after splitting
color: {
value: [
"#FF0000" /*Red */,
"#0000FF" /*blue */,
"#FFFF00" /*yellow*/,
],
},
opacity: {
value: 1,
animation: {
enable: true,
speed: 0.2,
minimumValue: 0.1,
sync: false,
startValue: "max", //multiple fireworks
destroy: "min",
},
},
shape: {
type: "star",
},
size: {
value: 4,
animation: {
enable: false, //to get the sparkly feeling
},
},
life: {
count: 1, //amount of time
duration: {
value: {
min: 1,
max: 2,
},
},
},
move: {
//all about firework showers
enable: true, // to get the fireworks effect
gravity: {
enable: false, //stops gravity from pulling them up
},
speed: 3, //speed of the fireworks
direction: "none", //direction of the fireworks
outMode: "destroy", // avoids overlapping of fireworks
},
},
},
},
life: {
count: 1,
},
shape: {
type: "line",
},
size: {
value: { min: 1, max: 100 },
animation: {
enable: true,
sync: true,
speed: 150,
startValue: "random",
destroy: "min",
},
},
stroke: {
color: {
value: ["#00FFFF", "#FF8000", "#0080FF"],
},
width: 1,
},
rotate: {
path: true, //single path
},
move: {
enable: true,
gravity: {
acceleration: 15,
enable: true,
inverse: true, //to avoid projectiles and follow a st line
maxSpeed: 100,
},
speed: { min: 10, max: 20 },
outModes: {
default: "destroy",
},
trail: {
// to give the split particle a trail so that we can see its dirn
enable: true,
length: 10,
},
},
},
},
};
const particlesInit = useCallback(async (engine) => {
await loadFull(engine);
}, []);
// dependencies
import Particles from "react-tsparticles";
import { loadFull } from "tsparticles";
import { useCallback } from "react";
// config and particles init function
const config = {
fullScreen: {
enable: true,
},
detectRetina: true,
fpsLimit: 60,
emitters: {
direction: "top",
position: {
y: 100,
x: 50,
},
rate: {
delay: 0.03,
quantity: 1,
},
life: {
count: 0,
duration: 0.1,
delay: 0.1,
},
size: {
width: 100,
height: 0,
},
particles: {
//properties of the main firework particle
number: {
value: 0, //to randomiser the number of particles
},
destroy: {
mode: "split", //to get the fireworks effect
split: {
rate: {
value: 100, //amount of splits
},
particles: {
// setting properties of those particles formed after splitting
color: {
value: [
"#FF0000" /*Red */,
"#0000FF" /*blue */,
"#FFFF00" /*yellow*/,
],
},
opacity: {
value: 1,
animation: {
enable: true,
speed: 0.2,
minimumValue: 0.1,
sync: false,
startValue: "max", //multiple fireworks
destroy: "min",
},
},
shape: {
type: "star",
},
size: {
value: 4,
animation: {
enable: false, //to get the sparkly feeling
},
},
life: {
count: 1, //amount of time
duration: {
value: {
min: 1,
max: 2,
},
},
},
move: {
//all about firework showers
enable: true, // to get the fireworks effect
gravity: {
enable: false, //stops gravity from pulling them up
},
speed: 3, //speed of the fireworks
direction: "none", //direction of the fireworks
outMode: "destroy", // avoids overlapping of fireworks
},
},
},
},
life: {
count: 1,
},
shape: {
type: "line",
},
size: {
value: { min: 1, max: 100 },
animation: {
enable: true,
sync: true,
speed: 150,
startValue: "random",
destroy: "min",
},
},
stroke: {
color: {
value: ["#00FFFF", "#FF8000", "#0080FF"],
},
width: 1,
},
rotate: {
path: true, //single path
},
move: {
enable: true,
gravity: {
acceleration: 15,
enable: true,
inverse: true, //to avoid projectiles and follow a st line
maxSpeed: 100,
},
speed: { min: 10, max: 20 },
outModes: {
default: "destroy",
},
trail: {
// to give the split particle a trail so that we can see its dirn
enable: true,
length: 10,
},
},
},
},
};
const particlesInit = useCallback(async (engine) => {
await loadFull(engine);
}, []);
在上面的程式碼塊中,我們匯入了 TsParticles
依賴項,併為之前的煙花動畫建立了一個配置。為了在進度已滿時顯示動畫,我們需要設定一個條件,檢查 scrolled
的值是否為 100,然後渲染 Particles
元件:
<Particles options={config} init={particlesInit} />
{scrolled === 100 ? (
<Particles options={config} init={particlesInit} />
) : null}
{scrolled === 100 ? (
<Particles options={config} init={particlesInit} />
) : null}
最終結果:

小結
在本文中,我們討論了 React TsParticles 庫及其融入網路應用時的視覺效果。我們還展示了在 React 應用程式中設定和實現 TsParticles 的步驟。此外,我們還討論了使用使用者互動自定義粒子動畫行為以及與其他 React 元件的整合。
評論留言