Animated Particle Background
Advanced
Dynamic particle background with floating dots and connecting lines, perfect for hero sections and modern web designs.
Live Preview
Code Implementation
HTML
<div class="particle-container">
<canvas id="particleCanvas"></canvas>
<div class="content-overlay">
<h1>Particle Background</h1>
<p>Interactive particle system with connecting lines</p>
<button class="cta-button">Get Started</button>
</div>
</div>
CSS
.particle-container {
position: relative;
width: 100%;
height: 350px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
overflow: hidden;
border-radius: 15px;
display: flex;
align-items: center;
justify-content: center;
}
#particleCanvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.content-overlay {
position: relative;
z-index: 2;
text-align: center;
color: white;
padding: 20px;
}
.content-overlay h1 {
font-size: 2.5rem;
font-weight: 700;
margin: 0 0 15px 0;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.content-overlay p {
font-size: 1.2rem;
margin: 0 0 25px 0;
opacity: 0.9;
text-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
}
.cta-button {
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.3);
color: white;
padding: 12px 30px;
border-radius: 50px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
text-transform: uppercase;
letter-spacing: 1px;
}
.cta-button:hover {
background: rgba(255, 255, 255, 0.3);
border-color: rgba(255, 255, 255, 0.5);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.cta-button:active {
transform: translateY(0);
}
/* Responsive */
@media (max-width: 768px) {
.content-overlay h1 {
font-size: 2rem;
}
.content-overlay p {
font-size: 1rem;
}
.particle-container {
height: 300px;
}
}
JavaScript
document.addEventListener('DOMContentLoaded', function() {
const canvas = document.getElementById('particleCanvas');
const ctx = canvas.getContext('2d');
// Set canvas size
function resizeCanvas() {
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// Particle system
const particles = [];
const particleCount = 50;
const maxDistance = 100;
// Mouse position
let mouse = {
x: null,
y: null,
radius: 150
};
// Track mouse movement
canvas.addEventListener('mousemove', function(e) {
const rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left;
mouse.y = e.clientY - rect.top;
});
canvas.addEventListener('mouseleave', function() {
mouse.x = null;
mouse.y = null;
});
// Particle class
class Particle {
constructor() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.vx = (Math.random() - 0.5) * 0.5;
this.vy = (Math.random() - 0.5) * 0.5;
this.radius = Math.random() * 2 + 1;
this.opacity = Math.random() * 0.5 + 0.3;
}
update() {
// Mouse interaction
if (mouse.x !== null && mouse.y !== null) {
const dx = mouse.x - this.x;
const dy = mouse.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < mouse.radius) {
const force = (mouse.radius - distance) / mouse.radius;
const angle = Math.atan2(dy, dx);
this.vx -= Math.cos(angle) * force * 0.01;
this.vy -= Math.sin(angle) * force * 0.01;
}
}
// Update position
this.x += this.vx;
this.y += this.vy;
// Boundary collision
if (this.x < 0 || this.x > canvas.width) {
this.vx *= -1;
this.x = Math.max(0, Math.min(canvas.width, this.x));
}
if (this.y < 0 || this.y > canvas.height) {
this.vy *= -1;
this.y = Math.max(0, Math.min(canvas.height, this.y));
}
// Friction
this.vx *= 0.99;
this.vy *= 0.99;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = `rgba(255, 255, 255, ${this.opacity})`;
ctx.fill();
}
}
// Create particles
function createParticles() {
for (let i = 0; i < particleCount; i++) {
particles.push(new Particle());
}
}
// Draw connections between particles
function drawConnections() {
for (let i = 0; i < particles.length; i++) {
for (let j = i + 1; j < particles.length; j++) {
const dx = particles[i].x - particles[j].x;
const dy = particles[i].y - particles[j].y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < maxDistance) {
const opacity = (maxDistance - distance) / maxDistance * 0.3;
ctx.beginPath();
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
ctx.strokeStyle = `rgba(255, 255, 255, ${opacity})`;
ctx.lineWidth = 1;
ctx.stroke();
}
}
}
}
// Animation loop
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Update and draw particles
particles.forEach(particle => {
particle.update();
particle.draw();
});
// Draw connections
drawConnections();
requestAnimationFrame(animate);
}
// Initialize
createParticles();
animate();
// Button interaction
const ctaButton = document.querySelector('.cta-button');
ctaButton.addEventListener('click', function() {
// Create burst effect
for (let i = 0; i < 10; i++) {
setTimeout(() => {
particles.push(new Particle());
}, i * 50);
}
// Remove extra particles after animation
setTimeout(() => {
particles.splice(particleCount, particles.length - particleCount);
}, 2000);
console.log('CTA button clicked!');
});
});
Snippet Features
Browser Compatibility
🟢
chrome 50+ 🟠
firefox 45+ 🔵
safari 10+ 🟦
edge 15+