← Volver

Lightspeed Star Tunnel Hero

Cinematic warp-speed star tunnel with mouse-controlled center for immersive space travel effect

UI
Preview
<section class="w-full h-screen bg-black overflow-hidden relative">

  <canvas id="tunnel"></canvas>

  <div class="absolute inset-0 flex items-center justify-center pointer-events-none">
    <h1 class="text-white text-4xl md:text-6xl font-semibold tracking-tight text-center">
      Enter Hyper Speed
    </h1>
  </div>

  <script>
    const canvas = document.getElementById("tunnel");
    const ctx = canvas.getContext("2d");

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    let centerX = canvas.width / 2;
    let centerY = canvas.height / 2;

    let targetX = centerX;
    let targetY = centerY;

    const stars = [];

    for (let i = 0; i < 400; i++) {
      stars.push({
        x: (Math.random() - 0.5) * canvas.width,
        y: (Math.random() - 0.5) * canvas.height,
        z: Math.random() * canvas.width
      });
    }

    // πŸ‘‰ Mouse moves tunnel center
    window.addEventListener("mousemove", (e) => {
      targetX = e.clientX;
      targetY = e.clientY;
    });

    function animate() {
      ctx.fillStyle = "black";
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // smooth follow (important πŸ”₯)
      centerX += (targetX - centerX) * 0.05;
      centerY += (targetY - centerY) * 0.05;

      stars.forEach(star => {

        star.z -= 8;

        if (star.z <= 0) {
          star.z = canvas.width;
        }

        const k = 128 / star.z;

        const x = star.x * k + centerX;
        const y = star.y * k + centerY;

        const size = (1 - star.z / canvas.width) * 3;

        // trail line (speed effect πŸ”₯)
        const px = star.x * (128 / (star.z + 8)) + centerX;
        const py = star.y * (128 / (star.z + 8)) + centerY;

        ctx.strokeStyle = "rgba(255,255,255,0.8)";
        ctx.lineWidth = size;
        ctx.beginPath();
        ctx.moveTo(px, py);
        ctx.lineTo(x, y);
        ctx.stroke();

      });

      requestAnimationFrame(animate);
    }

    animate();

    // responsive
    window.addEventListener("resize", () => {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    });
  </script>

</section>