Skip to content
animorio
IT
All components

The windscreen wiper cleanup

Loading, Physics, TransitionsCanvas, GSAPAdvancedCompressed weight: Demo 15 KBGSAP 28 KBFreeDownload the zip

Clearing a cache made as a windscreen in the rain at night: every drop is a small lens that shows the city lights behind the glass upside down and sharp, while the wet glass around it shows them blurred. The big drops slide down in fits and starts, leave a trail of droplets and swallow the ones they meet. Pressed, the two wipers start: every pass clears its arc and pushes the water away, the rubber blade flips over at every reversal, and less and less rain comes back: the clear glass is the progress. At the end the glass dries and a glint runs across it: 2.4 GB cleared.

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, viewport-fit=cover">
  <title>The windscreen wiper cleanup</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/archivo@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the windscreen wiper cleanup: clearing a cache shown as a rainy windscreen at night. Raindrops cover the glass
         and each one shows the city lights behind it upside down; the big ones slide, leave a trail and swallow the
         small ones. Pressed, the two wipers start: every pass pushes the water away, and less and less rain comes
         back, so the clear glass is the progress. At the end the glass is dry and a glint runs across it. The glass,
         the lights, the drops and the wipers are painted by script.js on the canvas -->
    <section class="wipe" aria-label="Clear cache" data-wipe>
      <div class="wipe__glass" role="progressbar" aria-label="Cache clearing progress" aria-valuemin="0" aria-valuemax="100"
           aria-valuenow="0" aria-valuetext="Ready to clear 2.4 GB" data-scene>
        <canvas class="wipe__paint" aria-hidden="true" data-paint></canvas>
      </div>
      <div class="wipe__info" aria-hidden="true">
        <p class="wipe__title">
          <svg class="wipe__tick" viewBox="0 0 24 24" data-tick><path d="M5.5 12.6l4.2 4.2 8.8-9.4" pathLength="1"/></svg>
          <span class="wipe__swap" data-title>System cache · 2.4 GB</span>
        </p>
        <p class="wipe__pct" data-pct>0%</p>
        <p class="wipe__meta"><span class="wipe__swap" data-meta>Browsers, thumbnails and logs</span></p>
      </div>
      <div class="wipe__buttons">
        <button class="pill" type="button" data-go data-autoclic><span class="pill__label" data-label>Clear cache</span></button>
      </div>
      <p class="sr" role="status" aria-live="polite" data-live></p>
    </section>
  </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.

47 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 windscreen wiper cleanup” from Animorio and fit it into my site

What it does

On a black background, alone in the middle, a windscreen at night with a gently curved top edge: behind the glass a city street, with street lamps going away toward the middle, the red lights of the cars ahead, the headlights of one coming, a green traffic light and a few signs, all out of focus as discs of light mirrored on the wet road. The glass is covered in rain: a mist of tiny droplets makes everything blurrier and milky, and over it lie the real drops, each with the city inside it upside down and sharp, a dark rim, a crescent of light at the bottom and a highlight at the top. Now and then a drop grows too heavy and slides down in fits and starts, stretching a little, leaving a trail of droplets and a clearer strip in the mist behind it, and swallowing the drops it meets as it grows. At the bottom, parked, two black wipers with their arm, rubber blade and hub; under the glass the words System cache · 2.4 GB and Browsers, thumbnails and logs, and the Clear cache pill. Pointing at the pill makes the wipers give a flick, like a tap on the stalk, and drop back with a bounce. Pressed, the rain grows heavier for a moment and the two wipers start together, side by side like on a car: every pass is a 160 degree arc that slows down, hesitates for an instant at the reversal and comes back. Where the blade passes the glass turns clear and the lights sharp, the droplets vanish and the drops are pushed ahead of the rubber like a row of beads, which stays on the glass at the end of the stroke and slides away. The rubber leans against the way it moves and flips over at every reversal. The rain goes on, and the glass just cleared gets wet and misty again, but less and less: halfway less than half of it comes, near the end almost none. The line says Clearing cache, under it what is being cleared and how much (Thumbnails · 1.3 of 2.4 GB), on the right the big percentage. At the end the wipers finish their stroke and park, the last mist and the last drops in the corners dry up, a glint of light runs across the glass on a slant and the line becomes 2.4 GB cleared in green, with a tick that draws itself, and Cache is empty · just now. Clear again brings a shower that wets the glass again and then starts over. While it clears the pill, pale with just a ring, says Stop: the wipers finish their stroke and stop, the line says Clearing stopped with how much was cleared, and the rain comes back as before.

How it works

Two cities and a mask

The street behind the glass is drawn once, twice: sharp, with the lights as out of focus discs with a brighter rim, and blurred, with the same lights twice as wide and paler and a milky veil over them. Both are 40 units wider than the glass on every side, for the drops near the edge. A third canvas, at half resolution, is the mask of how clear the glass is: every frame paints the blurred city and over it the sharp one cut out by the mask (copy and then source-in on a canvas in between). The wipers and the sliding drops paint the mask, the rain mists it by taking a little off everywhere every frame (destination-out with an alpha of 1 − e^(−6·rain·dt)).

Every drop is a lens

A drop is drawn as an elliptical clip holding the sharp city around it, taken from a square 3.2 times its radius wide, flipped both ways (scale(−1, −1)) and made smaller: what a drop on a glass really does. Over it a single picture is stretched, made once: the dark rim where the drop reflects the dark, a light crescent at the bottom (a radial gradient with its centre moved up, which crosses the circle only at the bottom) and the highlight at the top left. The droplets too small to show the city are a speck of light with a faintly dark rim, stamped once and for good into a fourth canvas, which evaporates slowly so it never fills up.

Drops slide and join

Every drop has a threshold of its own, around 3.4 units: above it gravity pulls with a force in proportion to how far it is above, a friction holds it back, and now and then the glass snags it and lets it go again. As it slides it stretches with its speed, takes the droplets out of the mist (and grows a little), clears a strip in the mask and now and then leaves a droplet behind, losing its water. Two drops that touch become one, with the area of both and the centre moved toward the bigger one: the drops are sorted by x and only near ones are compared.

The wipers

The two arms are parallel and follow the same angle: half a cosine for the stroke, a pause at the reversal, half a cosine to come back. Every frame the slice of ring between the angle before and the angle now clears the mask and wipes out the mist. The drops inside the slice hook onto the blade: they keep their distance from the hub and sit just ahead of the rubber, where they join into a row of beads (never bigger than 4 units: the rest runs off the edge) that loses water every frame; when the arm turns back it leaves them, and they slide away. The rubber is a spring on the angle: it leans against the speed and at the reversal flips over with a small bounce.

The progress is the rain easing off

The demo's rain is (1 − progress)^1.25: it decides how many drops arrive every second (up to 180, plus six droplets per drop, with a ceiling of 300 drops) and how fast the glass mists over, so every pass finds less water than the one before. At the end the wipers finish their stroke and stop; the glass dries in 0.9 seconds (the drops left in the corners slide fast and fade, the sharp city covers everything) and a glint, a slanted linear gradient in lighter mode, runs across it. Stop lets the stroke finish and brings the rain back; Clear again brings a shower seven times as thick before starting over.

Those who cannot see, the demo and the drawing

The glass is a role=progressbar with aria-valuenow and aria-valuetext updated at most every half second, aria-busy while it works and an aria-live line for the start, a stop and the end; the button stays the same element in every state. Clicks from a script (the library preview's) never stop and start again only after 2.6 seconds of result. The drawing loop runs only while it rains or something moves, and stops when the glass is off screen.

Values to change

NameFileDefaultWhat it changes
SECONDSscript.js9How long the demo's cleanup takes, in seconds (a real one follows the files as they are deleted).
ITEMSscript.js[['Browser caches', 0.92], ['Thumbnails', 0.41], …]What gets cleared, each with its name and its gigabytes; the total is also in the words at rest in index.html.
STROKEscript.js0.62The seconds of one pass of the wipers, from one side to the other.
PAUSEscript.js0.09The small hesitation at the reversal, in seconds.
SWEEPscript.js160The arc of a pass, in degrees: under 150 leaves the top right corner wet.
RAINscript.js180The drops that land on the glass every second in full rain (plus six times as many droplets); at rest a little over a tenth of them.
LENSscript.js3.2How much of the world behind fits in a drop: higher, the flipped picture is smaller and holds more lights.
SLIDEscript.js3.4The radius past which a drop starts to slide, in drawing units (the glass is 380 wide).
GRAVITYscript.js150How hard the big drops are pulled down, in units per second squared.
WORDSscript.js{ busy: 'Clearing cache', done: 'cleared', stopped: 'Clearing stopped' }The words under the glass while it clears, at the end (after the gigabytes) and after Stop; the one at rest is changed in index.html.
LABELSscript.js{ busy: 'Stop', done: 'Clear again' }The button's words while it clears and at the end; the one at rest, Clear cache, is changed in index.html.

Try them in the Playground

When to use it

For a wait of a few seconds that takes something away: emptying a cache or the bin, freeing space, deleting temporary files, clearing a history, the maintenance screen of a car or driving app. The easing rain says how far along things are without reading anything, and the clear glass at the end is the reward. For a wait under two seconds it is too much (not even one pass shows), and it does not belong on a light page: it is made for a dark interface.

On phones

The component is 380 pixels wide and on a phone takes the width of the screen less 16 pixels a side (358 at 390): the drawing scales with the width and the canvas paints at the screen's real density, up to twice, so the drops stay sharp. There are at most 300 big drops, the heaviest work (the two cities) is done once and the drawing stops when the glass leaves the screen. The pill is 44 tall: under a finger it squashes and springs back; the wipers' flick is there with the mouse and the keyboard.

With reduced motion

No falling rain, sliding drops, moving wipers or glint at the end: the glass stays wet and still, and with the progress the drops and the mist fade away as the sharp city appears, along with the percentage. At the end the glass is clear; the words change with a fade and the tick appears without drawing itself.

Pitfalls

  • With the rain and the misting tuned to the rest state, the glass stayed clear after the very first pass and the progress could not be read: 0.7 seconds pass between two passes, so the full rain now brings 180 drops a second and the glass mists six times as fast, and both ease off with the progress.
  • The droplets stamped as lenses, at two or three pixels, turned into black specks that looked like dirt: under 2.6 pixels they are now a speck of light with a faintly dark rim, and the rim of the big drops is lighter too.
  • The drops pushed by the blade joined each other into huge balls riding the rubber: a hooked drop now never passes 4 units (the rest runs off the edge) and loses water every frame, so it stays a row of beads.
  • The mist, stamped all the time by the rain at rest, filled up into an even veil: it now evaporates slowly (a tenth a second) and settles close to how it starts.
  • With a 150 degree arc and the blade starting 30 units from the hub, the bottom right corner and two domes round the hubs stayed wet: the arc is now 160 degrees and the blade starts at 16 units.
  • The hover kept the wipers raised as long as the mouse stayed on the pill: it is now a single flick that drops back with a bounce, like a tap on the stalk.

Libraries

GSAP 3.15.0, Archivo (font variabile) 5.3.0.

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

Testing

Tested on 8 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