# Liquid Chrome

> Soft ribbons of liquid chrome that swirl through a dark pool, ripple under the cursor and catch the light as it moves.

Glossy ribbons of liquid metal drawn by a raw WebGL2 shader and lit by a virtual photo studio. The chrome rises from the surface on mount and keeps flowing. Move the cursor to leave a liquid wake and turn the reflections toward it; click to send a ripple across the pool. Pick a preset in the demo panel, switch the site theme for the light studio, or press refresh to replay the intro.

<demo-liquid-chrome>



</demo-liquid-chrome>

## Installation

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

## Usage

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

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <LiquidChrome
      color="#ffffff"
      :speed="0.2"
      :amplitude="0.3"
      :roughness="0.3"
      :ripple-strength="1"
    />
  </div>
</template>
```

The demo presets ship with the component: `liquidChromePreset('mercury')` returns the look of the Satin, Polished, Velvet, Mercury, Molten or Gold preset.

## 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 metal. White is polished chrome, warmer tones give gold or copper.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.2
      </code>
    </td>
    
    <td>
      How fast the chrome flows. 0 freezes it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        amplitude
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      How strongly the flow swirls and folds (0–2).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        frequency-x
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      How tightly the flow folds horizontally.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        frequency-y
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3
      </code>
    </td>
    
    <td>
      How tightly the flow folds vertically.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        detail
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        4
      </code>
    </td>
    
    <td>
      Layers of swirl, from 1 to 8. Low values give smooth, heavy shapes, high values intricate ones.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        thickness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Width of the chrome ribbons.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        depth
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How steeply the chrome rises from the surface. Higher values catch more reflections.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        roughness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.3
      </code>
    </td>
    
    <td>
      Softens the reflections, from a sharp mirror at 0 to a soft, frosted sheen at 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        exposure
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Brightness of the reflections.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        interactive
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The cursor leaves a wake, clicks send ripples out and the reflections follow the cursor.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How visible the wake and ripples are.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ripple-size
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of the wake and ripples.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How much the reflections sway and turn toward the cursor. 0 keeps the light still.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      The chrome rises from the surface when it mounts.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Lights the chrome for light pages, with soft gray contours instead of a dark studio.
    </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 merged on the container.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The canvas is decorative and marked `aria-hidden="true"`. Put real content above it.
- Pointer listeners are passive and sit on `window`, so the chrome never steals focus or clicks from your UI.
- With `prefers-reduced-motion: reduce` there is no intro, no wake and no ripples, the light holds still and the flow slows to a quarter of its speed.
- The render loop stops when the chrome is idle, offscreen or in a hidden tab. If the WebGL context is lost it waits and rebuilds when the browser restores it.
- Ported from [React Bits](https://reactbits.dev/backgrounds/liquid-chrome) by David Haz.
