# Hyperspeed

A three.js night highway. Tail lights stream away on the left road, headlights rush toward you on the right, light poles flick past both shoulders and dust streaks through the air, all wrapped in a soft bloom. The road bends along one of six curve shapes and morphs smoothly when you switch. Click and hold to boost: the traffic speeds up, the trails stretch into warp lines and the camera field of view springs wider. Move the pointer and the camera drifts toward it. The canvas is transparent by default, so your page shows through.

<demo-hyperspeed>



</demo-hyperspeed>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/hyperspeed.json"
```

## Usage

```vue
<script setup lang="ts">
  import Hyperspeed from '~/components/ui/hyperspeed/Hyperspeed.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <Hyperspeed
      curve="winding"
      :tail-colors="['#d856bf', '#6750a2', '#c247ac']"
      :head-colors="['#03b3c3', '#0e5ea5', '#324555']"
      :pole-colors="['#03b3c3']"
      @boost-start="onBoostStart"
      @boost-end="onBoostEnd"
    />
  </div>
</template>
```

The component fills its nearest positioned parent (`absolute inset-0`).

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        tail-colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      theme
    </td>
    
    <td>
      Colors of the lights moving away on the left road. Defaults to magentas and violet.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        head-colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      theme
    </td>
    
    <td>
      Colors of the oncoming lights on the right road. Defaults to cyan and deep blues.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pole-colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      theme
    </td>
    
    <td>
      Colors of the light poles along both shoulders.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        curve
      </code>
    </td>
    
    <td>
      <code>
        'straight' | 'gentle' | 'winding' | 'hills' | 'racing' | 'deep'
      </code>
    </td>
    
    <td>
      <code>
        'winding'
      </code>
    </td>
    
    <td>
      Shape of the road. Switching between curves morphs the road smoothly.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        curvature
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How strongly the road bends. 0 is straight.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Cruising speed of the traffic, poles and road markings.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        boost
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      Speed multiplier while the pointer is held down. The lights stretch into longer trails.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fov
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        90
      </code>
    </td>
    
    <td>
      Camera field of view in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        boost-fov
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        130
      </code>
    </td>
    
    <td>
      Field of view while boosting. The camera springs between the two.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        lanes
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      Lanes on each side of the road.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        road-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      Width of each side of the road.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        median-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Width of the strip between the two sides.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        density
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        40
      </code>
    </td>
    
    <td>
      Cars on each side of the road, up to 160.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        trail-length
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Length of the light trails.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Thickness of the light trails.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        poles
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        20
      </code>
    </td>
    
    <td>
      Light poles on each shoulder, up to 80. 0 removes them.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pole-height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Height of the light poles.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dust
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        100
      </code>
    </td>
    
    <td>
      Speed streaks flying past in the air, up to 1500. They stretch into warp lines while boosting.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      Soft bloom around every light. Dense traffic glows brighter. 0 turns it off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        reflections
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How much the lights reflect on the road, like wet asphalt at night.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        road-opacity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.1
      </code>
    </td>
    
    <td>
      Opacity of the road and its markings. Reflections fade with it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        steer
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.35
      </code>
    </td>
    
    <td>
      How far the camera drifts and turns toward the pointer.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        road-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      theme
    </td>
    
    <td>
      Color of the asphalt. The median takes a slightly lighter shade.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        line-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      theme
    </td>
    
    <td>
      Color of the lane markings.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      transparent
    </td>
    
    <td>
      Color behind the road, which the road fades into. Leave it unset to keep the canvas transparent.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        theme
      </code>
    </td>
    
    <td>
      <code>
        'dark' | 'light'
      </code>
    </td>
    
    <td>
      <code>
        'dark'
      </code>
    </td>
    
    <td>
      Dark renders glowing light trails. Light renders crisp colored trails on a pale road.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        interactive
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Click and hold to boost, and let the camera follow the pointer.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        boosting
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Turns the boost on from your own code, for example while something loads.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the container.
    </td>
  </tr>
</tbody>
</table>

## Events

<table>
<thead>
  <tr>
    <th>
      Event
    </th>
    
    <th>
      Payload
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        boost-start
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Fired when the user starts boosting.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        boost-end
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Fired when the user lets go.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The canvas is decorative and marked `aria-hidden="true"`.
- The boost is a pointer-only flourish. Use the `boosting` prop to drive it from your own UI, for example a keyboard-accessible button.
- With `prefers-reduced-motion: reduce`, traffic runs at 30% speed and the field of view no longer springs while boosting.
- Rendering pauses while the component is offscreen.
- Ported from [React Bits](https://reactbits.dev/backgrounds/hyperspeed) by David Haz.
