All Prompts
All Prompts

herosectionlandinganimatedinteractivetickercanvastailwind
Interactive Network Hero with Animated Stats Ticker
Интерактивный hero-блок для лендинга: заголовок, анимированный тикер статистики, визуализация сети. Tailwind CSS. Идеально для SaaS, инфраструктуры.
Prompt
<section class="font-sans antialiased text-blue-100 min-h-screen flex flex-col bg-blue-950" style="background: radial-gradient(circle at top center, #1e3a8a 0%, #020617 100%);">
<div class="max-w-7xl mx-auto w-full flex-grow flex flex-col relative border-x border-blue-800/40">
<!-- Top Corner Squares -->
<div class="absolute -top-[3px] -left-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
<div class="absolute -top-[3px] -right-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
<!-- Header Section -->
<header class="pt-24 pb-16 px-6 text-center border-b border-blue-800/40 relative z-10 flex flex-col items-center">
<!-- Header Intersection Squares -->
<div class="absolute -bottom-[3px] -left-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
<div class="absolute -bottom-[3px] -right-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
<h1 class="text-5xl md:text-6xl font-light tracking-tight text-white max-w-3xl mx-auto leading-[1.1]">
The infrastructure <br> for worldwide connectivity
</h1>
<div class="h-px w-24 bg-gradient-to-r from-transparent via-blue-500/50 to-transparent mt-10 mb-8"></div>
<p class="text-lg text-blue-200/70 font-light max-w-2xl mx-auto leading-relaxed">
Enabling digital-first organizations to expand across borders through a resilient, high-speed routing architecture built for the modern web.
</p>
</header>
<!-- Ticker Stats Section -->
<section class="border-b border-blue-800/40 relative z-10 bg-blue-900/20 backdrop-blur-sm overflow-hidden py-8">
<!-- Ticker Intersection Squares -->
<div class="absolute -bottom-[3px] -left-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
<div class="absolute -bottom-[3px] -right-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
<div id="tickerContainer" class="flex whitespace-nowrap w-max" style="will-change: transform;">
<!-- Ticker Content -->
<div id="tickerContent" class="flex gap-8 px-4 items-center">
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-white tracking-tight">120+</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
availability zones worldwide
</div>
</div>
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-blue-100 tracking-tight">
<span class="text-blue-500/70 font-light mr-1">$</span>3.2T
</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
processed safely annually
</div>
</div>
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-blue-400 tracking-tight">99.999%</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
guaranteed system reliability
</div>
</div>
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-blue-100 tracking-tight">850M+</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
authenticated daily sessions
</div>
</div>
</div>
<!-- Duplicated Ticker Content for Seamless Loop -->
<div class="flex gap-8 px-4 items-center" aria-hidden="true">
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-white tracking-tight">120+</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
availability zones worldwide
</div>
</div>
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-blue-100 tracking-tight">
<span class="text-blue-500/70 font-light mr-1">$</span>3.2T
</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
processed safely annually
</div>
</div>
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-blue-400 tracking-tight">99.999%</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
guaranteed system reliability
</div>
</div>
<div class="flex items-center gap-6 pr-8 border-r border-blue-800/50">
<div class="text-3xl font-light text-blue-100 tracking-tight">850M+</div>
<div class="text-xs text-blue-300/70 max-w-[120px] whitespace-normal leading-relaxed">
authenticated daily sessions
</div>
</div>
</div>
</div>
</section>
<!-- Animation Section -->
<main class="flex-grow relative overflow-hidden min-h-[500px] cursor-crosshair">
<!-- Controls -->
<div class="absolute top-6 right-6 flex gap-3 z-20">
<button id="pauseBtn" class="w-10 h-10 flex items-center justify-center bg-blue-900/40 hover:bg-blue-800/60 backdrop-blur-md border border-blue-700/50 rounded-full text-blue-200 transition-all cursor-pointer" aria-label="Pause animation">
<iconify-icon icon="solar:pause-linear" width="18" height="18"></iconify-icon>
</button>
<button class="w-10 h-10 flex items-center justify-center bg-blue-900/40 hover:bg-blue-800/60 backdrop-blur-md border border-blue-700/50 rounded-full text-blue-200 transition-all cursor-pointer" aria-label="Settings">
<iconify-icon icon="solar:settings-linear" width="18" height="18"></iconify-icon>
</button>
</div>
<!-- Canvas Container -->
<canvas id="networkCanvas" class="absolute inset-0 w-full h-full block z-0"></canvas>
<!-- Subtle Bottom Gradient -->
<div class="absolute bottom-0 left-0 right-0 h-64 bg-gradient-to-t from-blue-500/10 to-transparent pointer-events-none z-10"></div>
</main>
<!-- Bottom Corner Squares -->
<div class="absolute -bottom-[3px] -left-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
<div class="absolute -bottom-[3px] -right-[3px] w-1.5 h-1.5 bg-blue-400 z-30"></div>
</div>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://code.iconify.design/iconify-icon/1.0.7/iconify-icon.min.js"></script>
<script>
// Ticker Animation Logic
const ticker = document.getElementById('tickerContainer');
const tickerContent = document.getElementById('tickerContent');
let tickerPos = 0;
function animateTicker() {
tickerPos -= 0.6;
if (Math.abs(tickerPos) >= tickerContent.offsetWidth) {
tickerPos = 0;
}
ticker.style.transform = `translateX(${tickerPos}px)`;
requestAnimationFrame(animateTicker);
}
animateTicker();
// Canvas Network Animation Logic
const canvas = document.getElementById('networkCanvas');
const ctx = canvas.getContext('2d', { alpha: true });
let width, height;
let particles = [];
let isPlaying = true;
let animationFrameId;
// Mouse Interaction State
const mouse = { x: -1000, y: -1000, clickPulse: 0 };
window.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left;
mouse.y = e.clientY - rect.top;
});
window.addEventListener('click', () => {
mouse.clickPulse = 250;
});
window.addEventListener('mouseleave', () => {
mouse.x = -1000;
mouse.y = -1000;
});
function resize() {
width = canvas.clientWidth;
height = canvas.clientHeight;
canvas.width = width * window.devicePixelRatio;
canvas.height = height * window.devicePixelRatio;
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
initParticles();
}
class Particle {
constructor() {
this.vx = 0;
this.vy = 0;
this.offsetX = 0;
this.offsetY = 0;
this.reset(true);
}
reset(initial = false) {
this.angle = Math.PI + (Math.random() * Math.PI);
if (Math.random() > 0.3) {
this.angle = Math.PI * 1.25 + (Math.random() * Math.PI * 0.5);
}
this.speed = 0.5 + Math.random() * 2.5;
this.distance = initial ? Math.random() * (height * 1.2) : Math.random() * 50;
this.maxLength = 20 + Math.random() * 180;
this.length = 0;
this.alpha = 0;
this.vx = 0;
this.vy = 0;
this.offsetX = 0;
this.offsetY = 0;
}
update() {
this.distance += this.speed;
this.length = Math.min(this.maxLength, this.distance * 0.8);
const normalizedDist = this.distance / (height * 1.2);
this.alpha = Math.min(1, this.distance / 100) * Math.max(0, 1 - normalizedDist);
if (this.distance > height * 1.5) {
this.reset();
}
// Interactive Physics
const originX = width / 2;
const originY = height + 50;
const targetX = originX + Math.cos(this.angle) * (this.distance + this.length);
const targetY = originY + Math.sin(this.angle) * (this.distance + this.length);
const dx = (targetX + this.offsetX) - mouse.x;
const dy = (targetY + this.offsetY) - mouse.y;
const dist = Math.sqrt(dx * dx + dy * dy);
// Hover Repel
if (dist < 120 && dist > 0.1) {
const force = (120 - dist) / 120;
this.vx += (dx / dist) * force * 1.2;
this.vy += (dy / dist) * force * 1.2;
}
// Click Shockwave
if (mouse.clickPulse > 0 && dist < mouse.clickPulse && dist > 0.1) {
const force = (mouse.clickPulse - dist) / mouse.clickPulse;
this.vx += (dx / dist) * force * 6.0;
this.vy += (dy / dist) * force * 6.0;
}
// Apply velocity, friction, and spring back to original path
this.offsetX += this.vx;
this.offsetY += this.vy;
this.vx *= 0.82;
this.vy *= 0.82;
this.offsetX -= this.offsetX * 0.08;
this.offsetY -= this.offsetY * 0.08;
}
draw() {
const originX = width / 2;
const originY = height + 50;
// Bend the line by applying offset more strongly to the end
const startX = originX + Math.cos(this.angle) * this.distance + (this.offsetX * 0.2);
const startY = originY + Math.sin(this.angle) * this.distance + (this.offsetY * 0.2);
const endX = originX + Math.cos(this.angle) * (this.distance + this.length) + this.offsetX;
const endY = originY + Math.sin(this.angle) * (this.distance + this.length) + this.offsetY;
const distRatio = Math.min(1, this.distance / height);
let hue = distRatio < 0.3
? 200 + (distRatio / 0.3) * (215 - 200)
: 215 + ((distRatio - 0.3) / 0.7) * (230 - 215);
const color = `hsla(${hue}, 90%, 65%, ${this.alpha})`;
const tailColor = `hsla(${hue}, 90%, 65%, ${this.alpha * 0.05})`;
ctx.beginPath();
const gradient = ctx.createLinearGradient(startX, startY, endX, endY);
gradient.addColorStop(0, tailColor);
gradient.addColorStop(1, color);
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = gradient;
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.arc(endX, endY, 1.2, 0, Math.PI * 2);
ctx.fillStyle = `hsla(${hue}, 100%, 75%, ${this.alpha * 1.5})`;
ctx.fill();
}
}
function initParticles() {
particles = [];
const particleCount = window.innerWidth < 768 ? 150 : 350;
for(let i=0; i<particleCount; i++) {
particles.push(new Particle());
}
}
function animate() {
if (!isPlaying) return;
ctx.clearRect(0, 0, width, height);
if (mouse.clickPulse > 0) {
mouse.clickPulse *= 0.92;
if (mouse.clickPulse < 1) mouse.clickPulse = 0;
}
particles.forEach(p => {
p.update();
p.draw();
});
animationFrameId = requestAnimationFrame(animate);
}
window.addEventListener('resize', () => {
cancelAnimationFrame(animationFrameId);
resize();
if(isPlaying) animate();
});
// Initialize
resize();
animate();
// Pause Toggle Logic
const pauseBtn = document.getElementById('pauseBtn');
pauseBtn.addEventListener('click', () => {
isPlaying = !isPlaying;
if (isPlaying) {
pauseBtn.innerHTML = '<iconify-icon icon="solar:pause-linear" width="18" height="18"></iconify-icon>';
animate();
} else {
pauseBtn.innerHTML = '<iconify-icon icon="solar:play-linear" width="18" height="18"></iconify-icon>';
cancelAnimationFrame(animationFrameId);
}
});
</script>
</section>