# Light Pillar

> A swirling pillar of light that ignites on load, leans toward the cursor and surges on click.

A raymarched pillar of light strands drawn with raw WebGL2. It ignites from the bottom when it mounts. Move the cursor over it and the pillar leans, drifts and turns toward you. Click to send a surge of light up the pillar.

<demo-light-pillar>



</demo-light-pillar>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import LightPillar from '~/components/ui/light-pillar/LightPillar.vue';
</script>

<template>
  <div class="relative h-150 w-full overflow-hidden bg-black">
    <LightPillar
      top-color="#5227FF"
      bottom-color="#FF9FFC"
      :pillar-rotation="25"
      :bloom="0.5"
    />
  </div>
</template>
```

The strands render at a reduced resolution into a mipmapped buffer, then a
second pass upscales them with a bicubic filter and adds bloom, grain and
pulses. The render scale drops on its own when frames run slow. The loop
stops when the pillar is paused and settled, off screen, or the tab is hidden.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        top-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#5227FF'
      </code>
    </td>
    
    <td>
      Color of the lower, denser part of the pillar.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bottom-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#FF9FFC'
      </code>
    </td>
    
    <td>
      Color the light fades into toward the top.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Overall brightness.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow-amount
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.002
      </code>
    </td>
    
    <td>
      How much light the strands gather. Higher values burn brighter and whiter.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bloom
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Soft halo around the brightest strands, 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pillar-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      Width of the pillar.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pillar-height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.4
      </code>
    </td>
    
    <td>
      Vertical stretch of the strands. Higher values pack them tighter.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pillar-rotation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        25
      </code>
    </td>
    
    <td>
      Tilts the pillar, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        twist
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.4
      </code>
    </td>
    
    <td>
      How much the strands swirl around each other.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        detail
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        4
      </code>
    </td>
    
    <td>
      Layers of turbulence in the strands, 1 to 6. Fewer layers are smoother and faster.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        rotation-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      How fast the pillar turns. Also drives the overall animation speed.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        flow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How fast the light streams along the pillar, relative to the rotation.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        noise-intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Strength of the film grain.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        interactive
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The pillar leans, drifts and turns toward the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-pulse
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking sends a surge of light racing up the pillar.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The pillar ignites from the bottom and widens when it first appears.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Fades the edges into the page, 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        quality
      </code>
    </td>
    
    <td>
      <code>
        'low' | 'medium' | 'high'
      </code>
    </td>
    
    <td>
      <code>
        'high'
      </code>
    </td>
    
    <td>
      Render resolution of the light. The pillar is soft, so lower settings look similar.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        resolution
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Exact render scale relative to the element size, 0.25 to 2. Overrides <code>
        quality
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mix-blend-mode
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'screen'
      </code>
    </td>
    
    <td>
      CSS blend mode for the canvas. Screen lets the page show through the dark areas.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the pillar as colored light on a white background.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        paused
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Freezes the animation.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes merged onto the container.
    </td>
  </tr>
</tbody>
</table>

The component is absolutely positioned and fills its nearest positioned parent.
On a light page, use `light-mode` with `mix-blend-mode="normal"`; screen
blending disappears against white.

## Accessibility

- The canvas is decorative (`aria-hidden="true"`). Pointer input is read from the window, so it never blocks content placed on top.
- With `prefers-reduced-motion: reduce`, the pillar renders one still frame: no rotation, intro, cursor lean or click surges.
- Ported from [React Bits](https://reactbits.dev/backgrounds/light-pillar) by David Haz.
