ついに・・・この鳩でもわかるC#も更新1000回の日を迎えることになりました。大きな節目である1000回更新の記事として何をするか? そうだ、紙吹雪を表示するアプリをつくってみようと思って調べてみるとCanvas Confettiというライブラリが見つかりました。
Contents
紙吹雪を表示させるならCanvas Confetti一択?
使い方は驚くほど簡単です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>簡単にできる紙吹雪</title> <meta name = "viewport" content = "width=device-width, initial-scale = 1.0"> </head> <body> <script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.3.2/dist/confetti.browser.min.js"></script> <script> confetti(); </script> </body> </html> |
なんと <script src=”https://cdn.jsdelivr.net/npm/canvas-confetti@1.3.2/dist/confetti.browser.min.js”></script> を入れたあと、confetti();とやるだけです。実質たったの2行で紙吹雪の描画処理ができてしまうのです。
またオプションを指定することでさまざまな紙吹雪を生成することができます。
particleCountで紙吹雪の数を変更する
デフォルトだと実行時の紙吹雪の数は50です。particleCountで紙吹雪の数を変更することができます。
ticksで紙吹雪の数を変更する
またデフォルトの設定だと紙吹雪が表示されてから少し下に落ちると消えるようになっています。消えるタイミングを遅らせるためにはticksの値を大きくすればよいです。1000にすると途中で消えてしまうことはなくなります。
colorsで紙吹雪の色を指定する
colorsで紙吹雪の色を指定することができます。以下のコードだと赤、緑、青の3色だけの紙吹雪が生成されます。
1 2 3 4 5 6 7 8 9 |
<script> confetti({ colors: [ '#f00', '#0f0', '#00f', ] }); </script> |
spreadで紙吹雪が飛ぶ角度を変更する
spreadで紙吹雪が飛ぶ角度を変更することができます。30のように小さな値にすると紙吹雪がクラッカーを上に向けて発射したような飛び方をします。また360を指定すると打ち上げ花火のような紙吹雪になります。
1 2 3 4 5 |
<script> confetti({ spread: 30, }); </script> |
その他
1 2 3 4 5 6 7 8 9 10 11 12 |
<script> confetti({ angle: 90, // 紙吹雪が飛ぶ方向(指定しないと90=上向き) startVelocity: 20, // 紙吹雪が上に飛ぶ速度 scalar: 2, // 紙吹雪の大きさ gravity: 1, // 重力 (0にすると紙吹雪が落ちない) origin: { x: 0.5, // 紙吹雪の発生場所(両方とも0.5にすると中央) y: 0.5 }, }); </script> |
自分で生成したcanvas上で使いたいとき
画面全体ではなく特定のcanvasタグに描画する場合はcanvasタグにidを付けて以下のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>紙吹雪をcanvas要素に描画</title> <meta name = "viewport" content = "width=device-width, initial-scale = 1.0"> </head> <body> <canvas id = "canvas"></canvas> <script src = "https://cdn.jsdelivr.net/npm/canvas-confetti@1.3.2/dist/confetti.browser.min.js"></script> <script> const $canvas = document.getElementById('canvas'); $canvas.width = 500; $canvas.height = 500; $canvas.style.backgroundColor = '#000'; $canvas.confetti = confetti.create($canvas, { resize: true }); $canvas.confetti({ // オプションの指定も可能(もちろん省略も可能) angle: 90, spread: 50, particleCount: 100, ticks: 1000, startVelocity: 20, scalar: 2, gravity: 1, origin: { x: 0.5, y: 0.5 }, }); </script> </body> </html> |
Canvas Confettiのオプションをテストするアプリ
Canvas Confettiのオプションを変更してどのような紙吹雪が生成されるかテストするアプリを作ってみることにします。
HTML部分を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Canvas Confettiのテスト</title> <meta name = "viewport" content = "width=device-width, initial-scale = 1.0"> <style> .range { width: 200px; } </style> </head> <body> <table> <tr><td>angle</td><td><input type="range" id = "angle" class = "range"></td><td id = "angle-value"></td></tr> <tr><td>spread</td><td><input type="range" id = "spread" class = "range"></td><td id = "spread-value"></td></tr> <tr><td>startVelocity</td><td><input type="range" id = "start-velocity" class = "range"></td><td id = "start-velocity-value"></td></tr> <tr><td>scalar</td><td><input type="range" id = "scalar" class = "range"></td><td id = "scalar-value"></td></tr> <tr><td>gravity</td><td><input type="range" id = "gravity" class = "range"></td><td id = "gravity-value"></td></tr> <tr><td>particleCount</td><td><input type="range" id = "particle-count" class = "range"></td><td id = "particle-count-value"></td></tr> <tr><td>ticks</td><td><input type="range" id = "ticks" class = "range"></td><td id = "ticks-value"></td></tr> <tr><td>x</td><td><input type="range" id = "x" class = "range"></td><td id = "x-value"></td></tr> <tr><td>y</td><td><input type="range" id = "y" class = "range"></td><td id = "y-value"></td></tr> </table> <button onclick="createConfetti()">紙吹雪を生成する</button> <button onclick="init()">初期設定に戻す</button> <script src = "https://cdn.jsdelivr.net/npm/canvas-confetti@1.3.2/dist/confetti.browser.min.js"></script> <script src = "./index.js"></script> </body> </html> |
グローバル変数と定数を示します。要素を定数に格納して値の取得と設定ができるようにしておきます。arr2はレンジスライダーのmin、max、step、valueです。arr3はレンジスライダーのvalueを表示させる部分の要素です。
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
const $angle = document.getElementById('angle'); const $spread = document.getElementById('spread'); const $startVelocity = document.getElementById('start-velocity'); const $scalar = document.getElementById('scalar'); const $gravity = document.getElementById('gravity'); const $particleCount = document.getElementById('particle-count'); const $ticks = document.getElementById('ticks'); const $x = document.getElementById('x'); const $y = document.getElementById('y'); const $angleValue = document.getElementById('angle-value'); const $spreadValue = document.getElementById('spread-value'); const $startVelocityValue = document.getElementById('start-velocity-value'); const $scalarValue = document.getElementById('scalar-value'); const $gravityValue = document.getElementById('gravity-value'); const $particleCountValue = document.getElementById('particle-count-value'); const $ticksValue = document.getElementById('ticks-value'); const $xValue = document.getElementById('x-value'); const $yValue = document.getElementById('y-value'); const arr1 = [$angle, $spread, $startVelocity, $scalar, $gravity, $particleCount, $ticks, $x, $y]; const arr2 = [ [0, 360, 1, 90], // $angle, [0, 360, 1, 90], // $spread, [0, 100, 1, 20], // $startVelocity, [0.1, 10, 0.1, 2], // $scalar, [0, 10, 0.1, 1], // $gravity, [1, 500, 1, 100], // $particleCount, [1, 2000, 1, 200], // $ticks, [0, 1, 0.01, 0.5], // $x, [0, 1, 0.01, 0.5], // $y ]; const arr3 = [$angleValue, $spreadValue, $startVelocityValue, $scalarValue, $gravityValue, $particleCountValue, $ticksValue, $xValue, $yValue]; |
ページが読み込まれたらレンジスライダーを初期化して値を設定します。またイベントリスナを追加してレンジスライダーのvalueが変更されたらその値を表示できるようにします。
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
window.onload = () => { init(); for(let i = 0; i < arr1.length; i++) arr1[i].oninput = () => arr3[i].innerText = arr1[i].value; } function init(){ // レンジスライダーの初期化(min、max、step、valueの設定) for(let i = 0; i < arr1.length; i++){ arr1[i].min = arr2[i][0]; arr1[i].max = arr2[i][1]; arr1[i].step = arr2[i][2]; arr1[i].value = arr2[i][3]; } // レンジスライダーのvalueを取得して表示 for(let i = 0; i < arr1.length; i++) arr3[i].innerText = arr1[i].value; } |
[紙吹雪を生成する]ボタンがクリックされたらレンジスライダーからvalueを取得してオプションを指定してconfettiを実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function createConfetti(){ confetti({ angle: Number($angle.value), // 紙吹雪が飛ぶ方向(指定しないと90=上向き)90 spread: Number($spread.value), startVelocity: Number($startVelocity.value), // 紙吹雪が上に飛ぶ速度20 scalar: Number($scalar.value), // 紙吹雪の大きさ2 gravity: Number($gravity.value), // 重力 (0にすると紙吹雪が落ちない)1 origin: { x: Number($x.value), // 紙吹雪の発生場所(両方とも0.5にすると中央)0.5 y: Number($y.value), }, particleCount: Number($particleCount.value),//100 ticks: Number($ticks.value),//1000 }); } |