DEV Community

Play Button Pause Button
Prince
Prince

Posted on

Physics effects with the normal css , html and javascript

Follow us on the instagram: https://www.instagram.com/prince_codes1/

Code:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Interactive Particle Physics</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { background: #000; height: 100vh; overflow: hidden; display: flex; justify-content: center; align-items: center; font-family: 'Arial', sans-serif; color: white; } canvas { position: absolute; top: 0; left: 0; z-index: 1; } .controls { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 10; display: flex; gap: 15px; background: rgba(0, 0, 0, 0.7); padding: 15px 25px; border-radius: 50px; backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); } .control-btn { background: none; border: none; color: white; font-size: 16px; cursor: pointer; padding: 8px 16px; border-radius: 50px; transition: all 0.3s; border: 1px solid rgba(255, 255, 255, 0.2); } .control-btn:hover, .control-btn.active { background: rgba(255, 255, 255, 0.2); transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); } .info-panel { position: absolute; top: 20px; left: 20px; z-index: 10; background: rgba(0, 0, 0, 0.7); padding: 15px; border-radius: 10px; backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); font-size: 14px; opacity: 0.8; transition: opacity 0.3s; } .info-panel:hover { opacity: 1; } .title { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); z-index: 10; font-size: 24px; font-weight: bold; letter-spacing: 2px; text-shadow: 0 0 10px rgba(255, 255, 255, 0.5); } </style> </head> <body> <canvas id="canvas"></canvas> <div class="title">INTERACTIVE PARTICLE PHYSICS</div> <div class="controls"> <button class="control-btn active" data-mode="attract">Attract</button> <button class="control-btn" data-mode="repel">Repel</button> <button class="control-btn" data-mode="orbit">Orbit</button> <button class="control-btn" data-mode="chaos">Chaos</button> <button class="control-btn" data-mode="reset">Reset</button> </div> <script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // Set canvas size canvas.width = window.innerWidth; canvas.height = window.innerHeight; // Particles array let particles = []; let mode = 'attract'; // Mouse position const mouse = { x: null, y: null, down: false, prevX: null, prevY: null }; // Particle class class Particle { constructor(x, y, vx, vy) { this.x = x; this.y = y; this.size = Math.random() * 3 + 2; this.color = `hsl(${Math.random() * 360}, 100%, 70%)`; this.vx = vx; this.vy = vy; this.alpha = 1; this.trail = []; this.trailLength = 20; } update() { // Update position this.x += this.vx; this.y += this.vy; // Add position to trail this.trail.unshift({ x: this.x, y: this.y }); if (this.trail.length > this.trailLength) { this.trail.pop(); } // Check boundaries if (this.x < 0 || this.x > canvas.width) this.vx *= -0.8; if (this.y < 0 || this.y > canvas.height) this.vy *= -0.8; // Apply friction this.vx *= 0.99; this.vy *= 0.99; // Interact with other particles based on mode for (let i = 0; i < particles.length; i++) { const particle = particles[i]; if (this === particle) continue; const dx = particle.x - this.x; const dy = particle.y - this.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { const forceX = dx / distance; const forceY = dy / distance; const force = (150 - distance) / 150; if (mode === 'attract') { this.vx += forceX * force * 0.03; this.vy += forceY * force * 0.03; } else if (mode === 'repel') { this.vx -= forceX * force * 0.1; this.vy -= forceY * force * 0.1; } else if (mode === 'orbit') { this.vx += forceY * force * 0.05; this.vy -= forceX * force * 0.05; } else if (mode === 'chaos') { this.vx += (Math.random() - 0.5) * force * 0.2; this.vy += (Math.random() - 0.5) * force * 0.2; } } } } draw() { // Draw trail for (let i = 0; i < this.trail.length; i++) { const alpha = (this.trail.length - i) / this.trail.length * 0.6; const size = this.size * (1 - i / this.trail.length); ctx.beginPath(); ctx.arc(this.trail[i].x, this.trail[i].y, size, 0, Math.PI * 2); ctx.fillStyle = this.color.replace('hsl', 'hsla').replace(')', `, ${alpha})`); ctx.fill(); } // Draw particle ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fillStyle = this.color; ctx.fill(); // Draw glow ctx.beginPath(); ctx.arc(this.x, this.y, this.size * 2, 0, Math.PI * 2); const gradient = ctx.createRadialGradient( this.x, this.y, this.size, this.x, this.y, this.size * 4 ); gradient.addColorStop(0, this.color.replace('hsl', 'hsla').replace(')', ', 0.4)')); gradient.addColorStop(1, this.color.replace('hsl', 'hsla').replace(')', ', 0)')); ctx.fillStyle = gradient; ctx.fill(); } } // Create particles when mouse is dragged function createParticles() { if (mouse.down && mouse.prevX !== null) { const speedX = (mouse.x - mouse.prevX) * 0.2; const speedY = (mouse.y - mouse.prevY) * 0.2; // Create multiple particles with slight variations for (let i = 0; i < 2; i++) { const randomOffsetX = (Math.random() - 0.5) * 10; const randomOffsetY = (Math.random() - 0.5) * 10; const randomSpeedX = speedX + (Math.random() - 0.5) * 2; const randomSpeedY = speedY + (Math.random() - 0.5) * 2; particles.push(new Particle( mouse.x + randomOffsetX, mouse.y + randomOffsetY, randomSpeedX, randomSpeedY )); } } mouse.prevX = mouse.x; mouse.prevY = mouse.y; } // Animation loop function animate() { // Clear canvas with semi-transparent black for trail effect ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Create particles if mouse is down if (mouse.down) { createParticles(); } // Update and draw particles for (let i = 0; i < particles.length; i++) { particles[i].update(); particles[i].draw(); // Remove particles with very low velocity const speed = Math.sqrt( particles[i].vx * particles[i].vx + particles[i].vy * particles[i].vy ); if (speed < 0.05 && particles.length > 100) { particles.splice(i, 1); i--; } } // Draw connections between close particles drawConnections(); requestAnimationFrame(animate); } // 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 < 100) { ctx.beginPath(); ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(particles[j].x, particles[j].y); const alpha = (100 - distance) / 100 * 0.2; ctx.strokeStyle = `rgba(255, 255, 255, ${alpha})`; ctx.lineWidth = 1; ctx.stroke(); } } } } // Event listeners window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; }); canvas.addEventListener('mousedown', (e) => { mouse.down = true; mouse.x = e.clientX; mouse.y = e.clientY; mouse.prevX = e.clientX; mouse.prevY = e.clientY; }); canvas.addEventListener('mouseup', () => { mouse.down = false; mouse.prevX = null; mouse.prevY = null; }); canvas.addEventListener('mousemove', (e) => { mouse.x = e.clientX; mouse.y = e.clientY; }); // Mobile support canvas.addEventListener('touchstart', (e) => { mouse.down = true; mouse.x = e.touches[0].clientX; mouse.y = e.touches[0].clientY; mouse.prevX = e.touches[0].clientX; mouse.prevY = e.touches[0].clientY; }); canvas.addEventListener('touchend', () => { mouse.down = false; mouse.prevX = null; mouse.prevY = null; }); canvas.addEventListener('touchmove', (e) => { e.preventDefault(); mouse.x = e.touches[0].clientX; mouse.y = e.touches[0].clientY; }); // Mode buttons const buttons = document.querySelectorAll('.control-btn'); buttons.forEach(button => { button.addEventListener('click', () => { // Set active button buttons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); // Set mode mode = button.dataset.mode; // Reset particles if reset button if (mode === 'reset') { particles = []; } }); }); // Start animation animate(); // Add initial particles for (let i = 0; i < 50; i++) { const x = Math.random() * canvas.width; const y = Math.random() * canvas.height; const vx = (Math.random() - 0.5) * 2; const vy = (Math.random() - 0.5) * 2; particles.push(new Particle(x, y, vx, vy)); } // Create initial bursts function createInitialBurst() { const x = Math.random() * canvas.width; const y = Math.random() * canvas.height; for (let i = 0; i < 20; i++) { const angle = Math.random() * Math.PI * 2; const speed = Math.random() * 5 + 1; const vx = Math.cos(angle) * speed; const vy = Math.sin(angle) * speed; particles.push(new Particle(x, y, vx, vy)); } } // Create initial bursts for (let i = 0; i < 3; i++) { setTimeout(() => { createInitialBurst(); }, i * 1000); } </script> </body> </html> 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.