particles.jsのアニメーション切替問題!
Particlesjs Switch
Webサイトにリッチな演出を加えるライブラリのひとつに particles.js があります。星屑のようなパーティクルが舞う背景は、とても華やかで目を引きますよね。しかし、アニメーションを複数パターン切り替えて使いたい場合、注意しなければならない落とし穴があります。
複数アニメーション切替で起きる問題
particles.js は一度ロードすると
インスタンスを保持したまま動き続けます。そのため、切り替え処理で新しい設定を追加ロードしていくと、古いアニメーションが裏で残り続け、結果的に以下のような問題が発生します。
- 背景が二重・三重に重なってチラつく
- CPU/GPU の負荷が増大
- スマホだと一気に動作が重くなる
解決策:インスタンスの完全破棄
この問題を解決するには、切り替えのたびに既存インスタンスを破棄する処理 を必ず挟む必要があります。以下の関数を用意すると安全です。
app.js
//////////////////////アニメーションを完全破棄////////////////////
function clearParticles() {
if (window.pJSDom && window.pJSDom.length > 0) {
try {
window.pJSDom[0].pJS.fn.vendors.destroypJS(); // ←これが核
window.pJSDom = [];
console.log("Particles.js 初期化完了");
} catch (e) {
console.warn("Particles.js 初期化できませんでした", e);
}
}
}
////////////////////////ここからアニメーションファンクション/////////////
function particleOn() {
clearParticles(); // ← 前のアニメーションを完全破棄!
particlesJS('particles-js',
{
"particles": {
"number": {
"value": 80,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#ffffff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.5,
"random": false,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 5,
"random": true,
"anim": {
"enable": false,
"speed": 40,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": true,
"distance": 150,
"color": "#ffffff",
"opacity": 0.4,
"width": 1
},
"move": {
"enable": true,
"speed": 6,
"direction": "none",
"random": false,
"straight": false,
"out_mode": "out",
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "repulse"
},
"onclick": {
"enable": true,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 400,
"size": 40,
"duration": 2,
"opacity": 8,
"speed": 3
},
"repulse": {
"distance": 200
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true,
"config_demo": {
"hide_card": false,
"background_color": "#b61924",
"background_image": "",
"background_position": "50% 50%",
"background_repeat": "no-repeat",
"background_size": "cover"
}
}
);
}
////////////////////////////////////////////////////////////
function snowOn() {
clearParticles(); // ← 前のアニメーションを完全破棄!
// 雪を降らせる
particlesJS("particles-js", {
"particles": {
//シェイプの設定
"number": {
"value": 150, //シェイプの数
"density": {
"enable": true, //シェイプの密集度の設定許可
"value_area": 800 //シェイプの密集度
}
},
"shape": {
"type": "image", //circle、edge、triangle、polygon、star、image から選べる
"image": {
"src": "https://kakechimaru.com/wp-content/themes/kakechimaru/image/snow_particlesjs.png", //雪の画像を設定する ※相対パスでも可
}
},
"opacity": {
"value": 0.7, //透明度
"random": false, //透明度ランダムの許可
"anim": {
"enable": false, //透明度のアニメーションさせるかどうか
"speed": 1, //アニメーションのスピード
"opacity_min": 0.1, //透明度の最小値
"sync": false //シェイプを同時にアニメーションさせるかどうか
}
},
"size": {
"value": 5, //シェイプの大きさ
"random": true, //大きさランダムの許可
"anim": {
"enable": false, //大きさアニメーションさせるかどうか
"speed": 20, //スピード
"size_min": 0.1, //スピードの最小値
"sync": false //同時にアニメーションさせるかどうか
}
},
// 線の設定
"line_linked": {
"enable": false, //線を表示するかどうか
},
// 動きの設定
"move": {
"enable": true, //シェイプの動かすかどうか
"speed": 2, //スピード
"direction": "bottom", //シェイプの動く方向(none、top、top-right、right、bottom-right、bottom、bottom-left、left、top-left から選べる)
"random": true, // 動きはランダム
"straight": false, // 動きをとどめない
"out_mode": "out", //エリア外に出たシェイプの動き(out、bounce から選べる)
"bounce": false, //跳ね返りなし
"attract": {
"enable": true,
"rotateX": 300,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
//マウスオーバー時
"onhover": {
"enable": false, //マウスオーバーの許可
},
//クリック時
"onclick": {
"enable": false, //クッリクの許可
},
"resize": true
}
},
"retina_detect": true
});
}
////////////////////////////////////////////////////////////
function bubbleOn() {
clearParticles(); // ← 前のアニメーションを完全破棄!
particlesJS("particles-js",
{
"particles": {
"number": {
"value": 28,
"density": {
"enable": true,
"value_area": 789.1476416322727
}
},
"color": {
"value": "#ffffff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 3,
"color": "#9be1ff"
},
"polygon": {
"nb_sides": 8
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.41035677364878176,
"random": true,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 43.403120289774996,
"random": true,
"anim": {
"enable": false,
"speed": 21.57842157842158,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 500,
"color": "#ffffff",
"opacity": 0.4, "width": 2
},
"move": {
"enable": true,
// "speed":4.734885849793636,
"speed": 1.734885849793636,
"direction": "top",
"random": false,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 2367.442924896818,
"rotateY": 1104.8066982851817
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "bubble"
},
"onclick": {
"enable": true,
"mode": "repulse"
},
"resize": true
},
"modes": {
"grab": {
"distance": 503.4965034965035,
"line_linked": {
"opacity": 0.5
}
},
"bubble": {
"distance": 400,
"size": 4,
"duration": 0.3,
"opacity": 1,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}
);
var count_particles, stats, update;
stats = new Stats;
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
count_particles = document.querySelector('.js-count-particles');
update = function () {
stats.begin(); stats.end();
if (window.pJSDom[0].pJS.particles && window.pJSDom[0].pJS.particles.array) {
count_particles.innerText = window.pJSDom[0].pJS.particles.array.length;
}
requestAnimationFrame(update);
};
requestAnimationFrame(update);;
}
///////////////////////////////////////////////////////////////
function snow2On() {
clearParticles(); // ← 前のアニメーションを完全破棄!
particlesJS('particles-js',
{
"particles": {
//シェイプ数
"number": {
//要素内に表示するシェイプの数
"value": 160,//初期値80
"density": {
//シェイプ表示間隔設定
"enable": true,
//シェイプ表示間隔指定
"value_area": 800
}
},
//シェイプ色
"color": {
"value": "#ffffff"
},
//シェイプの設定
"shape": {
//シェイプ形
"type": "circle", //circle, edge, triangle, polygon, star, image 複数指定["circle", "triangle", "image"]
//シェイプボーダー設定
"stroke": {
//ボーダー幅
"width": 0,
//ボーダー色
"color": "#000000"
},
//シェイプの形でpolygonを指定した場合
"polygon": {
//ポリゴン角数指定
"nb_sides": 5
},
//シェイプの形でimageを指定した場合
"image": {
//画像パス
"src": "img/github.svg",
//画像幅
"width": 100,
//画像高
"height": 100
}
},
//シェイプ透過率指定
"opacity": {
//透過率指定
"value": 0.8,//初期値0.5
//ランダム設定
"random": false, //true:有効, false:無効
//透過アニメーション設定
"anim": {
//アニメーション設定
"enable": false, //true:有効, false:無効
//アニメーション速度
"speed": 1,//初期値1
//アニメーション最小透過率
"opacity_min": 0.1,
//アニメーション同期
"sync": false //true:有効, false:無効
}
},
//シェイプサイズ
"size": {
//シェイプサイズ指定
"value": 5,
//ランダムサイズ
"random": true, //true:有効, false:無効
//サイズアニメーション設定
"anim": {
//アニメーション設定
"enable": false, //true:有効, false:無効
//アニメーション速度
"speed": 40,//初期値40
//アニメーション最小サイズ,
"size_min": 1,
//アニメーション同期設定
"sync": false //true:有効, false:無効
}
},
//シェイプを線で繋ぐか
"line_linked": {
//線の設定
"enable": false, //true:有効, false:無効
//線の間隔
"distance": 150,
//線の色
"color": "#ffffff",
//線の透過率
"opacity": 0.4,
//線の幅
"width": 1
},
//シェイプの動きの設定
"move": {
//動きを制御するか
"enable": true, //true:有効, false:無効
//動く速度
"speed": 0.5,
//動く方向
"direction": "bottom", //none, top, top-right, right, bottom-right, bottom, bottom-left, left, top-left
//ランダム設定
"random": false, //true:有効, false:無効
//静止状態にする
"straight": false, //true:有効, false:無効
//シェイプの動き
"out_mode": "out", //ボックス内で動かす bounce ボックス外に逃がす out
"attract": {
"enable": true,
"rotateX": 1000,
"rotateY": 1000
}
}
},
"interactivity": {
"detect_on": "canvas",
//マウスイベント設定
"events": {
//マウスオーバー時の処理
"onhover": {
"enable": false, //true:有効, false:無効
"mode": "bubble" //grad:付近のシェイプと線を繋ぐ, bubble:拡大, repulse:拒絶
},
//クリック時の処理処理
"onclick": {
//クリック時の処理
"enable": true, //true:有効, false:無効
//クリック時の処理
"mode": "push" //push:追加, remove:削除, bubble:拡大, repulse:拒絶
},
"resize": true
},
//以下でマウスイベント発生時の詳細値を設定
"modes": {
"grab": {
"distance": 300,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 100,
"size": 7.5,
"duration": 2,
"opacity": 8,
"speed": 3
},
"repulse": {
"distance": 1
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
//Retina Display対応
"retina_detect": true, //true:有効, false:無効
}
);
}
///////////////////////////////////////////////////////////
function paperOn() {
clearParticles(); // ← 前のアニメーションを完全破棄!
particlesJS("particles-js", { //ここに書くのがHTMLのidに対応するもの
"particles": {
"number": {
"value": 50,//紙吹雪の数
"density": {
"enable": false,
"value_area": 200
}
},
"color": {
"value": ["#EA5532", "#F6AD3C", "#FFF33F", "#00A95F", "#00ADA9", "#00AFEC", "#4D4398", "#E85298"]//紙吹雪の色の種類
},
"shape": {
"type": "polygon",//形状はPolygon,つまり多角形
"stroke": {
"width": 0,
},
"polygon": {
"nb_sides": 4//多角形の角の数
}
},
"opacity": {
"value": 1,
"random": false,
"anim": {
"enable": true,
"speed": 20,
"opacity_min": 0,
"sync": false
}
},
"size": {
// "value":5,
"value": 8,
"random": true,//サイズをランダムにする
"anim": {
"enable": true,
"speed": 1,
"size_min": 1,
"sync": false
}
},
"line_linked": {
"enable": false,
},
"move": {
"enable": true,
"speed": 3,//小さくするとゆっくり、大きくすると速くなる
"direction": "bottom",//落ちる向き
"random": true,//動きをランダムにするか
"straight": false,//まっすぐ落ちるかどうか
"out_mode": "out",//画面の外に出るか
"bounce": false,//跳ね返るかどうか
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": false,
},
"onclick": {
"enable": false,
},
"resize": true
},
},
"retina_detect": true
});
}
/////////////////////////////////////////////////////
function sakuraOn() {
clearParticles(); // ← 前のアニメーションを完全破棄!
particlesJS("particles-js", {
"particles": {
"number": {
"value": 60,//この数値を変更すると桜の数が増減できる
"density": {
"enable": true,
"value_area": 1121.6780303333778
}
},
"color": {
"value": "#fff"
},
"shape": {
"type": "image",//形状は画像を指定
"stroke": {
"width": 0,
},
"image": {
"src": "./img/sakura.png",//画像を指定
"width": 420,
"height": 420
}
},
"opacity": {
"value": 0.06409588744762158,
"random": true,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
// "value":8.011985930952697,
"value": 11.011985930952697,
"random": true,//サイズをランダムに
"anim": {
"enable": false,
"speed": 4,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": false,
},
"move": {
"enable": true,
"speed": 5,//この数値を小さくするとゆっくりな動きになる
"direction": "bottom-right",//右下に向かって落ちる
"random": true,//動きはランダムにしないfalse
"straight": false,//動きをとどめない
"out_mode": "out",//画面の外に出るように描写
"bounce": false,//跳ね返りなし
"attract": {
"enable": false,
"rotateX": 281.9177489524316,
"rotateY": 127.670995809726
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": false,
},
"onclick": {
"enable": false,
},
"resize": true
}
},
"retina_detect": false
});
}
///////////////////////////////////////////////////////////////
function hotalOn() {
clearParticles(); // ← 前のアニメーションを完全破棄!
particlesJS("particles-js", {
"particles": {
"number": {
// "value":50,//この数値を変更するとホタルの数が増減できる
"value": 80,//この数値を変更するとホタルの数が増減できる
"density": {
"enable": true,
"value_area": 1602.3971861905397
}
},
"color": {
"value": "#f3fa8b"//色
},
"shape": {
"type": "circle",//形状はcircleを指定
"stroke": {
"width": 0,
}
},
"opacity": {
"value": 1,
"random": true,//透過をランダムに
"anim": {
"enable": false,
"speed": 1.10115236356258881,
"opacity_min": 0,
"sync": false
}
},
"size": {
"value": 4.005992965476349,
"random": true,//サイズをランダムに
"anim": {
"enable": true,
"speed": 24.345709068776642,
"size_min": 0.5,
"sync": false
}
},
"line_linked": {
"enable": false,
},
"move": {
"enable": true,
// "speed":6,//この数値を小さくするとゆっくりな動きになる
"speed": 1,//この数値を小さくするとゆっくりな動きになる
"direction": "none",//方向指定なし
"random": true,//動きはランダムに
"straight": false,//動きをとどめない
"out_mode": "out",//画面の外に出るように描写
"bounce": false,//跳ね返りなし
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 600
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": false
},
"onclick": {
"enable": false
},
"resize": true
}
},
"retina_detect": true
});
}
///////////////////////////////////////////////////////////////////////////
function rainOn() {
clearParticles(); // ← 前のアニメーションを完全破棄!
particlesJS('particles-js', {
particles: {
number: {
value: 80, // Number of raindrops
density: {
enable: true,
value_area: 800
}
},
color: {
value: '#ffffff' // White raindrops
},
shape: {
type: 'circle', // Raindrops as circles
},
opacity: {
value: 0.5,
random: false,
anim: {
enable: false,
}
},
size: {
value: 3, // Size of raindrops
random: true,
anim: {
enable: false,
}
},
line_linked: {
enable: false, // No lines between raindrops
},
move: {
enable: true,
speed: 6, // Falling speed
direction: 'bottom', // Fall downwards
random: true,
straight: false,
out_mode: 'out', // Disappear when out of bounds
bounce: false,
attract: {
enable: false,
}
}
},
interactivity: {
detect_on: 'canvas',
events: {
onhover: {
enable: false, // No hover effects
},
onclick: {
enable: false, // No click effects
},
resize: true
}
},
retina_detect: true
});
}

コメント
コメントを投稿