Hyperiux Vault

Numeric Tunnel

Component 28

About

WebGL loader: rings of counting digits spawn from center and scale outward through a tunnel, then crossfade via a chromatic-aberration warp shader into your content.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Numeric Tunnel to your project and fits it to your theme.

Code

How Numeric Tunnel is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

"use client";

import { useCallback, useState } from "react";
import NumericTunnel from "@/components/ui/numeric-tunnel";

export default function NumericTunnelDemo() {
  const [isComplete, setIsComplete] = useState(false);
  const [instance, setInstance] = useState(0);

  const handleComplete = useCallback(() => {
    setIsComplete(true);
  }, []);

  const handleReplay = useCallback(() => {
    setIsComplete(false);
    setInstance((current) => current + 1);
  }, []);

  return (
    <NumericTunnel key={instance} onComplete={handleComplete}>
      <div className="relative flex h-screen w-full flex-col justify-between overflow-hidden bg-[#0e0e0c] text-white">
        <img
          src="https://cdn.21st.dev/assets/mirror/54/54954611e11f8afe47c25bff036f8887022cb5b8389e45568564d88aebdba1fc.jpg"
          alt=""
          className="absolute inset-0 h-full w-full object-cover"
        />
        <div className="absolute inset-0 bg-gradient-to-t from-black/85 via-black/25 to-black/50" />

        <div className="relative z-10 flex items-center justify-between px-8 py-6 max-md:px-5">
          <span className="text-sm font-semibold uppercase tracking-[0.2em]">Northline</span>
          <button type="button" aria-label="Menu" className="flex flex-col items-end gap-1.5">
            <span className="h-0.5 w-7 bg-white" />
            <span className="h-0.5 w-5 bg-white" />
          </button>
        </div>

        <div className="relative z-10 flex max-w-3xl flex-col gap-5 px-8 pb-16 max-md:px-5 max-md:pb-10">
          <p className="text-xs uppercase tracking-[0.3em] text-white/50">Studio reel — 2026</p>
          <h1 className="text-[6vw] font-medium leading-[0.95] tracking-tight max-md:text-[10vw]">
            We build things that move.
          </h1>
          <button
            type="button"
            onClick={handleReplay}
            className={`mt-2 inline-flex w-fit items-center gap-2 rounded-full border border-white/20 bg-white/10 px-5 py-2 text-sm font-medium backdrop-blur-md transition-all duration-300 hover:scale-105 hover:bg-white/20 active:scale-95 ${
              isComplete ? "opacity-100" : "pointer-events-none opacity-0"
            }`}
          >
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="h-4 w-4 shrink-0" aria-hidden="true">
              <path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
              <path d="M3 3v5h5" />
            </svg>
            Replay
          </button>
        </div>
      </div>
    </NumericTunnel>
  );
}

Dependencies

More by Hyperiux Vault

View all
  • Product Timeline

    Product Timeline

    2.3K
  • Stack Spread

    Stack Spread

    1.3K
  • Arrow Fill Button

    Arrow Fill Button

    912
  • Interactive List Preview

    Interactive List Preview

    869
  • Shiny Button

    Shiny Button

    750
  • Circular Split Roll

    Circular Split Roll

    641
  • Zoom Slider

    Zoom Slider

    430
  • Stack Loader

    Stack Loader

    371

Explore more

Part of Hyperiux Vault — browse the full library on 21st.dev.