# Ripple Grid

> A crisp grid that ripples like water, bending and lighting up as waves pass through it, with dot, cross and perspective-floor styles.

A crisp grid drawn in raw WebGL2 that ripples like water. Real waves travel outward from the center (or from random spots), bending the lines and lighting them up as each crest passes. Move the cursor and it leaves a wake of small ripples and lights the lines nearby; click to send a strong ripple. Draw it as lines, dots or small crosses, tilt it back into a perspective floor, or switch on light mode for light backgrounds. Pick a preset in the demo panel, or press refresh to replay the intro.

<demo-ripple-grid>



</demo-ripple-grid>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import RippleGrid from '~/components/ui/ripple-grid/RippleGrid.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <RippleGrid
      color="#ffffff"
      variant="lines"
      :cell-size="48"
      :glow="0.6"
      auto-ripple="center"
      :ripple-interval="2.6"
      :fade="0.5"
      :click-ripple="true"
    />
  </div>
</template>
```

The demo presets ship with the component: `rippleGridPreset('floor')` returns the grid shape of the Pulse, Floor, Dots, Cross or Calm preset. Color is left to you.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#ffffff'
      </code>
    </td>
    
    <td>
      Color of the grid. Light mode derives its ink from it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        variant
      </code>
    </td>
    
    <td>
      <code>
        'lines' | 'dots' | 'cross'
      </code>
    </td>
    
    <td>
      <code>
        'lines'
      </code>
    </td>
    
    <td>
      Draws the grid as lines, dots at each crossing, or small crosses.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cell-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        48
      </code>
    </td>
    
    <td>
      Size of each grid cell, in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        line-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Width of the lines, in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glow
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      Soft glow around the lines.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How far ripples bend the grid and how brightly their crests light it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How fast ripples travel outward.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Wavelength of the ripples.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-ripple
      </code>
    </td>
    
    <td>
      <code>
        'center' | 'random' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'center'
      </code>
    </td>
    
    <td>
      Where idle ripples start: from the center, at random spots, or not at all.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-interval
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2.6
      </code>
    </td>
    
    <td>
      Seconds between idle ripples.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Lays the grid back in perspective, like a floor, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        rotation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Turns the grid, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-interaction
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The cursor leaves a wake of small ripples and lights up the lines nearby.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-ripple
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking sends a strong ripple.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Reveals the grid with a ripple from the center.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Fades the edges into the page, from 0 to 1.
    </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>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the grid as 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 merged on the container.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The canvas is decorative and marked `aria-hidden="true"`. Put real content above it and check its contrast against your grid color.
- Pointer listeners are passive and sit on `window`, so the grid never takes focus or blocks clicks on content above it.
- With `prefers-reduced-motion: reduce` there is no intro, idle ripple, cursor wake or click ripple. The grid is drawn and holds still.
- The render loop stops when the grid is paused and settled, offscreen or in a hidden tab.
- Ported from [React Bits](https://reactbits.dev/backgrounds/ripple-grid) by David Haz.
