File size: 4,831 Bytes
85085e9 | 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | class ParticleSimulator {
constructor(canvasId) {
this.canvas = document.getElementById(canvasId);
this.particles = [];
this.isRunning = false;
this.animationId = null;
this.init();
}
init() {
this.createParticles(25);
this.start();
// Add resize listener
window.addEventListener('resize', () => {
this.handleResize();
});
}
createParticles(count) {
this.particles = [];
const colors = [
'rgba(14, 165, 233, 0.8)',
'rgba(100, 116, 139, 0.8)',
'rgba(2, 132, 199, 0.8)',
'rgba(71, 85, 105, 0.8)'
];
for (let i = 0; i < count; i++) {
const size = Math.random() * 8 + 4;
const particle = {
x: Math.random() * this.canvas.offsetWidth,
y: Math.random() * this.canvas.offsetHeight,
size: size,
speedX: (Math.random() - 0.5) * 3,
speedY: (Math.random() - 0.5) * 3,
color: colors[Math.floor(Math.random() * colors.length)],
trail: []
};
this.particles.push(particle);
}
}
start() {
this.isRunning = true;
this.animate();
}
stop() {
this.isRunning = false;
if (this.animationId) {
cancelAnimationFrame(this.animationId);
}
}
reset() {
this.stop();
this.particles = [];
this.createParticles(25);
this.start();
}
animate() {
if (!this.isRunning) return;
// Clear canvas
this.canvas.innerHTML = '';
// Update and draw particles
this.particles.forEach(particle => {
// Update position
particle.x += particle.speedX;
particle.y += particle.speedY;
// Boundary check
if (particle.x <= 0 || particle.x >= this.canvas.offsetWidth) {
particle.speedX *= -1;
}
if (particle.y <= 0 || particle.y >= this.canvas.offsetHeight) {
particle.speedY *= -1;
}
// Add to trail
particle.trail.push({ x: particle.x, y: particle.y });
if (particle.trail.length > 10) {
particle.trail.shift();
}
// Draw trail
particle.trail.forEach((trailPos, index) => {
const trailElement = document.createElement('div');
trailElement.className = 'particle-trail';
trailElement.style.width = `${particle.size * (index / particle.trail.length)}px`;
trailElement.style.height = `${particle.size * (index / particle.trail.length)}px`;
trailElement.style.left = `${trailPos.x}px`;
trailElement.style.top = `${trailPos.y}px`;
trailElement.style.backgroundColor = particle.color.replace('0.8', `${0.3 * (index / particle.trail.length)}`);
this.canvas.appendChild(trailElement);
});
// Draw particle
const particleElement = document.createElement('div');
particleElement.className = 'particle';
particleElement.style.width = `${particle.size}px`;
particleElement.style.height = `${particle.size}px`;
particleElement.style.left = `${particle.x}px`;
particleElement.style.top = `${particle.y}px`;
particleElement.style.backgroundColor = particle.color;
particleElement.style.boxShadow = `0 0 ${particle.size * 2}px ${particle.color}`;
this.canvas.appendChild(particleElement);
});
this.animationId = requestAnimationFrame(() => this.animate());
}
handleResize() {
this.stop();
this.start();
}
updateParticleCount(count) {
this.stop();
this.createParticles(count);
this.start();
}
}
// Initialize simulator when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
const simulator = new ParticleSimulator('simulationCanvas');
// Add event listeners for control buttons
document.querySelector('button:nth-child(1)').addEventListener('click', () => {
simulator.start();
});
document.querySelector('button:nth-child(2)').addEventListener('click', () => {
simulator.stop();
});
document.querySelector('button:nth-child(3)').addEventListener('click', () => {
simulator.reset();
});
// Add event listeners for sliders
const sliders = document.querySelectorAll('input[type="range"]');
sliders[0].addEventListener('input', (e) => {
simulator.updateParticleCount(parseInt(e.target.value));
});
}); |