# Dither

Slow fractal waves drawn in crisp retro pixels. Pick a dither pattern (Bayer 8×8, 4×4, 2×2, halftone, lines, crosshatch or noise), a number of shades, or swap the colors for an indexed palette like Game Boy or Blueprint. Move the pointer and it erases, reveals or ripples the waves, leaving a fading trail; click to send a ring through the field. On mount the waves bloom out from the center. It renders on raw WebGL2 in two passes, so the pixels stay sharp at any size.

<demo-dither>



</demo-dither>

## Installation

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

## Usage

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

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <Dither
      wave-color="#bcbcbc"
      background-color="#120f17"
      dither-mode="bayer"
      :pixel-size="2"
      mouse-effect="erase"
      :mouse-radius="0.3"
    />
  </div>
</template>
```

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        wave-color
      </code>
    </td>
    
    <td>
      <code>
        string | [number, number, number]
      </code>
    </td>
    
    <td>
      <code>
        [0.5, 0.5, 0.5]
      </code>
    </td>
    
    <td>
      Color of the waves. Any CSS color, or a linear RGB array from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background-color
      </code>
    </td>
    
    <td>
      <code>
        string | [number, number, number]
      </code>
    </td>
    
    <td>
      <code>
        [0, 0, 0]
      </code>
    </td>
    
    <td>
      Color behind the waves. Use <code>
        'transparent'
      </code>
      
       to dither the waves over your own background.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dither-mode
      </code>
    </td>
    
    <td>
      <code>
        'bayer' | 'bayer4' | 'bayer2' | 'halftone' | 'lines' | 'crosshatch' | 'noise' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'bayer'
      </code>
    </td>
    
    <td>
      Pattern used to dither the shades.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        palette
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Two to eight colors from dark to light. Replaces the wave and background colors.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color-num
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        4
      </code>
    </td>
    
    <td>
      Number of shades per color channel.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pixel-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Size of each dither pixel, in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of the wave pattern.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.05
      </code>
    </td>
    
    <td>
      Speed of the wave animation.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave-frequency
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      How much finer each layer of detail gets.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave-amplitude
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      How strongly the finer layers of detail show.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        contrast
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Contrast of the waves before dithering.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        brightness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Brightens or darkens the waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        enable-mouse-interaction
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Lets the cursor interact with the waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-effect
      </code>
    </td>
    
    <td>
      <code>
        'erase' | 'reveal' | 'ripple'
      </code>
    </td>
    
    <td>
      <code>
        'erase'
      </code>
    </td>
    
    <td>
      Erase darkens the waves under the cursor, reveal lights them up and ripple bends them.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Radius of the cursor effect.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the cursor effect.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        trail
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How long the cursor leaves a fading trail, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-ripple
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking sends a ring through the waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Resolves from the center to full detail on mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        disable-animation
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Freezes the wave 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 marked `aria-hidden`. Put real content on top of it.
- With `prefers-reduced-motion: reduce` the waves, intro, trail and ripples stop and a single still frame is drawn.
- The render loop pauses when the canvas scrolls offscreen or the tab is hidden, and sleeps when the animation is disabled and nothing is settling.
- Ported from [React Bits](https://reactbits.dev/backgrounds/dither) by David Haz.
