Skip to content

Instantly share code, notes, and snippets.

@kujirahand
Created July 5, 2023 13:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kujirahand/f59b4b8c0c159e4f7d67c79e18e84cd0 to your computer and use it in GitHub Desktop.
Save kujirahand/f59b4b8c0c159e4f7d67c79e18e84cd0 to your computer and use it in GitHub Desktop.
Canvas APIを使って花火を打ち上げる
<!DOCTYPE html><html><head>
<meta name="viewport" content="width=device-width,initial-scale=1">
<body style="background-color: black;">
<!-- 花火を描画するキャンバス-->
<canvas id="fireworks" width="400" height="400"
style="border: 1px solid silver;"></canvas>
</body>
<script>
// HTMLの<canvas>要素を取得
const canvas = document.getElementById('fireworks');
const ctx = canvas.getContext('2d');
// 花火のパーティクルを格納する配列
let fireworks = [];
// パーティクルのクラス
class Particle {
constructor(x, y) {
this.x = x;
this.y = y;
this.color = 'red';
this.radius = 2;
this.speed = Math.random() * 3 + 1;
this.angle = Math.random() * Math.PI * 2;
this.vx = Math.cos(this.angle) * this.speed;
this.vy = Math.sin(this.angle) * this.speed;
this.gravity = 0.05;
this.opacity = 1;
}
update(deltaTime) {
this.x += this.vx * deltaTime;
this.y += this.vy * deltaTime;
this.vy += this.gravity * deltaTime;
this.opacity -= 0.01 * deltaTime;
this.radius -= 0.05 * deltaTime;
// 半径が0未満にならないように制限
if (this.radius < 0) { this.radius = 0; }
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.globalAlpha = this.opacity;
ctx.fill();
ctx.closePath();
}
}
// フレームを更新する関数
let lastTime = 0;
function update() {
// 経過時間を計算
const time = performance.now();
const deltaTime = (time - lastTime) / 100;
lastTime = time;
// キャンバスをクリア
ctx.clearRect(0, 0, canvas.width, canvas.height);
// パーティクルをアップデートして描画
for (let i = 0; i < fireworks.length; i++) {
fireworks[i].update(deltaTime);
fireworks[i].draw();
// 無効なパーティクルを削除
if (fireworks[i].opacity <= 0 || fireworks[i].radius <= 0) {
fireworks.splice(i, 1);
i--;
}
}
// フレームを再描画
requestAnimationFrame(update);
}
// 花火を(cx, cy)に打ち上げる
function launchFireworks(cx, cy) {
const colors = ['orange', 'red', 'yellow'];
for (let i = 0; i < 100; i++) {
const particle = new Particle(cx, cy);
particle.color = colors[Math.floor(Math.random() * colors.length)];
particle.radius = Math.random() * 2 + 1;
fireworks.push(particle);
}
}
// 初期化して花火を打ち上げる
lastTime = performance.now();
update();
setInterval(() => {
const cx = Math.random() * canvas.width;
const cy = Math.random() * canvas.height;
launchFireworks(cx, cy);
}, 100);
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment