先日、背景に泡のアニメーションを作成できるbubbly-bg.jsを紹介しました。
今回は、同類のjsライブラリ particles.jsを紹介いたします。
こちらは、オプションが多数ありますが、実は簡単に実装できてしまいます。
オプションの内容を説明しデフォルト値も踏まえ、実際にCODEPENで実装しています。
また、bubbly-bg.jsと異なる点もご理解いただけると思います。
particles.js
公式ページの紹介
後者を先にご覧いただくと、このライブラリのイメージがつかみやすい思います。
そして、このページが実装に大変役に立ちます。
特徴
まず、オプションが豊富です。
前述の記事で紹介した bubbly-bg.js は泡(円形)のアニメーションに特化していましたが、こちらのライブラリは円形の他に三角形、四角形、六角形、多角形と豊富な形から選択できます。
しかも、bubbly-bg.jsと同様、 jQuery非依存で、軽量のライブラリです。
なぜ軽量かというと、 bubbly-bg.jsと同じ理由で、HTML5から追加された図形描写の技術仕様Canvasと、JavaScriptを組み合わせて図形を描画しているためです。
ライブラリのファイルの中を覗いて見ると、canvas要素を指定したあと、getContextメソッドにより描画機能を有効にしていることからも分かります。
つまり、スクリプトで図形を描写することで、画像と比べてデータ量を軽量することが可能となっているのです。
使用方法概略
使用するファイル
- HTMLファイル
- CSSファイル
- JSファイル
使用方法
HTMLファイルでライブラリをCDNで読み込みます。
<body>
<div id="particles-js"></div> <!-- ここがcanvasになる -->
<!-- particles.js -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
<script src="particles.js"></script>
<!-- ご自身のパスに変更 -->
<script src="main.js"></script>
</body>
オプション
オプション名のドット続きの部分はネストして記述します。
詳細な記述方法は、後述のコードを見ると分かりやすいと思います。
particlesとは粒子を意味します。
つまり、ここでは図形(シェイプ)のことですが、文字数の関係上そのまま粒子と表記しています。
また、 interactivityとは双方向性という意味になります。
particlesオプション(粒子関連)一覧
key | 説明 | option type / notes | example | default |
particles.number.value | 粒子の数 | number | 40 | 400 |
particles.number.density.enable | 粒子の密度を設定するか trueの場合、粒子の数のオプションは無視される | boolean | true / false | true |
particles.number.density.value_area | 粒子の密度を設定した場合の密度 数値が大きくなる程、粒子の数は減少 | number | 800 | 800 |
particles.color.value | 粒子の色 | HEX (string) RGB (object) HSL (object) array selection (HEX) random (string) | “#b61924” {r:182, g:25, b:36} {h:356, s:76, l:41} [“#b61924”, “#333333”, “999999”] “random” | “#fff” |
particles.shape.type | アニメーションする粒子の形を指定、 circle : 円形 edg : 四角形 triangle : 三角形 polygon : 多角形 star : polygon.nb_slidesの数値が奇数の時に星形多角形 image : イメージを指定 配列で指定もOK | string array selection | “circle” “edg” “triangle” “polygon” “star” “image” [ “circle” , “triangle” , “image” ] | “circle” |
particles.shape.stroke.width | 粒子の枠の幅 0 : 枠を付けない | number | 2 | 0 |
particles.shape.stroke.color | 粒子の枠の色 | HEX (string) | “#222222” | “#ff0000” |
particles.shape.polygon.nb_slides | 多角形の頂点の数 5 : 五角形 | number | 5 | 5 |
particles.shape.image.src | 粒子とするイメージ | path link svg / png / gif / jpg | “assets/img/yop.svg” “http://mywebsite.com/assets/img/yop.png” | “” |
particles.shape.image.width | 粒子とするイメージの幅 | number (for aspect ratio) | 100 | 100 |
particles.shape.image.height | 粒子とするイメージの高さ | number (for aspect ratio) | 100 | 100 |
particles.opacity.value | 粒子の不透明度 0 : 透明 | number (0 to 1) | 0.75 | 1 |
particles.opacity.random | 粒子の不透明度をランダムにするか | boolean | true / false | false |
particles.opacity.anim.enable | 粒子の不透明度を変化させるか | boolean | true / false | false |
particles.opacity.anim.speed | 粒子の不透明度を変化の速度 | number | 3 | 2 |
particles.opacity.anim.opacity_min | 粒子の最小不透明度 | number (0 to 1) | 0.25 | 0 |
particles.opacity.anim.sync | 各粒子の不透明度の変化を同期させるか | boolean | true / false | false |
particles.size.value | 粒子のサイズ | number | 20 | 20 |
particles.size.random | 粒子のサイズをランダムにするか | boolean | true / false | false |
particles.size.anim.enable | 粒子のサイズを変化させるか | boolean | true / false | false |
particles.size.anim.speed | 粒子のサイズを変化速度 | number | 3 | 20 |
particles.size.anim.size_min | 粒子の最小サイズ | number | 0.25 | 0 |
particles.size.anim.sync | 各粒子の最小サイズを同期させるか | boolean | true / false | false |
particles.line_linked.enable | 粒子を線でつなぐか | boolean | true / false | true |
particles.line_linked.distance | 粒子を繋ぐ線の間隔 | number | 150 | 100 |
particles.line_linked.color | 粒子を繋ぐ線の色 | HEX (string) | “#ffffff” | “#fff” |
particles.line_linked.opacity | 粒子を繋ぐ線の不透明度 | number (0 to 1) | 0.5 | 1 |
particles.line_linked.width | 粒子を繋ぐ線の幅 | number | 1.5 | 1 |
particlesオプション(アニメーション)一覧
key | 説明 | option type / notes | example | default |
particles.move.enable | 粒子をアニメーションするか falseだと静止 | boolean | true / false | true |
particles.move.speed | 粒子のアニメーション速度 | number | 4 | 2 |
particles.move.direction | 移動方向を指定 none : 上下左右から自由に移動 top : 下から上へ top-right : 左下から右上へ right : 左から上へ bottom-right : 左上から右下へ bottom : 上から下へ bottom-left : 右上から左下へ left : 左から右へ top-left : 右下から左上へ | string | “none” “top” “top-right” “right” “bottom-right” “bottom” “bottom-left” “left” “top-left” | “none” |
particles.move.random | 移動方向へ向かってランダムに移動するか | boolean | true / false | false |
particles.move.straight | 移動方向へ向かって真っすぐに移動するか | boolean | true / false | false |
particles.move.out_mode | 粒子が画面端に来た時 out : 画面外へ消える bounce : 跳ね返る | string (out of canvas) | “out” “bounce” | “out” |
particles.move.bounce | 粒子が跳ね返るか | boolean (between particles) | true / false | false |
particles.move.attract.enable | シェイプをひきつけるか? | boolean | true / false | false |
particles.move.attract.rotateX | 0 : そのうち粒子は画面から消える | number | 3000 | 3000 |
particles.move.attract.rotateY | 0 : そのうち粒子は画面から消える | number | 1500 | 3000 |
補足説明
particles.move.attract.enable について、正直このオプションの意味するところが今一つ分からなかったのです。
ここでは、「シェイプをひきつけるか?」という説明にとどめています(後にはっきりと分かったら追記します)。シェイプが発生した位置からの移動距離を制限するか、ということでは?と思っております。
疑問が払拭できず幾度か試した結果、一つ分かったことは、これをtrueにしマウスイベントでシェイプの数を増加した場合、派生したシェイプの移動距離が制限されていることです。元から存在するシェイプも同様かもしれません。
一方、falseにした時は、シェイプは制限なく移動し広がっていきます。
そして、それに続く以降の rotateX 、rotateY はシェイプの移動の幅・高さと関連しているように見えます。
後述の「オプションを変更(クリックで★が増えるイメージ) 」の項のCODEPENの中で★のシェイプをクリックしてみてください。
どのようなアニメーションになるか実感できると思います。
個人的結論にはなり恐縮ですが、このオプションはデフォルトのままでも特に問題ないと思います。
下手に数値を小さくするとアニメーションが不自然になってしまうことがあります。
気になる方はデモページでお試しされることをお薦めします。
interactivity・retina_detect オプション一覧
key | 説明 | option type / notes | example | default |
interactivity.detect_on | マウスイベントを許可する要素を指定 | string | “canvas”, “window” | “canvas” |
interactivity.events.onhover.enable | カーソルを近づけた時の粒子の動き制御するか | boolean | true / false | true |
interactivity.events.onhover.mode | カーソルを近づけた時の粒子の動き grab : マウスを中心に粒子が線で繋がる bubble : 近くの粒子が強調される repulse : マウスから粒子が離れていく | string array selection | “grab” “bubble” “repulse” [“grab”, “bubble”] | “grab” |
interactivity.events.onclick.enable | マウスクリックした時、イベントを発生させるか | boolean | true / false | true |
interactivity.events.onclick.mode | マウスクリックした時のイベント push : クリックした位置で粒子が増加 remove : クリックした粒子は消滅 bubble : 近くの粒子が強調される(onhover.mode がbubbleの時は効かない) repulse : マウスから粒子が離れていく (onhover.modeがrepulse の時は効かない) | string array selection | “push” “remove” “bubble” “repulse” [“push”, “repulse”] | “push” |
interactivity.events.resize | マウスイベントで粒子のサイズを変更するか | boolean | true / false | true |
interactivity.events.modes.grab.distance | マウスイベントで粒子が繋がる距離 | number | 100 | 100 |
interactivity.events.modes.grab.line_linked.opacity | マウスイベントで粒子を繋ぐ線の不透明度 | number (0 to 1) | 0.75 | 1 |
interactivity.events.modes.bubble.distance | マウスイベントでk強調されるマウスと粒子の距離 | number | 100 | 200 |
interactivity.events.modes.bubble.size | マウスイベントで強調される粒子のサイズ | number | 40 | 80 |
interactivity.events.modes.bubble.duration | マウスイベントで粒子を強調する速度 | number (second) | 0.4 | 0.4 |
interactivity.events.modes.repulse.distance | マウスイベントで離れる粒子の距離 | number | 200 | 200 |
interactivity.events.modes.repulse.duration | マウスイベントで離れる粒子の速度 | number (second) | 1.2 | 0.4 |
interactivity.events.modes.push.particles_nb | マウスイベントで増加する粒子の数 | number | 4 | 4 |
interactivity.events.modes.remove.particles_nb | マウスイベントで減少する粒子の数 | number | 4 | 2 |
retina_detect | Retinaディスプレイ対応に対応するか | boolean | true / false | false |
オプション記述方法
以下は、公式のCODEPEN (赤い背景に白の無限の粒子が生じて線で繋がり自由に動く )のJSファイルを一部(長いため)転載させていただいていますので、記述例の参考としてご覧ください。
particlesJS("particles-js", {
"particles": {
"number": {
"value": 380,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#ffffff"
},
/* 途中省略 */
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "grab"
},
"onclick": {
"enable": true,
"mode": "push"
},
"resize": true
},
/* 途中省略 */
},
"retina_detect": true
});
/* ---- stats.js config ---- */
/* 以降は、アニメーションをモニタリングする別のJSの内容が記載されていますので、省略しています */
記述例を以降にも記載していますが、 オプションが多くてどこから手を付けていいか途方に暮れるかもしれません。
しかし、心配しなくても大丈夫です。
公式デモの右側パネルを操作して自分のイメージを作成できたら、右上の「CodePen」ボタンを押します。
そうすると、自分が作成したコードが表示されるので、それをコピペすればOKです。
但し、var以降はアニメーションの状態(particleの数等)をモニタリングする別のプラグイン stats.js のコードですので、コピーは不要です。
また、表示されたコードはcompressed(余白等を取り除いた圧縮)されたもののため、そのままコピペすると見づらいと思います。
よって、読みやすい表記に変換してくれるジェネレーター、unminify、IPVOID Unminify JS Code、 Online CSS Unminifier 等を使用されるとよいと思います。
もとの見やすい状態に戻ったら、オプションの内容がよく見えはずです。
この時、不要なもの・デフォルトのオプションも含まれていることがあるため、気づいたら削除してしまいましょう。
オプションを変更(流星群のイメージ)
「Run Pen」をクリックしてください。
HTMLファイルでは、canvasとなる要素の子要素にPタグを配置していますが、出力されるときにはこのPタグは、canvas要素の外に追いやられます。
おそらく、canvas要素に図形を描画する時、その子孫要素は無視されてしまうため( canvas内の描画によって上書きされる)、このような処理がなされていると思います。
そのため、PタグはCSSのpositionプロパティで、canvasに重ねるように調整しました。
CODEPENで確認
See the Pen particles.js meteor shower by blue moon (@blue-moon) on CodePen.
HTMLファイル
<body>
<div id="particles-js">
<p>meteor shower</p>
</div>
<!-- particles.js -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
<script src="particles.js"></script>
<!-- ご自身のパスに変更 -->
<script src="main.js"></script>
</body>
CSSファイル
body {
margin: 0;
}
#particles-js {
position: absolute;
width: 100%;
height: 100%;
background-image: linear-gradient(-20deg, #00008b 0%,#000033 100%);
}
p {
color: #fff;
text-align: center;
font-size: 20px;
}
/* Pタグをcanvasの中に納める */
canvas {
position: absolute;
top: 0;
}
JSファイル
particlesJS("particles-js", {
particles: {
number: {
value: 80,
density: {
enable: true,
value_area: 480.51896047731543
}
},
color: {
value: "#ffffff"
},
shape: {
type: "circle",
},
opacity: {
value: 1,
random: true,
anim: {
enable: true,
speed: 1,
opacity_min: 0,
sync: false
}
},
size: {
value: 2,
random: false,
anim: {
enable: true,
speed: 170,
size_min: 4,
sync: false
}
},
line_linked: {
enable: false,
},
move: {
enable: true,
speed: 20,
direction: "bottom-right",
random: false,
straight: true,
out_mode: "out",
bounce: false,
}
},
interactivity: {
detect_on: "window",
events: {
onhover: {
enable: false,
},
onclick: {
enable: false,
},
},
},
retina_detect: true
});
オプションを変更(クリックで★が増えるイメージ)
このパターンでは、canvas内でクリックすると 星形のシェイプが増加します。
あくまで実験的に作成したものなので、デザイン的にはイマイチですが、ご了承ください。
こちらは流星群のイメージと違って、 interactivity.detect_onオプションをwindowからcanvasに変更していますが、前項のパターンと同様、canvas要素の子要素が親要素から追いやられている点は同じです。
CODEPENで確認
See the Pen particles.js star by blue moon (@blue-moon) on CodePen.
HTMLファイル
<body>
<div id="particles-js">
<p>star</p>
</div>
<!-- particles.js -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
<script src="particles.js"></script>
<!-- ご自身のパスに変更 -->
<script src="main.js"></script>
</body>
CSSファイル
body {
margin: 0;
}
canvas {
display: block;
vertical-align: bottom;
}
/* canvasの中に収める */
p {
position: absolute;
left: calc(50% - 25px);
margin: 1em auto 0;
width: 50px;
color: #fff;
text-align: center;
font-size: 20px;
}
#particles-js {
position: absolute;
width: 100%;
height: 100%;
background-color: #c7a9d4;
}
JSファイル
particlesJS("particles-js", {
particles: {
number: {
value: 20,
density: {
enable: true,
value_area: 480.51896047731543
}
},
color: {
value: "#fff343"
},
shape: {
type: "star",
polygon: {
nb_sides: 5
},
},
opacity: {
value: .8969687262243222,
anim: {
enable: true,
speed: 1,
opacity_min: .2,
}
},
size: {
value: 20,
random: true,
anim: {
enable: true,
speed: 10,
size_min: 3,
}
},
line_linked: {
enable: false,
},
move: {
speed: 5,
random: true,
out_mode: "bounce",
bounce: false,
attract: {
enable: true,
rotateX: 10,
rotateY: 1200
}
}
},
interactivity: {
detect_on: "canvas",
events: {
onhover: {
enable: false,
},
onclick: {
enable: true,
mode: "push"
},
resize: true
},
modes: {
push: {
particles_nb: 4
},
}
},
retina_detect: true
});
まとめ
全てのオプションを解説したうえで、実装パターンまでご紹介しましたが、参考になりましたでしょうか。
もちろんcanvas要素を使用して、ライブラリなしで図形を描画したりすることも可能です。
しかし、折角このような軽量でアニメーションのパターンが無限に広がるライブラリがあるのなら、使わない手はありません。
前述の bubbly-bg.js と大きく違う点を3つ挙げるとすると、以下のようになると思います(もちろん他にも多数ありますがライブラリ採用の参考として挙げるとしたらです)。
- 背景のグラデーションの設定がなく(CSSで自作すれば問題ないですが)、シェイプの色が背景の色と関係性を持たないこと。
- マウスイベント(マウスオーバーとクリック)があり、シェイプがマウスカーソルの位置から離れていったり、増加したり、減少したりするアニメーションが実装可能ということ。
- 公式デモページがジェネレーターの役割を果たしていて、生成されたコードをコピペ可能であること。
以上、背景アニメーションのライブラリ採用の参考になれば幸いです。
※後日追記
3D背景アニメーションのJSライブラリについても投稿いたしましたので、ご参考までに。