# Gradient Waves

> Lit satin waves rolling in from a hazy horizon, with a light that follows the cursor and swells on click.

A ray-marched WebGL2 sea of soft gradient waves that fade into a colored haze at the horizon. The waves rise from calm water on load, the light and the view turn gently toward the cursor, and a click sends a swell rolling in from that point.

<demo-gradient-waves>



</demo-gradient-waves>

## Installation

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

## Usage

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

<template>
  <div class="relative h-125 w-full">
    <GradientWaves
      horizon-color="#5227FF"
      wave-color="#FF9FFC"
      crest-color="#FFFFFF"
    />
  </div>
</template>
```

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        horizon-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#5227FF'
      </code>
    </td>
    
    <td>
      Haze the waves fade into toward the horizon, and the tint of their shadows.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#FF9FFC'
      </code>
    </td>
    
    <td>
      Main color of the wave bodies.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        crest-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#FFFFFF'
      </code>
    </td>
    
    <td>
      Color of the crests and the light they catch.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'transparent'
      </code>
    </td>
    
    <td>
      Fills the canvas behind the waves. Transparent lets the page show through.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Draws the waves as soft colored ink for light pages.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.4
      </code>
    </td>
    
    <td>
      How fast the waves roll in.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        amplitude
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2.5
      </code>
    </td>
    
    <td>
      Height of the waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      How many waves fit in view. Higher is choppier.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wave-ratio
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.9
      </code>
    </td>
    
    <td>
      Balance between the long rolling waves and the shorter cross waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        swell
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        35
      </code>
    </td>
    
    <td>
      How much the long waves bend and meander.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        turbulence
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        20
      </code>
    </td>
    
    <td>
      How much the cross waves wander.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        64
      </code>
    </td>
    
    <td>
      Camera angle in degrees, from looking down to facing the horizon.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        zoom
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Field of view. Higher zooms in.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        5.5
      </code>
    </td>
    
    <td>
      Water level. Higher brings the waves closer.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fog-depth
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        15
      </code>
    </td>
    
    <td>
      How far you can see before the waves fade out.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        relief
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Depth of the light and shadow on the waves. 0 gives flat gradient waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-angle
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        120
      </code>
    </td>
    
    <td>
      Direction the light comes from, in degrees. 0 lights the waves from behind you, 180 from the horizon.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sheen
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Strength of a soft highlight on the crests.
    </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>
        opacity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Opacity of the whole effect.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        grain
      </code>
    </td>
    
    <td>
      <code>
        number | boolean
      </code>
    </td>
    
    <td>
      <code>
        0.2
      </code>
    </td>
    
    <td>
      Film grain on the waves, up to 0.5. 0 turns it off.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        quality
      </code>
    </td>
    
    <td>
      <code>
        'low' | 'medium' | 'high'
      </code>
    </td>
    
    <td>
      <code>
        'medium'
      </code>
    </td>
    
    <td>
      Rendering precision. Lower is faster on weak devices.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Starts from calm water and lets the waves rise from the horizon toward you.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-interaction
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The light follows the cursor across the waves and the view turns gently toward it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        parallax-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How far the view turns toward the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.6
      </code>
    </td>
    
    <td>
      How far the light turns to follow the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        swell-on-click
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking sends a swell rolling in from that point.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        paused
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Freezes the waves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        dpr
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Maximum device pixel ratio of the canvas.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Additional CSS classes for the container.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

The canvas is decorative and hidden from assistive technology (`aria-hidden`). With `prefers-reduced-motion: reduce` the waves hold still, the intro is skipped, and the cursor and click effects are off. Clicks on links, buttons and form fields placed over the background never start a swell. The render loop stops when the component is offscreen or the tab is hidden, and goes idle when nothing is moving.

- Ported from [React Bits](https://reactbits.dev/backgrounds/gradient-waves) by David Haz.
