Skip to content
animorio
IT
All components

The merging filters

Tags, Physics, Transitions, HoverGSAP, CSS onlyAdvancedCompressed weight: Demo 11 KBGSAP 28 KBFreeDownload the zip

The filter chips of a park’s trails, filled with a green liquid: lit on its own, a drop lands in the middle and spreads to the ends; next to a lit chip the liquid runs over from the neighbour, and between two lit ones it comes in from both sides and the two fronts stretch towards each other until they join. Lit chips side by side are one pool; switch one off and the pool splits with a neck that thins out and breaks, while the count of the trails rolls to its new number.

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The merging filters</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/parkinsans@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the filters of a park's trails: a lit filter is filled with a liquid, and the liquid of two lit filters side by
         side runs together into one pool; switched off, the pool splits with a neck that stretches and breaks. The
         chips are made by the script from its list -->
    <div class="trails" data-trails data-autoclic>
      <div class="chips" role="group" aria-label="Filter the trails" data-chips>
        <div class="flow" aria-hidden="true" data-flow></div>
        <span class="ring" aria-hidden="true" data-ring></span>
      </div>
      <div class="result">
        <p class="result__count" aria-hidden="true"><span class="odo" data-odo></span> <span data-noun>trails</span></p>
        <button class="clear" type="button" aria-disabled="true" data-clear>Clear</button>
        <p class="result__names" data-names></p>
        <p class="sr" aria-live="polite" data-live></p>
      </div>
    </div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.

26 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The merging filters” from Animorio and fit it into my site

What it does

On a white background seven pill-shaped chips on two lines, outlined in a light grey: Easy, Loop, Dogs welcome, Waterfall, Shady, Lake view and Under 2 hours. Under them, on the left, the number of trails left, 12 trails, with the names of the first two and how many more there are; on the right, Clear. When the page opens the chips rise one after the other and a drop of dark green liquid lands in Easy and in Dogs welcome, with a lighter light along its top edge. Lighting a chip with no lit neighbours, a flat drop lands in the middle and spreads to both ends, swelling a little past the outline before it stops. Lighting one next to a lit chip, the liquid runs over from the neighbour and fills it from that side; between two lit ones it comes in from both sides: the two tips, stretched by their run, reach for each other, touch with a narrow neck that widens at once, and the three chips become one pill. Where the liquid goes the words turn white and bolder, letter by letter. Switching off a chip between two lit ones, its liquid splits in half and goes back into the neighbours: in the middle a neck stretches, thins out and breaks. Switching off one next to a lit chip, the liquid goes back into the neighbour; on its own, the liquid runs out over the end on the side of the finger and the word turns dark again. With the pointer over an empty chip, the liquid of the lit neighbours leans towards it; over a lit one, or over Clear, the joints between the chips narrow a little, as if about to let go; holding a lit chip down squeezes the liquid. The number rolls to the new digits, the names change with a fade; if no trail has all the filters, the line says so and says which filter to drop to get more. Clear empties everything: every pool splits and the liquid runs out towards Clear.

How it works

Real buttons, drawn liquid

The chips are real buttons with aria-pressed, in a role="group" with its name; Tab, Enter and Space work as always. Over them there is a single layer in the liquid’s colour, cut at every frame with clip-path: path() to the liquid’s shape; inside the same layer are the words in white, each in its chip’s place, so a word turns white exactly as far as the liquid has reached.

Two spans on springs per chip

A chip’s liquid is two spans, each with its two ends on springs (FLOW), worked out on GSAP’s ticker in steps of 1/240 of a second. Lit, the spans cover the chip and, if the neighbour on the same line is lit, reach into the gap between them by half the gap plus one end: the ends of neighbours overlap and together make one smooth pill. They start from the middle as a flat drop (its height on a softer spring, SPLASH), from the neighbour’s end, or one from each side.

Pieces and necks

On every line the spans are put in order: the ones that overlap enough become one piece, and between two pieces close to each other a neck is drawn, two Bézier curves per side that leave each end along its curve and come down in the middle to a height of h·(1 − t²)^1.15, t being the distance between the ends’ centres over the two ends plus STRETCH. As soon as the ends touch the neck is already thick, as the bridge between two drops is; the further apart, the thinner, and past STRETCH it breaks. An end on the run stretches into a tongue with its speed, one drawing back gets blunt.

Where the liquid goes

With lit neighbours the spans go back into them, half each way if both are lit, and the neck left in the middle breaks. On its own the liquid runs out over the end on the side of the finger (towards Clear with Clear, to the left from the keys): the far end aims past the near one, so the last of it goes at speed instead of lingering like a comma.

The rest answers

With the pointer on an empty chip the lit neighbours lean towards it by REACH pixels; on a lit one, or on Clear, the joints loosen by 9 pixels and the necks show; held down, a lit one squeezes. The number sits on reels of digits that turn with back.out, every window as wide as its digit and faded at the top and bottom; the names change with a fade and a touch of blur, and an aria-live region says the count.

Keys and the preview

A single ring for the keyboard, over the liquid, slides from chip to chip. A click from a script (detail 0, the library’s preview) is a pretend hand: it lights Loop between the two lit ones, then Shady and Lake view on the line below, switches Loop off, goes over Clear and empties everything, then lights Easy and Dogs welcome again.

Values to change

NameFileDefaultWhat it changes
FILTERSscript.js['Easy', 'Loop', 'Dogs welcome', …]The filters, in order (the example’s trails know the first seven).
STARTscript.js['Easy', 'Dogs welcome']The filters lit when the page opens.
FLOWscript.js[90, 0.78]The spring the liquid runs on: how stiff it is and how much it is held back.
SPLASHscript.js0.38How much a landing drop’s height is held back (less, and it wobbles more).
STRETCHscript.js26How many pixels a neck of liquid stretches before it breaks.
REACHscript.js7How far the liquid leans towards an empty chip under the pointer.
NOUNscript.js['trail', 'trails']What is being counted, singular and plural.

Try them in the Playground

When to use it

For the filters of a list that combine: a park’s trails, the homes of a rental site, a school’s courses, recipes, the films of a catalogue. Wherever whoever chooses needs to see at once how many results are left.

On phones

At 390 pixels the chips go on three lines and the liquid only joins neighbours on the same line. A tap lights and unlights, holding a lit chip squeezes its liquid, and the liquid of a chip switched off on its own runs out on the side of the finger. The hover hints are not there: everything shows on the tap.

With reduced motion

The liquid is in its place at once: lit chips are already full and neighbours already joined, with no drops, no pouring and no necks, and the pointer moves nothing. The number changes with a fade instead of rolling, the names with a fade, and the keyboard’s ring goes from chip to chip without sliding.

Pitfalls

  • Two pills that overlap a little make a notch where the circles of their ends cross; the neck, worked out thin from the first touch, stayed hidden inside the circles and the notch showed. Now as soon as the ends touch the neck is almost as thick as the liquid (1 − t²) and only thins out as they part.
  • Switching a chip off by shrinking the liquid towards the middle cut the words at the top, at the bottom and at the sides, and ended in a dark dot: now the liquid runs out over one end at full height, the way it comes in, and the far end aims past the near one so the last of it vanishes at speed.
  • With Parkinsans’ tabular figures the 1 sat in a wide space and 12 read as “1 2”: every window of the counter takes the width of the digit it shows, measured once the font has loaded.
  • While the reels turned, pieces of the next digits showed above and below the number: the window has a mask that fades at the top and bottom.
  • With reduced motion the loop that redraws the liquid does not run, and the hover hints left the shape loosened even after the pointer had gone: with reduced motion the hints are off and every change redraws at once.

Libraries

GSAP 3.15.0, Parkinsans (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 11 KB; the libraries: GSAP 28 KB.

Testing

Tested on 6 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: To do

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All components