# Galaxy

> An endless flight through a twinkling starfield with warp jumps, cursor repulsion and star palettes.

An endless flight through layers of twinkling stars, drawn in one raw WebGL2 shader with no extra dependencies. It arrives from hyperspace on mount, then keeps gliding forward while the field slowly turns. Move the cursor and the stars glide out of its way; click to jump to warp speed and watch the stars stretch into streaks. Stars can take a hue-shifted color or come from a palette of up to four colors, the brightest ones carry cross flares, and light mode draws them as ink on paper. Pick a preset in the demo panel, or press refresh to replay the intro.

<demo-galaxy>



</demo-galaxy>

## Installation

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

## Usage

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

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <Galaxy
      :density="1"
      :glow-intensity="0.3"
      :star-speed="0.5"
      :hue-shift="140"
      :twinkle-intensity="0.3"
      :rotation-speed="0.1"
      :mouse-repulsion="true"
      :repulsion-strength="2"
      :click-warp="true"
    />
  </div>
</template>
```

The demo presets ship with the component: `galaxyPreset('hyperdrive')` returns the props of the Classic, Stardust, Hyperdrive, Sparkle, Drift or Cluster preset, and `GALAXY_PALETTES` holds the Stardust, Ice, Gold and Rose star colors.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        star-colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Up to four colors the stars are picked from. Replaces the hue shift and saturation coloring.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hue-shift
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        140
      </code>
    </td>
    
    <td>
      Shifts the hue of the stars, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        saturation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Color saturation of the stars, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        density
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How densely the stars are packed.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow-intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      Brightness of the glow around each star.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        star-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of each star glow.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        flare-intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the cross flares on the brightest stars.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        twinkle-intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      How much the stars twinkle, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        star-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How fast you travel through the stars.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Overall speed of the animation.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        rotation-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.1
      </code>
    </td>
    
    <td>
      How fast the starfield rotates.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        layers
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        4
      </code>
    </td>
    
    <td>
      Number of star layers, from 2 to 8.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        direction
      </code>
    </td>
    
    <td>
      <code>
        'forward' | 'backward'
      </code>
    </td>
    
    <td>
      <code>
        'forward'
      </code>
    </td>
    
    <td>
      Whether you fly into the stars or drift back out of them.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-interaction
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Lets the cursor interact with the stars.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-repulsion
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Pushes the stars away from the cursor. When off, the field shifts with the cursor instead.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        repulsion-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Strength of the push away from the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-center-repulsion
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Pushes the stars away from the center without the cursor. <code>
        0
      </code>
      
       turns it off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-warp
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking jumps forward at warp speed.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Drops out of warp speed on mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        focal
      </code>
    </td>
    
    <td>
      <code>
        [number, number]
      </code>
    </td>
    
    <td>
      <code>
        [0.5, 0.5]
      </code>
    </td>
    
    <td>
      Center of the starfield, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        rotation
      </code>
    </td>
    
    <td>
      <code>
        [number, number]
      </code>
    </td>
    
    <td>
      <code>
        [1, 0]
      </code>
    </td>
    
    <td>
      Fixed rotation of the starfield as a <code>
        [cos, sin]
      </code>
      
       pair.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        transparent
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Shows the page behind the stars. When off, the stars sit on the background color.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#000000'
      </code>
    </td>
    
    <td>
      Background behind the stars when <code>
        transparent
      </code>
      
       is off, or the paper color in light mode.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the stars as ink for light backgrounds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        opacity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Opacity of the whole effect.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        disable-animation
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Freezes the animation.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dpr
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      auto
    </td>
    
    <td>
      Maximum device pixel ratio, capped at 2.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes merged on the container.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The canvas is decorative and marked `aria-hidden="true"`. Put real content above it.
- Pointer listeners are passive and sit on `window`, so the starfield never takes focus or blocks clicks on content above it.
- With `prefers-reduced-motion: reduce` there is no intro, flight, rotation, cursor effect or warp jump. The stars are drawn and hold still.
- The render loop stops when the animation is frozen and idle, offscreen or in a hidden tab.
- Ported from [React Bits](https://reactbits.dev/backgrounds/galaxy) by David Haz.
