Created
September 7, 2025 20:59
-
-
Save goldenratio/49d2653a80323387e54f72e9465df4d3 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Particle System</title> | |
| <style> | |
| body { | |
| margin: 0; | |
| overflow: hidden; | |
| background-color: #1a1a1a; | |
| color: #fff; | |
| font-family: 'Inter', sans-serif; | |
| } | |
| canvas { | |
| display: block; | |
| background: #000; | |
| } | |
| .info { | |
| position: fixed; | |
| top: 10px; | |
| left: 10px; | |
| background: rgba(0, 0, 0, 0.5); | |
| padding: 10px; | |
| border-radius: 8px; | |
| font-size: 14px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="info"> | |
| <p>Particles: <span id="particleCount">0</span></p> | |
| <p>Click and hold to generate more particles.</p> | |
| </div> | |
| <canvas id="particleCanvas"></canvas> | |
| <script> | |
| const canvas = document.getElementById('particleCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| const particleCountElement = document.getElementById('particleCount'); | |
| let particles = []; | |
| let mouse = { x: null, y: null, isDown: false }; | |
| let hue = 0; | |
| // Set canvas size to full window | |
| function setCanvasSize() { | |
| canvas.width = window.innerWidth; | |
| canvas.height = window.innerHeight; | |
| } | |
| setCanvasSize(); | |
| // Event listeners for window and mouse | |
| window.addEventListener('resize', setCanvasSize); | |
| window.addEventListener('mousemove', (event) => { | |
| mouse.x = event.x; | |
| mouse.y = event.y; | |
| }); | |
| window.addEventListener('mousedown', () => { | |
| mouse.isDown = true; | |
| }); | |
| window.addEventListener('mouseup', () => { | |
| mouse.isDown = false; | |
| }); | |
| class Particle { | |
| constructor(x, y) { | |
| this.x = x; | |
| this.y = y; | |
| this.size = Math.random() * 5 + 1; | |
| this.speedX = Math.random() * 3 - 1.5; | |
| this.speedY = Math.random() * 3 - 1.5; | |
| this.color = `hsl(${hue}, 100%, 50%)`; | |
| } | |
| update() { | |
| this.x += this.speedX; | |
| this.y += this.speedY; | |
| if (this.size > 0.2) this.size -= 0.1; | |
| } | |
| draw() { | |
| ctx.fillStyle = this.color; | |
| ctx.beginPath(); | |
| ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); | |
| ctx.fill(); | |
| } | |
| } | |
| function handleParticles() { | |
| for (let i = 0; i < particles.length; i++) { | |
| particles[i].update(); | |
| particles[i].draw(); | |
| // Remove particles that are too small | |
| if (particles[i].size <= 0.2) { | |
| particles.splice(i, 1); | |
| i--; | |
| } | |
| } | |
| } | |
| function createParticles(count, x, y) { | |
| for (let i = 0; i < count; i++) { | |
| particles.push(new Particle(x, y)); | |
| } | |
| } | |
| function animate() { | |
| ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; | |
| ctx.fillRect(0, 0, canvas.width, canvas.height); | |
| handleParticles(); | |
| if (mouse.isDown) { | |
| createParticles(2, mouse.x, mouse.y); | |
| hue = (hue + 1) % 360; | |
| } | |
| particleCountElement.textContent = particles.length; | |
| requestAnimationFrame(animate); | |
| } | |
| // Initial particle creation | |
| createParticles(100, canvas.width / 2, canvas.height / 2); | |
| window.onload = function() { | |
| animate(); | |
| }; | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment