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>
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.