# Prism

> Rotating prism of glowing spectral light with configurable shape, colors and motion.

A raymarched prism of glowing spectral light drawn in one raw WebGL2 pass, with no extra dependencies. It fades in on mount and spins in place, tumbles in 3D, or holds still. Move the cursor over it and the prism tilts toward you.

<demo-prism>



</demo-prism>

## Installation

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

## Usage

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

<template>
  <div class="relative h-125 w-full overflow-hidden bg-black">
    <Prism
      animation-type="rotate"
      :time-scale="0.5"
      :height="3.5"
      :base-width="5.5"
      :scale="3.6"
      :glow="1"
      :hover-strength="2"
      :inertia="0.05"
    />
  </div>
</template>
```

The canvas is transparent. Pass `light-mode` on a white page to draw the light as colored ink instead of additive glow.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        animation-type
      </code>
    </td>
    
    <td>
      <code>
        'rotate' | '3drotate' | 'rotate3d' | 'hover' | 'static'
      </code>
    </td>
    
    <td>
      <code>
        'rotate'
      </code>
    </td>
    
    <td>
      Rotate spins in place, 3D rotate tumbles, hover turns only toward the cursor, static holds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        time-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Speed of the rotation. 0 holds it still.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      <code>
        []
      </code>
    </td>
    
    <td>
      Custom colors cycled through the color bands, up to 8. Leave empty for the original spectrum.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Brightness of the light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3.6
      </code>
    </td>
    
    <td>
      Size of the prism on screen. Larger values zoom in.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3.5
      </code>
    </td>
    
    <td>
      Height of the prism from its base to its tip.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        base-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        5.5
      </code>
    </td>
    
    <td>
      Width of the prism at its base.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hue-shift
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Rotates every color around the color wheel, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color-frequency
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How quickly the colors change through the light. Higher values show more bands.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        saturation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1.5
      </code>
    </td>
    
    <td>
      Color intensity, from 0 (grayscale) to 2.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        noise
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Film grain over the light, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        offset
      </code>
    </td>
    
    <td>
      <code>
        { x?: number; y?: number }
      </code>
    </td>
    
    <td>
      <code>
        { x: 0, y: 0 }
      </code>
    </td>
    
    <td>
      Moves the prism by a number of pixels, x to the right and y down.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        interactive
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Tilts the prism toward the cursor in every animation mode.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      How far the prism turns toward the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        inertia
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.05
      </code>
    </td>
    
    <td>
      How quickly the prism follows the cursor, from 0.01 (slow and smooth) to 1 (instant).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Fades the light in on mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        resolution
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Fraction of the screen resolution rendered, 0.25 to 1. The glow is soft, so 0.5 looks the same.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the light as colored ink for light backgrounds.
    </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 for the container.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The canvas is decorative and marked `aria-hidden="true"`. Put real content on top of it.
- With `prefers-reduced-motion: reduce` the prism renders a still frame: no intro, no rotation and no cursor tilt.
- Pointer tracking is passive and never blocks scrolling or clicks on content above the prism.
- Rendering stops when the prism is offscreen, the tab is hidden, or nothing is moving.
- Ported from [React Bits](https://reactbits.dev/backgrounds/prism) by David Haz.
