# Liquid Ether

> A glowing liquid that swirls under the cursor, colored by how fast it flows, with a sweeping intro, click puffs, presets and a light mode.

A glowing liquid that swirls under the cursor. Calm areas take the first color and the fastest currents the last, so every stroke glows hotter at its core. On mount a swirl sweeps out from the center; while the cursor is away the liquid stirs itself. Move the pointer to push it, and click to shoot a puff in the direction you were moving. It runs a stable-fluids solver on raw WebGL2 at half-float precision and sleeps when the motion settles or the canvas scrolls out of view.

<demo-liquid-ether>



</demo-liquid-ether>

## Installation

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

## Usage

```vue
<script setup lang="ts">
  import LiquidEther from '~/components/ui/liquid-ether/LiquidEther.vue';
</script>

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <LiquidEther
      :colors="['#5227FF', '#FF9FFC', '#B497CF']"
      :mouse-force="20"
      :cursor-size="100"
      :persistence="0.75"
      click-burst
    />
  </div>
</template>
```

On a light page, pass `light-mode` so the flow renders as soft ink instead of glowing light.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        colors
      </code>
    </td>
    
    <td>
      <code>
        string[]
      </code>
    </td>
    
    <td>
      <code>
        ['#5227FF', '#FF9FFC', '#B497CF']
      </code>
    </td>
    
    <td>
      Colors from slow to fast flow. Calm areas take the first color, the fastest currents the last.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Brightness of the flow.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-force
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        20
      </code>
    </td>
    
    <td>
      How strongly the cursor pushes the liquid.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cursor-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        100
      </code>
    </td>
    
    <td>
      Size of the area the cursor stirs, in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        persistence
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.75
      </code>
    </td>
    
    <td>
      How long the motion lingers before it settles, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        viscosity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      How thick the liquid is, from 0 to 1. Thicker liquid moves in broad, slow swirls.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        resolution
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Detail of the simulation, from 0.1 to 1. Lower values are faster and softer.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-demo
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Stirs the liquid on its own while the cursor is away.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Speed of the automatic stirring.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2.2
      </code>
    </td>
    
    <td>
      Strength of the automatic stirring compared with the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        auto-resume-delay
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1000
      </code>
    </td>
    
    <td>
      Milliseconds without input before the automatic stirring resumes.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-burst
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking shoots a puff of liquid in the direction the cursor was moving.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bounce-edges
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      The liquid bounces off the edges instead of flowing out of view.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      A swirl sweeps out from the center on mount.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Renders the flow as soft ink for light backgrounds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'transparent'
      </code>
    </td>
    
    <td>
      Solid color behind the flow. Leave transparent to show the page through.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        max-device-pixel-ratio
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2
      </code>
    </td>
    
    <td>
      Highest pixel ratio the canvas renders at.
    </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 above it.
- With `prefers-reduced-motion: reduce`, the intro sweep, the automatic stirring and click puffs are off; the liquid only moves when the pointer moves it.
- The animation pauses when the canvas is off screen or the tab is hidden, and stops once the motion settles.
- Pointer input is read from the window, so the canvas can sit under other content and still react.
- Ported from [React Bits](https://reactbits.dev/backgrounds/liquid-ether) by David Haz.
