JSライブラリBeautiful bubbly backgroundsのご紹介です。
泡と背景色を何色にするか悩む程度で、あっという間に泡のアニメーションを実装できます。
オプションは複数あるのですが複雑なことを望まなければ、悩むことはほとんどありません。しかし、その簡単さがゆえに、オプションの詳細説明がなく、試行錯誤しながら自分が納得がいくアニメーションを決めていく作業になるのです。
筆者もオプションをよく理解できていないまま実装していました。
その作業でもよいのですが、オプションの意味を理解していれば時短にもなりますし、より思い描いた泡のアニメーションを実装可能だと思います。
今回はオプションを徹底調査し、あわせて実際にCODEPENでオプションを追加したものをご紹介しています。
bubbly-bg.js
公式ページ
使用方法が簡潔に記載されています。
そのため、導入の難易度は低いと思います。
中央に表示されるイメージをクリックするとサイトのbody全体に泡のアニメーションが発生します。
特徴
簡単な設定・短時間で、サイト上に美しい泡が動くアニメーションを表示してくれるjQuery非依存のライブラリです。
HTMLファイルのbodyタグ直前に記述することも可能です。
ユーザーにはアクセスの都度、ランダムに変化するアニメーションを表示してくれます(同じものが再現されない)。
しかも、軽量でJSファイルは必須ではありません。
なぜ軽量かというと、HTML5から追加された図形描写の技術仕様Canvasと、JavaScriptを組み合わせて図形を描画します。つまり、スクリプトで図形を描写することになるため、画像と比べてデータ量を軽量することが可能になります。
使用方法概略
使用するファイル
- HTMLファイル
- CSSファイル
- JSファイル(オプションによっては必要。ウィンドウ幅によって泡の数を変更したい場合等)
使用方法
HTMLファイルでライブラリをCDNで読み込みます。
<body>
<!-- 途中省略 -->
<script src="https://cdn.jsdelivr.net/npm/bubbly-bg@1.0.0/dist/bubbly-bg.js"></script>
<script>bubbly();</script> <!-- オプションなしのデフォルトの場合はこれだけでもOK -->
</body>
オプション
オプション | デフォルト | |
animate | アニメーションするか(するでしょう)。 値は以下から選択 true 、false | true |
blur | 泡のぼかし具合 数値が大きくなると、泡のぼかし具合が大きくなる。 | 4 |
bubbleFunc | 色を定義(色相、彩度、明度、透明度) | () => `hsla(0, 0%, 100%, ${r() * 0.1})` 最後のアルファの値に使用されている変数(関数)r()は、Math.random()、つまりランダムな値を生成する関数のようですが、そのまま使用するとエラーが出ますのご注意ください。 ※Mathメソッドについては後述の補足説明③を参照 |
bubbles | 泡の数 数値または、計算式を指定 数値で指定すると、Window幅変更時、当然泡の数は変わらないので密度が変更してしまいます。 よって、デフォルトから変更する場合はJS及びjQueryでWindow幅を計測し、計算式で指定した方がよい場合があります。 記述例は後述の「 オプションを変更(夕闇に雪が降るイメージ) 」の項目を参照してください。 | Math.floor((canvas.width + canvas.height) * 0.02) 泡を描画する要素の幅と高さを加算後、0.02倍にし、小数点以下切り下げた数 |
canvas | 泡を描画する要素を指定 ※後述の補足説明①を参照 | body |
colorStart | 泡の背景(泡を描画する要素)のグラデーションの始まりの色 要素の左上部分の色 | blue-ish 青系の色 |
colorStop | 泡の背景(泡を描画する要素)のグラデーションの終わりの色 要素の右下部分の色 | blue-ish 青系の色 |
compose | 泡が重なった時の描画方法 globalCompositeOperation属性を指定 ※後述の補足説明②を参照 | lighter |
shadowColor | 泡の影 | #fff |
angleFunc | 泡の移動角度 弧度法による角度を指定 0の場合は左から右へ水平方向に移動 ※弧度法については、補足説明④を参照 | () => Math.random() * Math.PI * 2 ランダムな値に弧度法による角度を乗算 |
velocityFunc | 泡の速度 | () => 0.1 + Math.random() * 0.5 0.1に、ランダムな値を0.5倍したものを加算 |
radiusFunc | 泡の半径 | () => 4 + Math.random() * 25 4 に、ランダムな値を0.25倍したものを加算 |
補足説明
① canvas
オプションのプロパティにもなっている、HTMLの<canvas>要素は、HTML5から追加された図形を描く技術仕様です。
このライブラリでも要素を指定したあと、getContextメソッドにより描画機能を有効にしています。
特に注意したい点がいくつかあります。
まず、canvasに指定する要素のHTMLのタグは<canvas></canvas>としてください 。
指定方法の記述例は、後述の「 オプションを変更(カラフルなイメージ) 」の項を参照してください。
そして、このセレクターに対して幅を指定すると、高さは自動で決まるようです。ここで高さをpxで指定すると、canvasの中の泡が歪んでしまいました。
また、 <canvas> タグの中の子要素は無視されてアニメーションが上書きされてしまいますので、 <canvas> タグの中に含めたいものがあれば兄弟要素とし、CSSのpositionプロパティでレイヤーのように重ねる等工夫が必要です。
② globalCompositeOperation属性
例えば、イメージAが描画された後にイメージBが描画されたとします。
この2つが重なった時の合成方法は一般的には下記の表の各セルの最初の1文のようになります。
但し、これら全て試してみたところ、効くものと効かないものがありました(2文目以降に記載)。
もともと、このアニメーションにはそぐわないものも含まれておりますが、このアニメーションには、 source-over 、 lighter(デフォルト)あたりを選択するのが無難ではないかと思われます。
値 | 合成方法 |
source-atop | イメージBはイメージAと重なった部分のみ描画される。 泡Bは泡Aが合成された色で描画される。 泡の色によっては効かない。 |
source-in | イメージAとイメージBが重なった部分のみ描画される。 効かない。 |
source-out | イメージAは消え、イメージBはイメージAと重なった部分は描画されない。 泡が1つしか描画されない。 |
source-over | イメージAの前面にイメージBが描画される。 泡Bは泡Aが合成された色で描画される。 |
destination-atop | イメージAはイメージBと重なった部分のみ描画される。 泡が1つしか描画されない。 |
destination-in | イメージAはイメージBと重なった部分のみ描画され、イメージBは消える。 効かない。 |
destination-out | イメージAはイメージBと重なっていない部分のみ描画され、イメージBは描画されない。 泡の色によっては効かない。 泡が白くなる。 |
destination-over | イメージAの背面にイメージBが描画される 効かない。 |
lighter | イメージAとイメージB両方描画され、重なり部分は両方の色の混色となる。 デフォルト |
copy | イメージBのみ描画され、イメージAは消える。 泡が1つしか描画されない。 |
xor | イメージAとイメージBの重なった部分のみ描画されない。 泡Aと泡B両方描画され、重なり部分は両方の色の混色となる。泡の色によっては効かない。 |
③ Math メソッド
Mathメソッドについて一部MDNより引用させていただき、要約して説明いたします。
Math.floor()
Math.floor() 関数は与えられた数値以下の最大の整数を返します。
MDN 開発者向けのウェブ技術 > JavaScript > JavaScript リファレンス > 標準組込みオブジェクト > Math > Math.floor()
オプション説明一覧では「最大の整数」というのは省略して、単に「切り捨て」と記述しております。なぜなら、泡の数が負の値になることはないためです。
よって、正しくは上記の引用にある通りで、例えば、「3.2」の場合は「3」になり、「-3.2」の場合は「-4」になります。
Math.PI
Math.SQRT2 プロパティは、円周と直径の比率、およそ 3.14159 を表します。
MDN 開発者向けのウェブ技術 > JavaScript > JavaScript リファレンス > 標準組込みオブジェクト > Math > Math.PI
PIはMathオブジェクトの静的プロパティなので、Mathオブジェクトを生成してプロパティとして使用するのではなく、常に Math.PI として使用するようにしてくださいは(Math コンストラクターではありません)。
上記引用部分の「Math.SQRT2」は、おそらく「Math.PI」の記述ミスではないかと、確証はできませんが。
特定の半径の円周を計算する時に使用したりするものです。
Math.randome()
Math.randome() 関数は、 0 以上 1 未満 (0 は含むが、 1 は含まない) の範囲で浮動小数点の擬似乱数を返します。その範囲ではほぼ均一な分布で、ユーザーは範囲の拡大をすることができます。実装側で乱数生成アルゴリズムの初期シードを選択します。ユーザーが初期シードを選択、またはリセットすることは出来ません。
MDN 開発者向けのウェブ技術 > JavaScript > JavaScript リファレンス > 標準組込みオブジェクト > Math > Math.floor()
少し難解な説明です。
ここでは、ランダムな値を返すと解釈すれば足りると思います。
なお、引数に数値を与えれば、その範囲内でランダムな値を返します。
④ 弧度法
半径と等しい弧の長さの時、その扇形の中心角度を1(単位のラジアンは省略)とする角度の表し方です。
一方、一般的な「90度」という角度の表し方は、度数法といいます。
計算方法 1°=π/180 で計算し変換したものが下記になります。最初の方は15°単位で計算しましたが、60°からは30°単位で計算しています。
度数法 | 15 | 30 | 45 | 60 | 90 | 120 | 150 |
弧度法 | π/12 | π/6 | π/4 | π/3 | π/2 | 2/3π | 5/6π |
度数法 | 180 | 210 | 240 | 270 | 300 | 330 | 360 |
弧度法 | π | 7/6π | 4/3π | 3/2π | 5/3π | 11/6π | 2π |
と記載はしたものの、実際に計算式に当てはめるのはやっぱり難しいですので、デモや後述する例を参考にした方がスムーズだと思います。
公式デモページ記載の下2つのコードを確認
泡が下から出現し上昇
<script>
bubbly({
blur:15,
colorStart: '#194167',
colorStop: '#112144',
radiusFunc:() => 5 + Math.random() * 15,
angleFunc:() => -Math.PI / 2,
velocityFunc:() => Math.random() * 7.5,
bubbleFunc:() => `hsla(${200 + Math.random() * 50}, 100%, 65%, .1)`,
bubbles:350
});
</script>
泡が左右から出現し水平方向に移動
<script>
bubbly({
colorStart: '#d5d5d5',
colorStop: '#d5d5d5',
bubbles:400,
blur:1,
compose: 'source-over',
bubbleFunc:() => `hsla(${200 + Math.random() * 50}, 100%, 50%, .3)`,
angleFunc:() => Math.random() > 0.5 ? Math.PI : 2 * Math.PI,
velocityFunc:() => 1 + Math.random() * 10,
radiusFunc:() => Math.random() * 5
});
</script>
GtHubには掲載されていコードだったため、参考になります。
次からの項では、オプションを踏まえた上で上記コードを参考にし、公式ページとは別のものを実装してみます。
オプションを変更(夕闇に雪が降るイメージ)
「Run Pen」をクリックしてください。
このパターンでは、泡の数を画面幅によって変更したいため、JSファイルを使用しています。
また、画面が読み込まれた時とリサイズされた時に対応するため、jQueryを使用しています。
CODEPENで確認
See the Pen bubbly_snow by blue moon (@blue-moon) on CodePen.
HTMLファイル
<body>
<p>sunset & snow</p>
<script src="https://cdn.jsdelivr.net/npm/bubbly-bg@1.0.0/dist/bubbly-bg.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- jQuery読み込み --> -->
<script src="main.js"></script> <!-- ご自身のパスに変更 -->
</body>
CSSファイル
p {
margin-top: 20px;
font-size: 20px;
letter-spacing: 0.1em;
text-align: center;
color: #fff;
}
JSファイル
$(window).on('load resize', function() { // 画面読み込み時とリサイズ時
const w = window.innerWidth; // 泡の数を計算するため画面幅を取得
const h = window.innerHeight; // 泡の数を計算するため画面高さを取得
bubbly({
angleFunc:() => Math.PI / 1.8 , // Math.PI / 2 の場合は真上から落ちてくる
blur: 1.5,
bubbles: Math.floor((w + h) * 0.05),
bubbleFunc:() => 'hsla(0, 0%, 70%, .5)',
colorStart: '#161666',
colorStop: '#ffa07a',
compose: 'source-over',
velocityFunc:() => Math.random() * 2,
radiusFunc:() => Math.random() * 5,
});
});
オプションを変更(カラフルなイメージ)
このパターンでは、JSファイルは使用していません。
前述のパターンと大きく異なる点は、泡を発生させる要素をデフォルトのbodyから、指定する要素に変更している点です。
CODEPENで確認
See the Pen bubbly_colorful by blue moon (@blue-moon) on CodePen.
HTMLファイル
<body>
<canvas id="back"></canvas> <!-- アニメーションする要素 -->
<div class="title">
<p>colorful</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bubbly-bg@1.0.0/dist/bubbly-bg.js"></script>
<script>
bubbly({
blur: 5,
bubbleFunc: () => `hsla(${Math.random() * 350}, 90%, 50%, ${Math.random() * 0.3})`,
canvas: document.querySelector("#back"), // アニメーションする要素を指定
colorStart: '#1effff',
colorStop: '#ffff1e',
compose: 'source-over',
shadowColor: '#ffffef',
velocityFunc:() => Math.random() * 1.4,
radiusFunc:() => 3 + Math.random() * 20,
});
</script>
</body>
CSSファイル
#back {
margin: auto;
width: 100%;
}
.title {
position: fixed;
top: 3%;
left: 10%;
width: 80%;
text-align: center;
}
p {
font-size: 20px;
letter-spacing: 0.1em;
color: #fff;
}
まとめ
オプションを解説したうえで、実装パターンをご紹介しましたが、参考になりましたでしょうか。
アニメーションのパターンは無限ですし、デフォルトを活用すれば簡単に実装できますので、気軽にお試しください。
最初から、オプションス多く追加していくことを前提に進めていくと難しく感じるので、まずはデフォルトで試し、変更したい部分を少しずつオプション追加していく方法がよいか思います。
※後日追記
下記でも同様の背景アニメーションのJSライブラリを紹介しています。