VibeCoderzVibeCoderz
Telegram
All Prompts
Interactive Network Hero with Animated Stats Ticker preview
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>
All Prompts