# Ferrofluid

> A glossy sea of magnetic fluid where swells of spikes roll in and the cursor raises a crown.

A ray-marched sea of black magnetic fluid lit by three studio lights. Swells of spikes roll across the surface, the cursor acts as a magnet that raises a crown of spikes, and a click sends a ring of spikes out from that point. Raw WebGL2, no extra dependencies.

<demo-ferrofluid>



</demo-ferrofluid>

## Installation

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

## Usage

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

<template>
  <div class="relative h-125 w-full overflow-hidden">
    <Ferrofluid
      :colors="['#ffd2a1', '#ff8a4c', '#ff6a3d']"
      :brightness="1.1"
      :spike-height="1"
      :tilt="48"
      flow-direction="down"
    />
  </div>
</template>
```

The canvas is transparent by default, so the page background shows between the spikes. Set `:transparent="false"` to paint `color` behind the fluid. Use `light-mode` on light pages: the fluid turns into glossy white liquid.

## 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>
        ['#ffffff', '#ffffff', '#ffffff']
      </code>
    </td>
    
    <td>
      Colors of the studio lights reflected in the fluid: key light, side lights and fill light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        brightness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the reflections.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1.6
      </code>
    </td>
    
    <td>
      Zoom of the fluid. Higher values show bigger, fewer spikes.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        spike-height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How tall the spikes grow in a strong field.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sharpness
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        2.5
      </code>
    </td>
    
    <td>
      How peaked the spikes are. Low values give soft mounds, high values taller cones.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        48
      </code>
    </td>
    
    <td>
      Viewing angle in degrees. Low values look down from above, high values look across.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        turbulence
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      How much the spike pattern sways and drifts out of its regular grid.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fluidity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How loosely the spikes respond, from 0 (thick and slow) to 1 (bouncy).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How fast the swells roll across the surface.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        magnetism
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the magnetic field that raises swells of spikes.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        variation
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Picks a different arrangement of swells.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        flow-direction
      </code>
    </td>
    
    <td>
      <code>
        'down' | 'up' | 'left' | 'right' | 'none'
      </code>
    </td>
    
    <td>
      <code>
        'down'
      </code>
    </td>
    
    <td>
      Direction the swells roll. <code>
        none
      </code>
      
       keeps them morphing in place.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-interaction
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Turns the cursor into a magnet that raises a crown of spikes.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-strength
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Strength of the cursor magnet.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.22
      </code>
    </td>
    
    <td>
      Reach of the cursor magnet, as a fraction of the height.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mouse-dampening
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.15
      </code>
    </td>
    
    <td>
      Seconds the crown takes to catch up with the cursor. 0 follows instantly.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        click-pulse
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Clicking sends a magnetic pulse through the fluid.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Raises the spikes when the field switches on.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        light-mode
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Renders the fluid as glossy white liquid for light backgrounds.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        transparent
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Lets the page show through. When off, the fluid sits on <code>
        color
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#120f17'
      </code>
    </td>
    
    <td>
      Background color when <code>
        transparent
      </code>
      
       is off. Defaults to white in light mode.
    </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>
        paused
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Freezes the fluid.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mix-blend-mode
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      CSS <code>
        mix-blend-mode
      </code>
      
       applied to the container.
    </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 has `aria-hidden="true"`. Put real content on top of it.
- With `prefers-reduced-motion: reduce` the swells stop drifting, the intro and click pulse are skipped and the spikes settle at once.
- Rendering pauses while the component is off screen or the tab is hidden.
- Ported from [React Bits](https://reactbits.dev/backgrounds/ferrofluid) by David Haz.
