Components/Liquid

Liquid

A two-layer group whose touching pieces merge like liquid.

VerifiedSince 0.3.9

Usage

Morph

With the default effect="morph", give items x / y: element and liquid animate together, and touching pieces merge like droplets.

Loading demo...

Shape Physics

morph.shape turns on shape change: the mass flows to the new centre first, size and radius follow, and content blurs in motion and sharpens as it settles.

<template>
  <TxLiquid :blur="8" fill="var(--tx-bg-color)">
    <TxLiquidItem :morph="{ shape: true, speed: 1, bounce: 0.5 }">
      <div :class="open ? 'panel-open' : 'panel-closed'">…</div>
    </TxLiquidItem>
  </TxLiquid>
</template>

Dissolve

dissolve is orthogonal to effect: at the contact point, the item's imagery melts into its neighbour through a turbulence warp, not a blur. Text never melts.

<template>
  <TxLiquid :blur="10" fill="var(--tx-bg-color)">
    <TxLiquidItem dissolve>
      <img class="avatar" src="/a.png" alt="">
    </TxLiquidItem>
    <TxLiquidItem :dissolve="{ mix: 0.7, active: dragging }">
      <img class="avatar" src="/b.png" alt="">
    </TxLiquidItem>
  </TxLiquid>
</template>

Move Trail

With effect="move", you move the element yourself (CSS or pointer events); the liquid chases it on a spring and drags a droplet tail.

Loading demo...

Best Practices

  • Keep item backgrounds transparent: the liquid is the surface. Opaque content, such as a round photo, covers its own blob.
  • Pass a CSS variable as fill (e.g. var(--tx-bg-color)) so the liquid follows the theme.
  • Put shadows on shadow, not on children, so one shadow hugs the merged liquid.
  • When pieces that should merge look separate, raise blur before tuning anything else.
  • For high-frequency dragging, start from the effect="move" defaults; reach for advanced only if they fall short.

API Reference

TxLiquid

Props

PropTypeDefaultDescription
blurnumber6Goo blur sigma (px); sets how far apart pieces start bridging.
contrastnumber18Alpha-contrast slope; larger values give a sharper liquid edge.
fillstring'#fff'Liquid surface color; accepts var().
shadowstring-box-shadow syntax drawn on the merged silhouette; inset layers paint inside.
filterPaddingnumber24Extra filter-region slack (px) for blobs that leave the group box.

Slots

SlotPropsDescription
default-Several TxLiquidItem nodes.

TxLiquidItem

Props

PropTypeDefaultDescription
effect'morph' | 'move''morph'Liquid behavior: morph merges, move chases with a tail.
morphMorphTuning-shape / speed / bounce / contentBlur, plus the advanced escape hatch.
moveMoveTuning-springiness / wobble / stretch / trail, plus advanced.
dissolveboolean | number | DissolveOptions-Contact-melt modifier; 0..1 scales its intensity.
x / y / scalenumber0 / 0 / 1Component-driven position and scale, pixel-synced with the liquid.
transition'snappy' | 'smooth' | 'bouncy' | SpringConfig | { duration, ease }'smooth'Spring or duration transition for x / y.
delaynumber0Transition delay in ms, for staggering.
observebooleanfalseMakes the liquid follow content you animate yourself; implied by morph.shape, dissolve, and move.
radiusnumber | [tl, tr, br, bl]measuredOverrides the radius measured from computed style.

Slots

SlotPropsDescription
default-The real interactive content; keep its background transparent.

Overview

  • TxLiquid is a relatively positioned isolation: isolate container: the silhouette SVG sits below every child, the melt overlay above the content, and neither takes pointer events.
  • TxLiquidItem must render inside a TxLiquid, or it throws.
  • Size the group to contain the items' full travel; bridging starts roughly once blur ≳ gap.
  • The component owns the wrapper's transform (x/y/scale), the content filter during morph.shape, and mask-image on <img> (dissolve); don't set your own.
  • dissolve with effect="move" is ignored with a warning; under reduced motion, component-driven transitions become instant.
  • The entry also exports resolveTransition(transition, reducedMotion?) and liquidTransitionPresets, which compile a preset or SpringConfig into { duration, easing } (CSS linear(), or cubic-bezier where unsupported) for WAAPI or CSS motion outside the component.

Technologies

  • The silhouette layer merges each item's blob through an SVG goo filter (Gaussian blur plus alpha contrast); the content layer skips the filter and stays crisp and interactive.
  • Ported from Jakubantalik/Libraries · liquid-gooey (MIT © Jakub Antalik); React's Liquid / Liquid.Item map to TxLiquid / TxLiquidItem.
  • Source: packages/tuffex/packages/components/src/liquid/.
查看源码
packages/tuffex/packages/components/src/liquid/index.ts