Created
July 5, 2023 13:08
-
-
Save kujirahand/f59b4b8c0c159e4f7d67c79e18e84cd0 to your computer and use it in GitHub Desktop.
Canvas APIを使って花火を打ち上げる
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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