API Reference

Imperative control via FluidHandle.

While the <Fluid> component is primarily declarative (props in, simulation out), sometimes you need imperative control: injecting splats from application logic, pausing the simulation in response to an event, or querying the engine state. The FluidHandle interface provides this.

Getting the Handle

Use Svelte's bind:this to capture a reference to the component instance. The handle property exposes the imperative API.

<script lang="ts">
  import { Fluid } from 'svelte-fluid';
  import type { FluidHandle } from 'svelte-fluid';

  let fluidRef: { handle: FluidHandle };
</script>

<Fluid bind:this={fluidRef} />

<button onclick={() => fluidRef.handle.randomSplats(5)}>
  Add splats
</button>

The same pattern works with presets — every preset component exposes the same handle property:

<script lang="ts">
  import { LavaLamp } from 'svelte-fluid';
  import type { FluidHandle } from 'svelte-fluid';

  let lampRef: { handle: FluidHandle };
</script>

<LavaLamp bind:this={lampRef} />

FluidHandle Methods

splat(x, y, dx, dy, color)

Inject a single splat at the given position with velocity and color.

ParameterTypeDescription
xnumberX position in normalized coords (0 = left, 1 = right)
ynumberY position in normalized coords (0 = bottom, 1 = top)
dxnumberX velocity (raw value, not scaled by splatForce)
dynumberY velocity (raw value, not scaled by splatForce)
colorRGBColor in 0-1 linear range. Values above 1 are valid HDR and appear as bloom highlights.
// Inject a bright red splat at the center moving rightward
fluidRef.handle.splat(0.5, 0.5, 500, 0, { r: 1.5, g: 0.1, b: 0.1 });

Velocity values are in pixels per frame and written directly to the splat shader uniform. Unlike pointer-driven splats, these are not multiplied by splatForce. Pick the absolute magnitude you want. Typical values range from 100 (gentle) to 1000 (forceful).

randomSplats(count)

Push N additional random splats onto the splat queue. Colors are generated by the engine's internal generateColor function.

ParameterTypeDescription
countnumberNumber of random splats to inject
// Add 10 random splats
fluidRef.handle.randomSplats(10);

pause()

Stop the animation loop. The WebGL context stays alive but no frames are requested. Call resume() to restart. Idempotent — calling pause() on an already-paused engine is a no-op.

fluidRef.handle.pause();

resume()

Restart the animation loop after a pause(). Idempotent — calling resume() on an already-running engine is a no-op.

fluidRef.handle.resume();

isPaused

Readonly boolean property indicating whether the engine's animation loop is currently paused.

if (fluidRef.handle.isPaused) {
  fluidRef.handle.resume();
}

Types

RGB

A simple color triple with r, g, b number fields. The unit convention depends on context:

ContextRangeNotes
backColor prop0-255CSS-style. Normalized internally before reaching the shader.
FluidHandle.splat() color0-1Linear. Values above 1 are valid HDR and create bloom highlights.
PresetSplat.color0-1Linear. Same convention as splat().
revealCoverColor, revealAccentColor, revealFringeColor0-1Linear.
interface RGB {
  r: number;
  g: number;
  b: number;
}

PresetSplat

Declarative initial splat consumed once at engine construction. Used by preset wrappers to paint a deterministic opening scene.

FieldTypeDescription
xnumberX position, 0-1 (left to right)
ynumberY position, 0-1 (bottom to top)
dxnumberX velocity (raw, not scaled by splatForce)
dynumberY velocity (raw, not scaled by splatForce)
colorRGBColor in 0-1 linear range (HDR values above 1 are valid)
interface PresetSplat {
  x: number;
  y: number;
  dx: number;
  dy: number;
  color: RGB;
}

FluidEngine (Advanced)

For advanced users who need framework-agnostic fluid simulation, the FluidEngine class is available as a direct import. It is the WebGL engine that powers the <Fluid> component, but it has no Svelte dependency.

import { FluidEngine } from 'svelte-fluid/engine/FluidEngine';

The engine is constructed with a canvas element and a config object matching the FluidConfig interface. It exposes the same splat(), randomSplats(), pause(), resume(), and isPaused API as FluidHandle, plus additional methods:

  • setConfig(config) — update configuration at runtime (respects the 4-bucket system)
  • dispose() — free all GPU resources (textures, framebuffers, programs). The WebGL context is left intact for potential reuse.

Architecture invariant: the engine never imports Svelte. It is fully framework-agnostic and could be used with React, vanilla JS, or any other framework. The Svelte component is a thin wrapper that handles lifecycle, sizing, and prop reactivity.