この記事は CSS Advent Calendar 2019 の22日目の記事です。
「CSSでこんなこともできるんだ」くらいの軽い気持ちで読んでいただけたら嬉しいです。
パーティクルアニメーションとは?
「パーティクル」とは粒子のこと。
この粒子に様々な動きや変化を与えることで、神秘的な演出・派手な演出・キュートな演出など、さまざまな表現が可能になります。
CSSで描いてみた
以下は、CSSで制作したパーティクルアニメーションのサンプルです。
※Qiita上では動作が重いことがあります。
※サンプル右上のCodePenロゴからご覧いただくのがオススメです。
※スマートフォンでは綺麗に表示されない場合があります。
See the Pen Particle Rotation #02 by Hisami Kurita (@hisamikurita) on CodePen.
解説
このサンプルでは、CSSアニメーションを使用しています。
以下に、技術的なポイントを解説していきます。
Pug + SCSS
メタ言語の Pug と SCSS を使用しています。
主な用途は以下の2つです:
-
for文
で多数の要素(ここでは200個)を生成する - 各要素に固有のスタイルを適用する
Pugのコード(例)
- for (var i = 0; i < 200; i++)
div.rotate
div.flip_rotate
div.flip_pos
div.flip
変換後のHTML
<div class="rotate">
<div class="flip_rotate">
<div class="flip_pos">
<div class="flip"></div>
</div>
</div>
</div>
<!-- 上記が200個生成されます -->
SCSSのコード(例)
@for $i from 1 through 200 {
.rotate:nth-of-type(#{$i}) {
// 各要素に固有スタイルを設定
}
}
変換後のCSS(例)
.rotate:nth-of-type(1) { }
.rotate:nth-of-type(2) { }
/* ...省略... */
.rotate:nth-of-type(200) { }
補足:
HTMLとCSSだけでも実装できますが、200個すべてに個別スタイルを当てるのは非常に大変です 😅
そのためメタ言語を使うことで効率的にコーディングしています。
ランダム関数 random()
パーティクルアニメーションでは、動きにランダム性を加えることで自然さを出します。
animation: rotation linear infinite reverse;
animation-duration: random(50000) + 20000 + ms;
このコードでは:
-
0〜49999ms
のランダムな値に20000ms
を加算 - 結果として、
20001ms〜70000ms
の範囲でランダムなアニメーション時間が設定されます
→ 極端に短い or 長い動きを避けつつ、バリエーションを持たせることができます。
animation-delay
に負の値を指定する
animation-delay
に負の値を使うことで、「アニメーションがすでに始まっていた」ような見せ方が可能です。
animation: rotation linear infinite reverse;
animation-delay: random(9999) + 50000 * -1ms;
ここでは:
-
-50000ms 〜 -59999ms
の範囲でランダムな開始位置に設定 - これにより、アニメーション開始時点ですでに全体が動いているように見せられます
なお、animation-duration
は 20001ms〜70000ms
の範囲なので、アニメーションがちょうど良いタイミングで収束します。
まとめ
今回の主な技術的ポイントは以下の通りです:
- Pug+SCSSを使った構造とスタイルの効率的な生成
-
random()
関数によるランダムな動きの追加 -
animation-delay
による開始タイミングの制御
パーティクルアニメーションは、数値や色、スピード、配置を少し変えるだけで大きく印象が変わります。
バリエーションサンプル
背景色や奥行き感を変えてバリエーションを作ってみました。
See the Pen Perticle Rotation #03 by Hisami Kurita (@hisamikurita) on CodePen.
よければ、CodePen上でコードをいじって、自由に遊んでみてください!
終わりに
この記事を通して、CSSアニメーションやパーティクル表現に少しでも興味を持っていただけたら幸いです 🙌
作品は週1(目標)で作って CodePen に投稿しています。
よかったらフォローしてください!