Particle Background Animation
Advanced
Interactive particle system with mouse tracking, gravity effects, and customizable configurations. Perfect for hero sections and landing pages.
Live Preview
Code Implementation
HTML
<div class="particle-demo">
<canvas id="particleCanvas"></canvas>
<div class="particle-overlay">
<h1>Interactive Particle System</h1>
<p>Move your mouse to interact with particles</p>
<div class="particle-controls">
<button id="resetBtn">Reset</button>
<button id="gravityBtn">Toggle Gravity</button>
<button id="colorBtn">Change Colors</button>
</div>
</div>
</div>
CSS
.particle-demo {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
#particleCanvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
cursor: crosshair;
}
.particle-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
color: white;
z-index: 2;
pointer-events: none;
}
.particle-overlay h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
font-weight: 700;
}
.particle-overlay p {
font-size: 1.2rem;
margin-bottom: 2rem;
opacity: 0.9;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.particle-controls {
display: flex;
gap: 1rem;
justify-content: center;
pointer-events: auto;
flex-wrap: wrap;
}
.particle-controls button {
padding: 0.75rem 1.5rem;
background: rgba(255, 255, 255, 0.15);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 30px;
color: white;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
backdrop-filter: blur(10px);
font-weight: 500;
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.particle-controls button:hover {
background: rgba(255, 255, 255, 0.25);
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}
.particle-controls button:active {
transform: translateY(0);
}
@media (max-width: 768px) {
.particle-overlay h1 {
font-size: 2rem;
}
.particle-overlay p {
font-size: 1rem;
}
.particle-controls {
gap: 0.5rem;
}
.particle-controls button {
padding: 0.6rem 1.2rem;
font-size: 0.8rem;
}
}
JavaScript
class ParticleSystem {
constructor(canvas) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.particles = [];
this.mouse = { x: 0, y: 0, radius: 100 };
this.gravity = false;
this.colorSchemes = [
['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#ffeaa7'],
['#667eea', '#764ba2', '#f093fb', '#f5576c', '#4facfe'],
['#43e97b', '#38f9d7', '#667eea', '#764ba2', '#f093fb']
];
this.currentScheme = 0;
this.colors = this.colorSchemes[this.currentScheme];
this.resize();
this.init();
this.bindEvents();
this.animate();
}
resize() {
this.canvas.width = this.canvas.offsetWidth;
this.canvas.height = this.canvas.offsetHeight;
}
init() {
this.particles = [];
const particleCount = Math.min(120, Math.floor(this.canvas.width * this.canvas.height / 8000));
for (let i = 0; i < particleCount; i++) {
this.particles.push({
x: Math.random() * this.canvas.width,
y: Math.random() * this.canvas.height,
vx: (Math.random() - 0.5) * 2,
vy: (Math.random() - 0.5) * 2,
size: Math.random() * 4 + 1,
color: this.colors[Math.floor(Math.random() * this.colors.length)],
alpha: Math.random() * 0.6 + 0.4,
originalAlpha: Math.random() * 0.6 + 0.4
});
}
}
bindEvents() {
this.canvas.addEventListener('mousemove', (e) => {
const rect = this.canvas.getBoundingClientRect();
this.mouse.x = e.clientX - rect.left;
this.mouse.y = e.clientY - rect.top;
});
this.canvas.addEventListener('mouseleave', () => {
this.mouse.x = -1000;
this.mouse.y = -1000;
});
window.addEventListener('resize', () => {
this.resize();
this.init();
});
document.getElementById('resetBtn').addEventListener('click', () => {
this.init();
});
document.getElementById('gravityBtn').addEventListener('click', () => {
this.gravity = !this.gravity;
});
document.getElementById('colorBtn').addEventListener('click', () => {
this.currentScheme = (this.currentScheme + 1) % this.colorSchemes.length;
this.colors = this.colorSchemes[this.currentScheme];
this.particles.forEach(particle => {
particle.color = this.colors[Math.floor(Math.random() * this.colors.length)];
});
});
}
update() {
this.particles.forEach(particle => {
// Mouse interaction
const dx = this.mouse.x - particle.x;
const dy = this.mouse.y - particle.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < this.mouse.radius) {
const force = (this.mouse.radius - distance) / this.mouse.radius;
const angle = Math.atan2(dy, dx);
particle.vx -= Math.cos(angle) * force * 0.5;
particle.vy -= Math.sin(angle) * force * 0.5;
particle.alpha = Math.min(1, particle.originalAlpha + force * 0.5);
} else {
particle.alpha = particle.originalAlpha;
}
// Gravity effect
if (this.gravity) {
particle.vy += 0.1;
}
// Update position
particle.x += particle.vx;
particle.y += particle.vy;
// Friction
particle.vx *= 0.99;
particle.vy *= 0.99;
// Boundary collision
if (particle.x < 0 || particle.x > this.canvas.width) {
particle.vx *= -0.8;
particle.x = Math.max(0, Math.min(this.canvas.width, particle.x));
}
if (particle.y < 0 || particle.y > this.canvas.height) {
particle.vy *= -0.8;
particle.y = Math.max(0, Math.min(this.canvas.height, particle.y));
}
});
}
draw() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Draw connections
this.particles.forEach((particle, i) => {
for (let j = i + 1; j < this.particles.length; j++) {
const other = this.particles[j];
const dx = particle.x - other.x;
const dy = particle.y - other.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
this.ctx.beginPath();
this.ctx.strokeStyle = `rgba(255, 255, 255, ${(1 - distance / 100) * 0.2})`;
this.ctx.lineWidth = 1;
this.ctx.moveTo(particle.x, particle.y);
this.ctx.lineTo(other.x, other.y);
this.ctx.stroke();
}
}
});
// Draw particles
this.particles.forEach(particle => {
this.ctx.beginPath();
this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
this.ctx.fillStyle = particle.color.replace('rgb', 'rgba').replace(')', `, ${particle.alpha})`);
this.ctx.fill();
// Add glow effect
this.ctx.shadowColor = particle.color;
this.ctx.shadowBlur = 10;
this.ctx.fill();
this.ctx.shadowBlur = 0;
});
}
animate() {
this.update();
this.draw();
requestAnimationFrame(() => this.animate());
}
}
document.addEventListener('DOMContentLoaded', function() {
const canvas = document.getElementById('particleCanvas');
if (canvas) {
new ParticleSystem(canvas);
}
});