# Pattern Waves

> A lit halftone surface of dots, lines or glyphs that moves like draped silk.

A WebGL background that prints a moving, lit surface as a halftone of dots, squares, plus signs, contour lines or characters. Pick a preset or tune each value. Move the cursor to leave a wake of ripples, and click to drop a splash.

<demo-pattern-waves>



</demo-pattern-waves>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import PatternWaves from '~/components/ui/pattern-waves/PatternWaves.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <PatternWaves
      preset="silk"
      color="#ffffff"
      background-color="#120f17"
      fade="edges"
      :fade-size="0.5"
      :cursor-size="50"
      :cursor-strength="0.6"
    />
  </div>
</template>
```

## Presets

<table>
<thead>
  <tr>
    <th>
      Preset
    </th>
    
    <th>
      Pattern
    </th>
    
    <th>
      Wave
    </th>
    
    <th>
      Look
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        silk
      </code>
    </td>
    
    <td>
      <code>
        dot
      </code>
    </td>
    
    <td>
      <code>
        silk
      </code>
    </td>
    
    <td>
      Draped fabric folds in fine dots.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ocean
      </code>
    </td>
    
    <td>
      <code>
        dot
      </code>
    </td>
    
    <td>
      <code>
        swell
      </code>
    </td>
    
    <td>
      Rolling parallel waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pond
      </code>
    </td>
    
    <td>
      <code>
        dot
      </code>
    </td>
    
    <td>
      <code>
        ripple
      </code>
    </td>
    
    <td>
      Rings that travel in from off screen.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        lines
      </code>
    </td>
    
    <td>
      <code>
        line
      </code>
    </td>
    
    <td>
      <code>
        silk
      </code>
    </td>
    
    <td>
      Flowing contour lines.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        terminal
      </code>
    </td>
    
    <td>
      <code>
        glyph
      </code>
    </td>
    
    <td>
      <code>
        ripple
      </code>
    </td>
    
    <td>
      Characters picked by brightness.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mesh
      </code>
    </td>
    
    <td>
      <code>
        plus
      </code>
    </td>
    
    <td>
      <code>
        silk
      </code>
    </td>
    
    <td>
      A grid of plus signs.
    </td>
  </tr>
</tbody>
</table>

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        preset
      </code>
    </td>
    
    <td>
      <code>
        'silk' | 'ocean' | 'pond' | 'lines' | 'terminal' | 'mesh'
      </code>
    </td>
    
    <td>
      <code>
        'silk'
      </code>
    </td>
    
    <td>
      A complete starting look. Every pattern, wave and light prop below overrides the preset value when you pass it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pattern
      </code>
    </td>
    
    <td>
      <code>
        'dot' | 'square' | 'plus' | 'line' | 'glyph'
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      The mark that draws the surface. Line traces it as flowing contour lines, glyph uses characters picked by brightness.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave
      </code>
    </td>
    
    <td>
      <code>
        'silk' | 'swell' | 'ripple'
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      The shape of the moving surface. Silk is draped fabric folds, swell is rolling parallel waves, ripple is rings travelling in from off screen.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#ffffff'
      </code>
    </td>
    
    <td>
      The one color of the pattern. Shadows, midtones and highlights come from it. A color darker than the background prints like ink.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#000000'
      </code>
    </td>
    
    <td>
      Color behind the pattern. Pass <code>
        transparent
      </code>
      
       to show the page through.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        spacing
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      Distance between marks in CSS pixels. Smaller values give a finer print.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mark-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      Largest mark as a fraction of the spacing.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        depth
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      How tall the surface is. Deeper surfaces cast stronger shading and lift the marks along the crests.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      Angle of the light across the waves in degrees, from -90 to 90. 0 lights the folds head on, larger values graze them.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shine
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      Strength of the glints where the surface catches the light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        contrast
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      Spread between the quiet shadows and the lit areas.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      How fast the surface moves. 0 freezes it while the cursor keeps working.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      Size of the waves. Larger values give broader, calmer forms.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        direction
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      from preset
    </td>
    
    <td>
      Direction the waves travel in degrees. The light turns with it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        opacity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Overall opacity of the pattern, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade
      </code>
    </td>
    
    <td>
      <code>
        'edges' | 'center' | 'bottom' | 'top' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'edges'
      </code>
    </td>
    
    <td>
      Where the pattern fades into the background. Center keeps the middle calm for a headline.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How far the fade reaches, from 0.05 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        characters
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '.:-=+*#%@'
      </code>
    </td>
    
    <td>
      Characters for the glyph pattern, from the lightest to the densest.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        interactive
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Lets the cursor disturb the surface. Moving it leaves a wake of ripples, a click drops a splash.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cursor-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        50
      </code>
    </td>
    
    <td>
      Radius of the patch of surface the cursor pushes, in CSS pixels.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cursor-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      How hard the cursor pushes the surface, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      On mount the marks fade in from the center, then the surface rises.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        paused
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Freezes the surface. The cursor ripples keep working.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the root element.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        style
      </code>
    </td>
    
    <td>
      <code>
        StyleValue
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Inline styles for the root element.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The canvas has `aria-hidden="true"`. The effect is decorative and carries no information.
- Put text and controls on top of it in normal DOM. Pointer events pass through to your content; the component listens on `window`.
- With `prefers-reduced-motion: reduce`, the surface stays still, the intro is skipped and cursor ripples are off.
- The render loop sleeps when the surface is still and when it is off screen.
- Ported from [React Bits](https://reactbits.dev/backgrounds/pattern-waves) by David Haz.
