space / index.html
obov's picture
Add 3 files
4c3ffe7 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Particle Canvas</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
overflow: hidden;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
}
canvas {
position: fixed;
top: 0;
left: 0;
z-index: 1;
}
.content {
position: relative;
z-index: 2;
pointer-events: none;
}
.particle {
position: absolute;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
}
.controls {
position: fixed;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
z-index: 10;
pointer-events: all;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 9999px;
padding: 0.5rem 1rem;
display: flex;
gap: 1rem;
align-items: center;
}
button {
pointer-events: all;
background: rgba(255, 255, 255, 0.2);
border: none;
color: white;
padding: 0.5rem 1rem;
border-radius: 9999px;
cursor: pointer;
transition: all 0.3s ease;
}
button:hover {
background: rgba(255, 255, 255, 0.3);
transform: scale(1.05);
}
.title {
font-size: 5rem;
font-weight: 800;
background: linear-gradient(to right, #ff758c, #ff7eb3, #a18cd1, #8ec5fc);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
text-align: center;
margin-bottom: 2rem;
}
.subtitle {
font-size: 1.5rem;
color: rgba(255, 255, 255, 0.8);
text-align: center;
max-width: 600px;
margin: 0 auto 3rem;
}
@media (max-width: 768px) {
.title {
font-size: 3rem;
}
.subtitle {
font-size: 1rem;
padding: 0 1rem;
}
.controls {
flex-direction: column;
border-radius: 1rem;
padding: 1rem;
}
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div class="content min-h-screen flex flex-col justify-center items-center px-4">
<h1 class="title">Cosmic Harmony</h1>
<p class="subtitle">Move your cursor to paint the canvas with colorful particles. Each interaction creates a unique visual symphony.</p>
</div>
<div class="controls">
<button id="clearBtn">Clear Canvas</button>
<button id="colorBtn">Change Colors</button>
<button id="modeBtn">Toggle Mode</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const clearBtn = document.getElementById('clearBtn');
const colorBtn = document.getElementById('colorBtn');
const modeBtn = document.getElementById('modeBtn');
// Set canvas to full window size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Particle system
let particles = [];
let mouseX = 0;
let mouseY = 0;
let isMouseDown = false;
let colorPalette = [
'#FF758C', '#FF7EB3', '#A18CD1', '#8EC5FC',
'#87F5FB', '#A3FFD6', '#B7FFB1', '#FFD166'
];
let currentMode = 'trail'; // 'trail' or 'explosion'
// Initialize
function init() {
window.addEventListener('resize', onResize);
canvas.addEventListener('mousemove', onMouseMove);
canvas.addEventListener('mousedown', onMouseDown);
canvas.addEventListener('mouseup', onMouseUp);
canvas.addEventListener('touchmove', onTouchMove);
canvas.addEventListener('touchstart', onTouchStart);
canvas.addEventListener('touchend', onTouchEnd);
clearBtn.addEventListener('click', clearCanvas);
colorBtn.addEventListener('click', changeColors);
modeBtn.addEventListener('click', toggleMode);
animate();
}
// Animation loop
function animate() {
ctx.fillStyle = 'rgba(26, 26, 46, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Update and draw particles
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
p.x += p.vx;
p.y += p.vy;
p.life--;
if (p.life <= 0) {
particles.splice(i, 1);
i--;
continue;
}
ctx.globalAlpha = p.life / p.maxLife;
ctx.fillStyle = p.color;
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(animate);
}
// Create particles
function createParticles(x, y) {
const particleCount = currentMode === 'trail' ? 3 : 50;
const baseSize = currentMode === 'trail' ? 2 : 4;
for (let i = 0; i < particleCount; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = currentMode === 'trail' ?
Math.random() * 0.5 :
Math.random() * 5;
particles.push({
x: x,
y: y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
radius: baseSize + Math.random() * 3,
color: colorPalette[Math.floor(Math.random() * colorPalette.length)],
life: currentMode === 'trail' ? 50 + Math.random() * 50 : 30 + Math.random() * 50,
maxLife: currentMode === 'trail' ? 100 : 80
});
}
}
// Event handlers
function onMouseMove(e) {
mouseX = e.clientX;
mouseY = e.clientY;
if (isMouseDown) {
createParticles(mouseX, mouseY);
}
}
function onMouseDown() {
isMouseDown = true;
createParticles(mouseX, mouseY);
}
function onMouseUp() {
isMouseDown = false;
}
function onTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
mouseX = touch.clientX;
mouseY = touch.clientY;
createParticles(mouseX, mouseY);
}
function onTouchStart(e) {
const touch = e.touches[0];
mouseX = touch.clientX;
mouseY = touch.clientY;
createParticles(mouseX, mouseY);
}
function onTouchEnd() {
// No action needed
}
function onResize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
function clearCanvas() {
ctx.fillStyle = '#1a1a2e';
ctx.fillRect(0, 0, canvas.width, canvas.height);
particles = [];
}
function changeColors() {
// Generate a new random color palette
colorPalette = [];
const hueBase = Math.random() * 360;
for (let i = 0; i < 8; i++) {
const hue = (hueBase + (i * 45) + Math.random() * 30) % 360;
const saturation = 70 + Math.random() * 30;
const lightness = 60 + Math.random() * 20;
colorPalette.push(`hsl(${hue}, ${saturation}%, ${lightness}%)`);
}
}
function toggleMode() {
currentMode = currentMode === 'trail' ? 'explosion' : 'trail';
modeBtn.textContent = currentMode === 'trail' ? 'Explosion Mode' : 'Trail Mode';
}
// Start the app
init();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=obov/space" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>