Skip to content
animorio
IT
All components

The gallery that opens

Galleries, Transitions, Images, PhysicsGSAPAdvancedCompressed weight: Demo 13 KBGSAP 28 KBFreeDownload the zip

Six pictures in a grid: opening one, the picture flies out of its square and grows in the middle of the screen as its crop comes off, while the page behind darkens to the picture’s colour; it slides from picture to picture on a spring and, dragged down, flies back into its square.

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 gallery that opens</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/jost@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the gallery: six pictures in a grid. Each one opens into the viewer flying out of its square, slides to the
         next on a spring and closes by being dragged down. The pictures are drawn by the script into the sprite -->
    <section class="gallery" aria-label="Summer pictures" data-gallery data-autoclic>
      <svg class="gallery__sprite" aria-hidden="true" focusable="false" data-sprite></svg>
      <ul class="gallery__grid" data-grid></ul>
      <p class="gallery__hint">Open a picture, swipe to the next, drag it down to close.</p>

      <div class="viewer" role="dialog" aria-modal="true" aria-label="Pictures" tabindex="-1" hidden data-viewer>
        <div class="viewer__shade" data-shade></div>
        <div class="viewer__track" data-track></div>
        <div class="viewer__caption" aria-live="polite" data-caption>
          <h2 class="viewer__title" data-cap-title></h2>
          <p class="viewer__line" data-cap-line></p>
        </div>
        <div class="viewer__strip" data-strip><span class="viewer__ring" aria-hidden="true" data-ring></span></div>
        <button class="viewer__btn viewer__close" type="button" aria-label="Close" data-close>
          <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6.5 6.5l11 11M17.5 6.5l-11 11"/></svg>
        </button>
        <button class="viewer__btn viewer__nav viewer__nav--prev" type="button" aria-label="Previous picture" data-prev>
          <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M14.5 6 8.5 12l6 6"/></svg>
        </button>
        <button class="viewer__btn viewer__nav viewer__nav--next" type="button" aria-label="Next picture" data-next>
          <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9.5 6l6 6-6 6"/></svg>
        </button>
      </div>
    </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.

9 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 gallery that opens” from Animorio and fit it into my site

What it does

On a black background a grid of six squares with rounded corners, six pictures drawn in plain colours: cliffs at dusk with a lighthouse, dunes, a lake with snowy peaks reflected in it, an arcade with three arches, fields seen from above with a river, waves with a small sail. Below, Open a picture, swipe to the next, drag it down to close. Under the pointer a square zooms its picture a little and the name rises from the bottom. Opening it, the picture flies from its square to the middle of the screen, growing and losing its crop until it has its whole shape, wide or tall, with a slight overshoot; behind it the page darkens to a shade of the picture and the grid steps back and dims; the name and a line appear under the picture, a strip with the six small pictures and a ring round the open one, a round button to close at the top right and, on a computer, the arrows at the sides. With a finger, the arrows or the keys it slides to the next picture on a spring: the pictures shrink a little as they move away from the middle, the background changes shade between one picture and the next, the name slides away and the new one comes, the ring runs along the strip. Dragged down, the picture follows the hand and shrinks while the background lightens and the grid comes forward; let go past a certain point it flies back into its square, otherwise it goes back to the middle.

How it works

Six drawings, used three times

The pictures are drawn by the script, once each, as SVG symbols (symbol) made of gradients and shapes: the hills are smooth curves through points, the fields a grid of points moved by random numbers that are always the same. Each picture is used with use in the squares of the grid (preserveAspectRatio slice, cut to a square), open and in the strip.

The flight

When it opens, the picture is already in its place, big and whole, and the script takes it back into the square: it moves it to the middle of the square, scales it to its size and cuts it with a clip-path inset to the central square, with rounded corners that stay the same on screen. Then GSAP brings move, scale and cut back to zero in OPEN seconds: the move with back.out (a little beyond and back), the cut with power3.out. Closing, the same backwards, towards the square in the grid.

The spring between pictures

The open pictures stand in a row, a screen apart; the position is a number (which picture, with decimals) that a spring (SWIPE) brings to the picture chosen, worked out on GSAP’s ticker in steps of 4 milliseconds. Dragged, the row follows the finger (with resistance beyond the first and the last); let go, it moves on to the next picture if it went past a fifth of the width (22 per cent) or was thrown. Each picture shrinks by DEPTH as it moves away from the middle, and the background takes the shade between those of the two pictures.

Down to close

A vertical drag takes the picture away: it follows the hand (sideways by 0.7) and shrinks down to 0.65, the background and the controls fade and the grid comes forward. Past DISMISS pixels, or with a quick throw, it flies into its square; otherwise it goes back to the middle with back.out.

Keys and the preview

The viewer is a dialog (role dialog, aria-modal): the arrows and Home and End change picture, Esc closes and Tab stays inside; on a trackpad a sideways swipe moves on by one picture. Closed, the focus goes back to the square. A click from a script (the library’s preview) opens a picture, goes on twice and closes it.

Values to change

NameFileDefaultWhat it changes
OPENscript.js0.62The seconds a picture takes to fly open (it flies back a little faster).
SWIPEscript.js[260, 0.86]The spring between pictures: how stiff it is and how much it is held back.
DEPTHscript.js0.1How much a picture shrinks as it slides away from the middle.
DISMISSscript.js110How far down, in pixels, a picture is dragged to close it.

Try them in the Playground

When to use it

For a portfolio, the rooms of a guesthouse, the dishes on a menu, a product catalogue, a photo story: anywhere a grid of pictures has to open without losing the thread.

On phones

Two columns of squares; open, the picture takes the width of the screen, a finger leafs through and drags it down to close. There are no arrows at the sides: the strip of small pictures and the close button stay.

With reduced motion

The picture opens and closes without the flight, already in its place; it goes from picture to picture without the spring and the pictures at the sides do not shrink. Dragged down, the picture still follows the hand.

Pitfalls

  • A picture going from a square to a rectangle is not done with scale, which would stretch it: the picture already has its own shape, a clip-path inset cuts it to a square and scale shrinks it, so the crop opens during the flight.
  • The rounded corners of the crop scale with the picture: to look the same on screen, the radius is divided by the scale of the moment.
  • Closing, the grid is on its way back to its own size: the square is measured with the grid’s transform taken off for an instant, or the picture would land a little beside it.
  • A square under the pointer has its picture zoomed: the crop the flight starts from and lands on takes the scale read from the computed CSS into account, or the flight would start with a jump.
  • The first time Safari draws a picture big it takes a long frame, and the flight would start halfway: the picture stays on its square for two frames, looking just like it, and then flies.

Libraries

GSAP 3.15.0, Jost (font variabile) 5.3.0.

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

Testing

Tested on 3 October 2026

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

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