# Ghost Fibers

> Layered ribbons of fine glowing fibers that twist, fold and drift through soft depth of field.

A WebGL2 background of up to three ribbons, each made of many fine fibers drawn as dots, dashes or lines. The ribbons twist and roll, the camera blurs what is out of focus, and bloom lights the folds. Move the cursor to pull the focus onto the ribbon under it (or part the fibers around it), and click a ribbon to send a pulse of light along it.

<demo-ghost-fibers>



</demo-ghost-fibers>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import GhostFibers from '~/components/ui/ghost-fibers/GhostFibers.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden bg-black">
    <GhostFibers
      glow-color="#8b5cf6"
      line-color="#dfd1fc"
      secondary-color="#6f4ac5"
      :layers="3"
      :threads="72"
      hover-effect="focus"
    />
  </div>
</template>
```

The effect is additive light, so it reads best on a dark background. On a light background set `light-mode`; the fibers are then drawn as colored ink, and darker colors such as `#7c3aed` / `#4c1d95` work best. The demo switches to this mode when the site is in light theme.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        glow-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#8b5cf6'
      </code>
    </td>
    
    <td>
      Main color of the fibers.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        line-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Color of the bright folds, sparkles and tips. Leave out to use a pale tint of the glow color.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        secondary-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Second color the gradient blends toward. Leave out to use a deeper shade of the glow color.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        gradient
      </code>
    </td>
    
    <td>
      <code>
        'depth' | 'along' | 'across'
      </code>
    </td>
    
    <td>
      <code>
        'depth'
      </code>
    </td>
    
    <td>
      How the two colors blend: by distance, along the length of the ribbons, or across their width.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        layers
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      Number of ribbons, from 1 to 3.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        waves
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How much the ribbons undulate. 0 keeps them straight.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        twist
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1.2
      </code>
    </td>
    
    <td>
      How often the ribbons turn over along their length.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        volume
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.7
      </code>
    </td>
    
    <td>
      Thickness of each ribbon, from a single flat sheet at 0 to a layered bundle.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        spread
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Width of the ribbons.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of the whole effect.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        rotation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        18
      </code>
    </td>
    
    <td>
      Tilt of the whole effect, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        perspective
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.65
      </code>
    </td>
    
    <td>
      How far the ribbons turn into the distance, from side-on at 0 to steeply receding at 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        threads
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        72
      </code>
    </td>
    
    <td>
      Number of fibers in each ribbon.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        density
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Number of dots along each fiber.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        thickness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of the dots.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fiber-style
      </code>
    </td>
    
    <td>
      <code>
        'dots' | 'dashes' | 'lines'
      </code>
    </td>
    
    <td>
      <code>
        'dots'
      </code>
    </td>
    
    <td>
      Draws the fibers as rows of dots, short dashes or continuous lines.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tips
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Cuts the fibers at different lengths and lights their ends, like fiber optics.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fold-glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Brightness of the light where the ribbons fold edge-on.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Speed of the waves and the twist. 0 holds them still.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        flow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.4
      </code>
    </td>
    
    <td>
      Speed of the dots along the fibers. Negative values reverse them.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        roll-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.15
      </code>
    </td>
    
    <td>
      How fast the ribbons roll around their length.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        depth-of-field
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.85
      </code>
    </td>
    
    <td>
      Strength of the camera blur away from the focus. 0 keeps everything sharp.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        focus-depth
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Moves the focus nearer with negative values or farther with positive ones.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        particles
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Amount of dust floating around the ribbons.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sparkle
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How often single dots twinkle.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.8
      </code>
    </td>
    
    <td>
      Strength of the bloom around the bright areas.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        brightness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Overall brightness.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        vignette
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      How much the edges fade out, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        grain
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.06
      </code>
    </td>
    
    <td>
      Strength of the film grain.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-interaction
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Lets the view follow the cursor slightly and turns on the hover effect.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-effect
      </code>
    </td>
    
    <td>
      <code>
        'focus' | 'part' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'focus'
      </code>
    </td>
    
    <td>
      Pulls the focus to the ribbon under the cursor, parts the fibers around it, or does nothing.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the hover effect.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pulse-on-click
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Sends a pulse of light along the ribbon you click.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Draws the ribbons in from one end when the effect first appears.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the fibers as colored ink for light backgrounds.
    </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>
        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 has `aria-hidden="true"`. Put real content on top of it.
- With `prefers-reduced-motion: reduce`, the animation and intro stop, and the hover and click effects are off.
- Clicks on links, buttons, inputs and labels on top of the effect do not trigger a pulse.
- Rendering pauses while the effect is offscreen or the tab is hidden.
- Ported from [React Bits](https://reactbits.dev/backgrounds/ghost-fibers) by David Haz.
