All Prompts
All Prompts

herosectioninteractiveanimatedcanvastailwindlanding
Interactive Particle Canvas Hero Panel
Интерактивная панель героя с анимированным фоном из частиц. Идеально для лендингов и экспериментальных интерфейсов. Адаптивный UI.
Prompt
<section id="interactive-node"
class="relative w-full h-screen overflow-hidden flex flex-col items-center justify-center bg-[#020205] text-white select-none"
style="font-family: 'Inter', system-ui, -apple-system, sans-serif;">
<script src="https://cdn.tailwindcss.com"></script>
<canvas id="particle-canvas"
class="absolute inset-0 z-0 bg-radial-gradient from-gray-900 to-black cursor-none"></canvas>
<nav class="fixed top-0 left-0 w-full p-8 md:p-12 flex justify-between items-start z-30 pointer-events-none">
<div class="pointer-events-auto group cursor-help">
<div class="text-[11px] tracking-[0.5em] font-black uppercase mb-1 text-emerald-400">Aetheris / Node 77</div>
<div class="h-[2px] w-8 group-hover:w-full bg-emerald-500 transition-all duration-700"></div>
</div>
<div class="hidden md:block pointer-events-auto opacity-30 text-[9px] tracking-[0.3em] uppercase"
style="font-family: monospace;">
Buffer: 1024mb // Latency: 4ms
</div>
</nav>
<div
class="relative z-20 mx-4 p-10 md:p-16 max-w-md w-full flex flex-col items-center text-center transition-all duration-1000 group border border-white/5 hover:border-emerald-500/30"
style="background: rgba(10, 10, 15, 0.4); backdrop-filter: blur(40px); border-radius: 4px;">
<div
class="absolute -top-px left-10 right-10 h-px bg-gradient-to-r from-transparent via-emerald-500/50 to-transparent">
</div>
<span class="text-[10px] uppercase tracking-[0.6em] text-emerald-500 mb-6 font-bold">Resonance Active</span>
<h1
class="text-8xl md:text-9xl font-black leading-none tracking-tighter mb-8 italic text-transparent bg-clip-text bg-gradient-to-b from-white to-white/20">
.95</h1>
<p class="text-[12px] leading-relaxed opacity-50 mb-12 font-medium tracking-wide max-w-xs">
Mapping fluid consciousness through kinetic noise. Click to disrupt the equilibrium; hover to guide the flow.
</p>
<div class="w-full pt-10 border-t border-white/10 flex flex-col items-center gap-10">
<div class="flex justify-between w-full px-2 text-[10px] tracking-widest font-mono">
<div class="flex flex-col items-start">
<span class="opacity-30 mb-1">PROTO</span>
<span class="text-emerald-400">#X-909</span>
</div>
<div class="flex flex-col items-end">
<span class="opacity-30 mb-1">STRATA</span>
<span class="text-emerald-400">KINETIC</span>
</div>
</div>
<button id="cta-trigger" class="group relative px-12 py-5 overflow-hidden bg-white text-black transition-all duration-500 hover:tracking-[0.3em]">
<span class="relative z-10 text-[11px] font-black tracking-[0.2em] uppercase">Engage Link 0.8Ξ</span>
<div class="absolute inset-0 bg-emerald-400 translate-y-full group-hover:translate-y-0 transition-transform duration-500"></div>
</button>
</div>
</div>
<div class="fixed bottom-12 w-full flex flex-col items-center z-30 pointer-events-none">
<div class="text-[9px] uppercase tracking-[0.6em] opacity-20 mb-3">Sync Signature</div>
<div id="hex-id"
class="text-[11px] opacity-40 hover:opacity-100 transition-opacity pointer-events-auto cursor-crosshair font-mono">
7F:32:0A:E1:99
</div>
</div>
<script>
(function() {
const canvas = document.getElementById('particle-canvas');
const ctx = canvas.getContext('2d');
let width, height, particles = [];
const mouse = { x: -1000, y: -1000, active: false };
class Particle {
constructor() {
this.reset();
}
reset() {
this.x = Math.random() * width;
this.y = Math.random() * height;
this.vx = (Math.random() - 0.5) * 0.8;
this.vy = (Math.random() - 0.5) * 0.8;
this.size = Math.random() * 2 + 0.5;
this.color = Math.random() > 0.9 ? '#10b981' : '#ffffff';
this.alpha = Math.random() * 0.5 + 0.2;
}
update() {
const dx = mouse.x - this.x;
const dy = mouse.y - this.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 300) {
const force = (300 - dist) / 300;
this.vx += dx * force * 0.015;
this.vy += dy * force * 0.015;
}
this.vx *= 0.94;
this.vy *= 0.94;
this.x += this.vx + (Math.random() - 0.5) * 0.2;
this.y += this.vy + (Math.random() - 0.5) * 0.2;
if (this.x < 0) this.x = width;
if (this.x > width) this.x = 0;
if (this.y < 0) this.y = height;
if (this.y > height) this.y = 0;
}
draw() {
ctx.fillStyle = this.color;
ctx.globalAlpha = this.alpha;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
}
explode(mx, my) {
const dx = this.x - mx;
const dy = this.y - my;
const dist = Math.sqrt(dx * dx + dy * dy);
const force = Math.max(0, 500 - dist) / 20;
this.vx += (dx / dist) * force;
this.vy += (dy / dist) * force;
}
}
function resize() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width * window.devicePixelRatio;
canvas.height = height * window.devicePixelRatio;
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
init();
}
function init() {
particles = Array.from({ length: width < 768 ? 200 : 500 }, () => new Particle());
}
function animate() {
ctx.clearRect(0, 0, width, height);
particles.forEach(p => {
p.update();
p.draw();
});
ctx.beginPath();
ctx.strokeStyle = 'rgba(16, 185, 129, 0.1)';
ctx.lineWidth = 0.5;
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 dist = dx*dx + dy*dy;
if(dist < 5000) {
ctx.moveTo(particles[i].x, particles[i].y);
ctx.lineTo(particles[j].x, particles[j].y);
}
}
}
ctx.stroke();
requestAnimationFrame(animate);
}
window.addEventListener('mousemove', e => { mouse.x = e.clientX; mouse.y = e.clientY; });
window.addEventListener('mousedown', e => {
particles.forEach(p => p.explode(e.clientX, e.clientY));
});
window.addEventListener('resize', resize);
document.getElementById('hex-id').addEventListener('click', function() {
this.innerText = Math.random().toString(16).toUpperCase().slice(2, 12).match(/.{1,2}/g).join(':');
});
document.getElementById('cta-trigger').addEventListener('click', (e) => {
e.stopPropagation();
const btn = e.currentTarget;
btn.querySelector('span').innerText = "LINKING...";
setTimeout(() => { btn.querySelector('span').innerText = "CONNECTED"; }, 1000);
});
resize();
animate();
})();
</script>
</section>