import { E as ElementAnchor, b as ShaderScene } from '../../shader-B7AluScJ.js'; import 'react/jsx-runtime'; import 'react'; interface LiquidPresetOptions { /** PBR metalness on the liquid plane. Default: 0.35 */ metalness?: number; /** PBR roughness on the liquid plane. Default: 0.45 */ roughness?: number; /** Baseline displacement amplitude. The surface returns to this value when idle. Default: 2 */ displacementScale?: number; /** Whether raindrops fall on the surface. Default: false */ rain?: boolean; /** Time between raindrops in seconds. Ignored when `rain` is false. */ rainTime?: number; /** * Whether the cursor itself creates ripples (small drops on pointermove, * larger drops on click — both attached globally to `document.body` by * `liquid1`). Disable when you want the surface driven only by your own * `controls.pulse()` / `controls.setDisplacement()` calls. Default: true */ cursorDrops?: boolean; /** * Number of wave-simulation steps run per rendered frame. The shader's * wave equation propagates one cell per step, so this is the seam to * speed up the effect: 2 makes the wavefront travel ~2× faster across * the surface (and decays ~2× faster per visual frame, since the * built-in damping compounds). Costs N × the wave-sim GPU work. * Integer ≥ 1. Default: 1 */ simulationStepsPerFrame?: number; /** * Multiplier on the env-map contribution to the surface's reflections. * `liquid1` bakes a built-in studio scene (PointLight intensity 900 + * emissive ceiling intensity 100) into an env map — that's the bright * highlight you see at center. Lower this to dim the reflections; set to * 0 to remove them entirely. Default: 1 */ envMapIntensity?: number; /** Renderer pixel ratio. "auto" uses `window.devicePixelRatio`. Default: "auto" */ pixelRatio?: number | "auto"; /** Environment map URL for PBR reflections. Default: none (dark reflections). */ envMap?: string; /** * Built-in lighting mode used when no `envMap` URL is provided. * - "studio" (default): bundled bake — bright PointLight overhead, central hotspot. * - "softbox": HDR torus ring above the surface — directional highlights on * wave crests, no central hotspot, homogeneous in azimuth. * * Ignored when `envMap` is set; user-supplied env maps always win. * Default: "studio" */ lighting?: "studio" | "softbox"; /** * Wave-velocity damping per simulation step. The wave-sim multiplies each * cell's velocity by this value every step — values closer to 1 make ripples * dissipate slower, values further from 1 make them fade faster. * * The effective decay per visual frame compounds with `simulationStepsPerFrame`: * at 60fps with 1 step/frame the half-life is `ln(0.5)/(60·ln(attenuation))` seconds * (~2.3s at the default 0.995). Bumping `simulationStepsPerFrame` shortens * decay AND speeds up wavefront propagation; tune `attenuation` to control * decay independently. * * Reasonable range: ~0.97 (very short) … 0.9995 (very long). Default: 0.995 */ attenuation?: number; /** * Gate env-map specular reflections by surface slope. When true, flat regions * (calm water, ambient ripples) receive zero env contribution — the underlying * snapshot shows through cleanly with no PMREM-blur halos or reflection tint — * and only steep wave crests light up with the configured `lighting`. * * Combine with any `lighting` mode. Default: false */ reflectionOnSlopeOnly?: boolean; /** * `[edge0, edge1]` for the slope gate's `smoothstep`. The slope metric is * `length(transformedNormal.xy)` — 0 on flat water, rising with tilt. * * - `edge0`: slopes below this are fully gated out (snapshot shows through). * Raise to tolerate stronger ambient ripples without acquiring highlights. * - `edge1`: slopes above this get full env contribution (PBR + reflections). * Lower to let gentler waves catch highlights; raise to require steeper * crests. * * Only takes effect when `reflectionOnSlopeOnly` is true (or set to true at * runtime via `controls.setReflectionOnSlopeOnly`). Default: [0.05, 0.4] */ slopeGateRange?: [number, number]; } /** * Anything that can stand in for a screen-space point: a real DOM event, a * synthetic React event, or a hand-built `{ clientX, clientY }` literal. */ type ScreenPoint = { clientX: number; clientY: number; } | MouseEvent | PointerEvent | Touch; interface DropAtOptions { /** Forwarded to the underlying drop. Defaults to `0.04`. */ size?: number; /** Forwarded to the underlying drop. Defaults to `0.05`. */ strength?: number; /** * When the target is an `Element`, which point of its bounding box to fire * the ripple from. Ignored for `ScreenPoint` targets. Defaults to `"center"`. */ anchor?: ElementAnchor; } interface LiquidControls { /** * Set displacement amplitude immediately. Compose with any animation lib * (e.g. motion's `animate({ onUpdate: setDisplacement })`). No-op until * `` mounts; safe to call before/after mount. */ setDisplacement: (value: number) => void; /** * Trigger a built-in burst: ramps from baseline → `peak` → baseline over * `durationMs`. Pulse modulates the displacement *amplitude* — it is only * visible when there are existing ripples to amplify. Combine with `drop()` * (or `rain`) to produce the actual waves. Cancels any in-flight pulse. * No-op until `` mounts. */ pulse: (peak?: number, durationMs?: number) => void; /** * Add a localized ripple at normalized device coordinates (`x`, `y` ∈ [-1, 1], * with y up). Bypasses the `cursorDrops` filter, so it always fires. * Defaults: center of the surface, medium-sized splash. No-op until * `` mounts. * * For screen-space input (mouse events, button centers), prefer `dropAt` * — it handles canvas-bounds conversion automatically and works for shaders * that aren't fullscreen. */ drop: (x?: number, y?: number, size?: number, strength?: number) => void; /** * Drop a ripple at a screen-space point or DOM element. Converts to NDC * against the mounted canvas's bounds, so it works whether the shader is * fullscreen or confined to a smaller container. * * - Pass an `Element` to fire from its center (or anchor, via `opts.anchor`). * Works for keyboard-triggered clicks where `clientX/Y` would be `0`. * - Pass a `MouseEvent`/`PointerEvent`/`Touch` to fire from the pointer. * - Pass any `{ clientX, clientY }` literal for fully custom positioning. * * No-op until `` mounts. */ dropAt: (target: Element | ScreenPoint, opts?: DropAtOptions) => void; /** * Change simulation steps per frame at runtime. Integer ≥ 1. * See `LiquidPresetOptions.simulationStepsPerFrame`. */ setSimulationStepsPerFrame: (value: number) => void; /** * Set the env-map contribution multiplier. 0 = no reflections; 1 = default; * values >1 will exaggerate the built-in studio lighting. */ setEnvMapIntensity: (value: number) => void; /** * Set the wave-velocity damping per simulation step. See * `LiquidPresetOptions.attenuation` for the exact role. */ setAttenuation: (value: number) => void; /** * Toggle slope-gated reflections at runtime. See * `LiquidPresetOptions.reflectionOnSlopeOnly`. No-op until `` mounts. */ setReflectionOnSlopeOnly: (on: boolean) => void; /** * Adjust the slope gate's `smoothstep` thresholds at runtime. See * `LiquidPresetOptions.slopeGateRange`. No-op until `` mounts. */ setSlopeGateRange: (range: [number, number]) => void; /** * Switch lighting mode at runtime. No-op when an `envMap` URL was provided * at construction (the user's explicit choice wins; construct a new handle * to switch). No-op until `` mounts. */ setLighting: (mode: "studio" | "softbox") => void; /** Toggle raindrops at runtime. */ setRain: (on: boolean) => void; } interface LiquidHandle { scene: ShaderScene; controls: LiquidControls; } /** * Reusable `liquid1` scene factory for ``. * * Returns a `{ scene, controls }` handle. Pass `scene` to ``; use * `controls` to drive the effect imperatively from event handlers. * * @example * import { liquidPreset } from "shader-dom/presets/liquid" * * const liquid = liquidPreset({ cursorDrops: false }) * * * * * * */ declare function liquidPreset(options?: LiquidPresetOptions): LiquidHandle; export { type DropAtOptions, type LiquidControls, type LiquidHandle, type LiquidPresetOptions, type ScreenPoint, liquidPreset };