DEV Community

Play Button Pause Button
Prince
Prince

Posted on

Particles effect using the html css and js

`<!DOCTYPE html>









Interactive Particle System

<br>
* {<br>
margin: 0;<br>
padding: 0;<br>
box-sizing: border-box;<br>
}</p>
<div class="highlight"><pre class="highlight plaintext"><code> body {
font-family: 'Arial', sans-serif;
overflow: hidden;
background-color: #0a0a0a;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: white;
}
#canvas { position: fixed; top: 0; left: 0; z-index: 1; } .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 2; pointer-events: none; } .title { font-size: 2.5rem; font-weight: bold; text-shadow: 0 0 10px rgba(139, 92, 246, 0.8); color: #8b5cf6; opacity: 0; transition: opacity 2s ease; margin-bottom: 20px; text-align: center; } .subtitle { font-size: 1.2rem; opacity: 0; transition: opacity 2s ease; text-align: center; max-width: 80%; text-shadow: 0 0 5px rgba(255, 255, 255, 0.5); } .cta { position: absolute; bottom: 5%; font-size: 1.4rem; font-weight: bold; color: #8b5cf6; opacity: 0; transition: opacity 1s ease; text-align: center; z-index: 5; width: 100%; text-shadow: 0 0 10px rgba(139, 92, 246, 0.8); } .overlay-touch { position: absolute; width: 100%; height: 100%; z-index: 10; opacity: 0; pointer-events: all; cursor: pointer; } 
Enter fullscreen mode Exit fullscreen mode

&lt;/style&gt;
</code></pre></div>
<p></head><br>
<body><br>
<canvas id="canvas"></canvas></p>
<div class="highlight"><pre class="highlight plaintext"><code>&lt;!-- &lt;div class="overlay"&gt;
&lt;h1 class="title"&gt;Interactive Particle System&lt;/h1&gt;
&lt;h2 class="subtitle"&gt;Touch or click to interact with particles&lt;/h2&gt;
&lt;/div&gt; --&gt;

&lt;div class="cta"&gt;Double tap to create particle explosions&lt;/div&gt;

&lt;div class="overlay-touch"&gt;&lt;/div&gt;

&lt;script&gt;
// Canvas setup
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// Animation variables let particles = []; let connections = []; let animationStage = 0; let lastTime = 0; let mouseX = 0, mouseY = 0; let isUserInteracting = false; let isFirstTouch = true; // DOM elements const title = document.querySelector('.title'); const subtitle = document.querySelector('.subtitle'); const cta = document.querySelector('.cta'); const touchOverlay = document.querySelector('.overlay-touch'); // Colors const colors = [ '#8b5cf6', // Purple '#3b82f6', // Blue '#ec4899', // Pink '#10b981', // Green '#f59e0b' // Amber ]; // Particle class class Particle { constructor(x, y, color, size = 3, speedFactor = 1, fixed = false) { this.x = x; this.y = y; this.size = size; this.color = color; this.baseX = x; this.baseY = y; this.density = (Math.random() * 30) + 1; this.speedFactor = speedFactor; this.fixed = fixed; this.vx = (Math.random() - 0.5) * 2; this.vy = (Math.random() - 0.5) * 2; this.friction = 0.95; this.life = 1; this.decay = Math.random() * 0.01 + 0.001; this.maxSize = size; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.size * this.life, 0, Math.PI * 2); ctx.closePath(); // Create gradient for particle const gradient = ctx.createRadialGradient( this.x, this.y, 0, this.x, this.y, this.size * this.life ); gradient.addColorStop(0, this.color); gradient.addColorStop(1, 'rgba(0,0,0,0)'); ctx.fillStyle = gradient; ctx.fill(); } update() { if (this.fixed) return; // Apply velocity this.x += this.vx * this.speedFactor; this.y += this.vy * this.speedFactor; // Apply friction this.vx *= this.friction; this.vy *= this.friction; // Apply gravity (subtle pull downward) this.vy += 0.02 * this.speedFactor; // Boundary checks with bounce effect if (this.x &amp;lt; this.size) { this.x = this.size; this.vx *= -0.8; } if (this.x &amp;gt; canvas.width - this.size) { this.x = canvas.width - this.size; this.vx *= -0.8; } if (this.y &amp;lt; this.size) { this.y = this.size; this.vy *= -0.8; } if (this.y &amp;gt; canvas.height - this.size) { this.y = canvas.height - this.size; this.vy *= -0.8; } // Mouse interaction if (isUserInteracting) { const dx = mouseX - this.x; const dy = mouseY - this.y; const distance = Math.sqrt(dx * dx + dy * dy); const forceDirectionX = dx / distance; const forceDirectionY = dy / distance; // Calculate force (stronger when closer) const maxDistance = 150; const force = (maxDistance - Math.min(maxDistance, distance)) / 10; if (distance &amp;lt; maxDistance) { this.vx += forceDirectionX * force / this.density; this.vy += forceDirectionY * force / this.density; } } // Decay particle life if it's an explosion particle if (this.decay &amp;gt; 0) { this.life -= this.decay; if (this.life &amp;lt;= 0) { this.life = 0; } } } isAlive() { return this.life &amp;gt; 0.01; } } // Create initial particles function initParticles() { particles = []; for (let i = 0; i &amp;lt; 150; i++) { const x = Math.random() * canvas.width; const y = Math.random() * canvas.height; const color = colors[Math.floor(Math.random() * colors.length)]; const size = Math.random() * 3 + 2; particles.push(new Particle(x, y, color, size)); } } // Draw connections between particles function connectParticles() { connections = []; const maxDistance = 150; for (let i = 0; i &amp;lt; particles.length; i++) { if (!particles[i].isAlive()) continue; for (let j = i + 1; j &amp;lt; particles.length; j++) { if (!particles[j].isAlive()) continue; 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 &amp;lt; maxDistance) { const opacity = 1 - (distance / maxDistance); connections.push({ start: particles[i], end: particles[j], opacity: opacity * particles[i].life * particles[j].life }); } } } } // Draw the connections function drawConnections() { for (const connection of connections) { ctx.beginPath(); ctx.moveTo(connection.start.x, connection.start.y); ctx.lineTo(connection.end.x, connection.end.y); const gradient = ctx.createLinearGradient( connection.start.x, connection.start.y, connection.end.x, connection.end.y ); gradient.addColorStop(0, connection.start.color); gradient.addColorStop(1, connection.end.color); ctx.strokeStyle = gradient; ctx.globalAlpha = connection.opacity * 0.7; ctx.lineWidth = connection.opacity * 2; ctx.stroke(); ctx.globalAlpha = 1; } } // Create particle explosion function createExplosion(x, y) { const particleCount = Math.floor(Math.random() * 20) + 30; const baseHue = Math.floor(Math.random() * 360); for (let i = 0; i &amp;lt; particleCount; i++) { // Create color variations const hue = (baseHue + Math.random() * 30 - 15) % 360; const color = `hsl(${hue}, 80%, 60%)`; // Calculate random direction const angle = Math.random() * Math.PI * 2; const speed = Math.random() * 6 + 1; const size = Math.random() * 4 + 2; const particle = new Particle(x, y, color, size); particle.vx = Math.cos(angle) * speed; particle.vy = Math.sin(angle) * speed; particle.friction = 0.98; particle.decay = Math.random() * 0.02 + 0.005; particles.push(particle); } } // Animation loop function animate(timestamp) { const deltaTime = timestamp - lastTime; lastTime = timestamp; // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Update and draw particles particles = particles.filter(particle =&amp;gt; particle.isAlive()); for (const particle of particles) { particle.update(); particle.draw(); } // Connect particles connectParticles(); drawConnections(); // Progress the animation stages updateAnimation(deltaTime); requestAnimationFrame(animate); } // Handle animation stages function updateAnimation(deltaTime) { if (animationStage === 0 &amp;amp;&amp;amp; lastTime &amp;gt; 1000) { // Show title title.style.opacity = '1'; setTimeout(() =&amp;gt; { subtitle.style.opacity = '1'; touchOverlay.style.opacity = '1'; animationStage = 1; }, 2000); } else if (animationStage === 1 &amp;amp;&amp;amp; lastTime &amp;gt; 5000) { // Show CTA cta.style.opacity = '1'; animationStage = 2; // Create random explosions occasionally setInterval(() =&amp;gt; { if (!isUserInteracting &amp;amp;&amp;amp; Math.random() &amp;lt; 0.3) { const x = Math.random() * canvas.width; const y = Math.random() * canvas.height; createExplosion(x, y); } }, 3000); } } // Handle window resize window.addEventListener('resize', () =&amp;gt; { canvas.width = window.innerWidth; canvas.height = window.innerHeight; initParticles(); }); // Handle mouse/touch events for user interaction touchOverlay.addEventListener('mousemove', (e) =&amp;gt; { mouseX = e.clientX; mouseY = e.clientY; }); touchOverlay.addEventListener('mousedown', () =&amp;gt; { isUserInteracting = true; }); touchOverlay.addEventListener('mouseup', () =&amp;gt; { isUserInteracting = false; }); touchOverlay.addEventListener('touchmove', (e) =&amp;gt; { e.preventDefault(); mouseX = e.touches[0].clientX; mouseY = e.touches[0].clientY; isUserInteracting = true; // Create small particles while dragging if (Math.random() &amp;lt; 0.3) { const color = colors[Math.floor(Math.random() * colors.length)]; const particle = new Particle(mouseX, mouseY, color, Math.random() * 2 + 1); particle.vx = (Math.random() - 0.5) * 2; particle.vy = (Math.random() - 0.5) * 2; particles.push(particle); } }); touchOverlay.addEventListener('touchend', () =&amp;gt; { isUserInteracting = false; }); // Create explosion on click/tap touchOverlay.addEventListener('click', (e) =&amp;gt; { const x = e.clientX || e.touches[0].clientX; const y = e.clientY || e.touches[0].clientY; createExplosion(x, y); // Show/hide UI elements based on first touch if (isFirstTouch) { setTimeout(() =&amp;gt; { title.style.opacity = '0'; subtitle.style.opacity = '0'; }, 500); isFirstTouch = false; } }); // Initialize and start animation function init() { initParticles(); requestAnimationFrame(animate); } init(); 
Enter fullscreen mode Exit fullscreen mode

&lt;/script&gt;
</code></pre></div>
<p></body><br>
</html>`</p>

Top comments (0)