# Floating Lines

> Ribbons of fine glowing lines that drift in waves, part around the cursor and curl when clicked.

Three waves of fine, glowing lines drift across the canvas. Move the cursor over them and the lines part around it while the waves shift in depth; click and the lines curl into a swirl that slowly unwinds in the direction the cursor was moving. On mount the waves swell in from flat lines. Raw WebGL2, no 3D library.

<demo-floating-lines>



</demo-floating-lines>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import FloatingLines from '~/components/ui/floating-lines/FloatingLines.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden bg-black">
    <FloatingLines
      :lines-gradient="['#7fb2ff', '#ffffff']"
      line-style="dashed"
      :glow="0.6"
      :enabled-waves="['middle', 'bottom']"
    />
  </div>
</template>
```

The canvas is transparent and blends with `mix-blend-mode: screen`, so it sits on any dark page. Set `background-color` for an opaque backdrop, and `light-mode` on light pages: the lines print as ink instead of light. `floatingLinesPreset('signature' | 'classic' | 'mono' | 'lagoon' | 'ember' | 'dotted' | 'blueprint' | 'calm')` returns a ready-made look you can spread onto the component with `v-bind`.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        lines-gradient
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      <code>
        ['#e945f5', '#ffffff']
      </code>
    </td>
    
    <td>
      Up to 8 colors blended across the lines of each wave.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        enabled-waves
      </code>
    </td>
    
    <td>
      <code>
        Array<'top' | 'middle' | 'bottom'>
      </code>
    </td>
    
    <td>
      <code>
        ['top', 'middle', 'bottom']
      </code>
    </td>
    
    <td>
      Which waves to show.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        line-count
      </code>
    </td>
    
    <td>
      <code>
        number | number[]
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      Lines per wave, from 1 to 24. Pass an array to set each enabled wave separately.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        line-distance
      </code>
    </td>
    
    <td>
      <code>
        number | number[]
      </code>
    </td>
    
    <td>
      <code>
        6
      </code>
    </td>
    
    <td>
      Spacing between the lines of a wave. Pass an array to set each enabled wave separately.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        line-style
      </code>
    </td>
    
    <td>
      <code>
        'solid' | 'dotted' | 'dashed'
      </code>
    </td>
    
    <td>
      <code>
        'solid'
      </code>
    </td>
    
    <td>
      Draws the lines as solid strands, rows of dots or dashes.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        line-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Width of each line in pixels.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the glow around the lines.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        brightness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Overall brightness of the lines.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        animation-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Speed of the wave motion.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        amplitude
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Height of the waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        depth-of-field
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How much the waves in the back soften out of focus, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        edge-fade
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Fades the lines out toward the left and right edges, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        top-wave-position
      </code>
    </td>
    
    <td>
      <code>
        { x?: number; y?: number; rotate?: number }
      </code>
    </td>
    
    <td>
      <code>
        { x: 10, y: 0.5, rotate: -0.4 }
      </code>
    </td>
    
    <td>
      Offset, height and curl of the top wave.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        middle-wave-position
      </code>
    </td>
    
    <td>
      <code>
        { x?: number; y?: number; rotate?: number }
      </code>
    </td>
    
    <td>
      <code>
        { x: 5, y: 0, rotate: 0.2 }
      </code>
    </td>
    
    <td>
      Offset, height and curl of the middle wave.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bottom-wave-position
      </code>
    </td>
    
    <td>
      <code>
        { x?: number; y?: number; rotate?: number }
      </code>
    </td>
    
    <td>
      <code>
        { x: 2, y: -0.7, rotate: -1 }
      </code>
    </td>
    
    <td>
      Offset, height and curl of the bottom wave.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        interactive
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Bends the lines around the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bend-radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        5
      </code>
    </td>
    
    <td>
      Size of the area around the cursor that bends the lines.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bend-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        -0.5
      </code>
    </td>
    
    <td>
      Negative values part the lines around the cursor, positive values pull them in.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-damping
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.05
      </code>
    </td>
    
    <td>
      How smoothly the bend follows the cursor, from 0 (frozen) to 1 (instant).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        parallax
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Shifts the waves in depth as the cursor moves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        parallax-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.2
      </code>
    </td>
    
    <td>
      Strength of the parallax shift.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-swirl
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking stirs the lines into a curl that slowly unwinds, turning the way the cursor moved.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Swells the waves in from flat lines on mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mix-blend-mode
      </code>
    </td>
    
    <td>
      <code>
        CSSProperties['mixBlendMode']
      </code>
    </td>
    
    <td>
      <code>
        'screen'
      </code>
    </td>
    
    <td>
      CSS mix-blend-mode of the container in dark mode.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        undefined
      </code>
    </td>
    
    <td>
      Paints an opaque background behind the lines. Leave it unset for a transparent canvas.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the lines 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>
        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 waves hold still, the intro is skipped, and the cursor bend and click swirl are turned off.
- Rendering stops while the effect is off screen or the tab is hidden.
- Ported from [React Bits](https://reactbits.dev/backgrounds/floating-lines) by David Haz.
