Skip to content
animorio
IT
Back to the library

The flock-of-birds logo

Intro, Physics, SVG, TextGSAPAdvancedCompressed weight: Demo 17 KBGSAP 28 KBFreeDownload the zip

A logo entrance in a sunset sky: a flock of swallows arrives from far away, swirling in waves, then the birds land one after the other on the points of the letters until the logo is made of birds; the letters fill up from the bottom and three latecomers perch on top and sing. In the Playground you type your own name or upload your own logo.

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 flock-of-birds logo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/outfit@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="scena">
    <!-- the soft clouds, drawn on a canvas behind everything -->
    <canvas class="nuvole" data-clouds aria-hidden="true"></canvas>

    <!-- the logo: the script writes it here; it fills up from the bottom through a mask -->
    <svg class="palco" data-stage role="img" aria-label="Wrenly" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="fill-edge" gradientUnits="userSpaceOnUse" x1="0" x2="0" y1="0" y2="1" data-fill-edge>
          <stop offset="0" stop-color="#000" />
          <stop offset="1" stop-color="#fff" />
        </linearGradient>
        <mask id="fill" maskUnits="userSpaceOnUse" data-fill-mask>
          <rect fill="url(#fill-edge)" data-fill-rect />
        </mask>
      </defs>
      <g data-world>
        <g data-logo mask="url(#fill)"></g>
      </g>
    </svg>

    <!-- the flock: hundreds of small birds, drawn on a canvas -->
    <canvas class="stormo" data-flock aria-hidden="true"></canvas>

    <!-- the latecomers, the notes and the feathers, over everything -->
    <svg class="palco palco--sopra" data-front aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <!-- the belly stays inside the body (in each bird's own coordinates) -->
        <clipPath id="bird-body-clip">
          <path d="M-20 -30C-18 -44 -4 -50 12 -48C26 -46 32 -34 30 -22C28 -10 16 -4 2 -4C-12 -4 -22 -16 -20 -30Z" />
        </clipPath>

        <!-- a swallow, drawn facing right; the point between its feet is 0 0. The script clones it for every
             latecomer and turns each piece on its own joint -->
        <g id="bird-model" data-bird-model>
          <g data-b-place>
            <g data-b-flip>
              <!-- the legs, under the body; they tuck in when it flies -->
              <g data-b-legs>
                <path class="zampa" d="M-1 -7L-3 0M9 -7L9 0" />
                <path class="zampa zampa--dita" d="M-8 0L1 0M4 0L13 0" />
              </g>
              <g data-b-trunk>
                <!-- the far wing, darker, only seen when the wings go up -->
                <g data-b-wing-far>
                  <path class="uccello-lontano" d="M9 -43C-3 -45 -17 -37 -33 -19C-19 -21 -5 -23 5 -27C13 -30 15 -39 9 -43Z" />
                </g>
                <!-- the forked tail -->
                <g data-b-tail>
                  <path class="uccello-ala" d="M-14 -24C-26 -20 -40 -8 -56 6C-45 1 -38 -1 -31 -4C-37 4 -42 13 -47 24C-34 11 -22 0 -9 -11Z" />
                  <path class="uccello-piuma" d="M-20 -17L-44 2M-18 -12L-38 14" />
                </g>
                <!-- the body: blue back, cream belly, a shine on the back -->
                <path class="uccello" d="M-20 -30C-18 -44 -4 -50 12 -48C26 -46 32 -34 30 -22C28 -10 16 -4 2 -4C-12 -4 -22 -16 -20 -30Z" />
                <g clip-path="url(#bird-body-clip)">
                  <path class="uccello-pancia" d="M-26 -10C-8 -18 12 -26 36 -34L36 0L-26 0Z" />
                  <path class="uccello-macchia" d="M4 -16C7 -18 10 -17 10 -15C9 -13 6 -13 4 -16ZM14 -20C16 -21 18 -20 18 -19C17 -17 15 -17 14 -20ZM-4 -11C-2 -12 0 -12 0 -10C-1 -9 -3 -9 -4 -11Z" />
                  <path class="uccello-lucido" d="M-14 -36C-8 -43 2 -46 10 -45" />
                </g>
                <!-- the head turns on the neck: throat, forehead, beak in two halves, eye with iris, shine and lid -->
                <g data-b-head>
                  <circle class="uccello" cx="20" cy="-50" r="15" />
                  <path class="uccello-gola" d="M21 -42C27 -45 33 -45 34 -40C32 -34 24 -33 17 -37Z" />
                  <path class="uccello-gola" d="M30 -59C34 -59 36 -55 34.5 -51.5C31.5 -52.5 29 -55.5 30 -59Z" />
                  <path class="uccello-lucido" d="M10 -59C13 -62 17 -64 21 -64" />
                  <g data-b-beak-low>
                    <path class="becco becco--sotto" d="M33 -47.6L44.5 -47.6L33.5 -43.4Z" />
                  </g>
                  <g data-b-beak-up>
                    <path class="becco" d="M33 -54L47 -48.6L33 -47.4Z" />
                  </g>
                  <ellipse class="guancia" cx="17" cy="-44" rx="4.6" ry="2.6" data-b-blush />
                  <circle class="occhio" cx="25" cy="-53" r="5.6" />
                  <g data-b-pupil>
                    <circle class="iride" cx="26.4" cy="-53" r="3.8" />
                    <circle class="pupilla" cx="26.9" cy="-53" r="2.1" />
                    <circle class="riflesso" cx="25.3" cy="-54.8" r="1.2" />
                  </g>
                  <circle class="palpebra" cx="25" cy="-53" r="6.4" data-b-lid />
                </g>
                <!-- the near wing, folded along the body; it turns on the shoulder to fly -->
                <g data-b-wing>
                  <path class="uccello-ala" d="M5 -41C-7 -43 -21 -35 -37 -17C-23 -19 -9 -21 1 -25C9 -28 11 -37 5 -41Z" />
                  <path class="uccello-piuma" d="M-6 -33L-24 -22M-2 -28L-18 -21M-12 -27L-28 -19" />
                </g>
              </g>
            </g>
          </g>
        </g>
      </defs>
      <g data-heroes></g>
      <g data-fx></g>
    </svg>

    <p class="nota">Click or tap to see it again</p>
  </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.

27 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 flock-of-birds logo” from Animorio and fit it into my site

What it does

The sky is a sunset: violet up high, pink in the middle, orange and gold near the horizon, with soft clouds lit from below drifting slowly by. In a corner a little cloud of dots appears: it is a flock of swallows arriving from far away, growing as it comes closer. Over the stage the birds turn like a real murmuration, a flock that squeezes and stretches in waves, each one with wings beating in three frames and now and then a glide. Then, from left to right, each swallow leaves the whirl, comes down along a curve and lands on its point of the logo of a made-up brand, Wrenly: it brakes with its wings open, settles and folds them, one after the other, while a few feathers drift down, until the letters are made of birds. Then the birds melt into the logo: the letters fill with colour in a fade that rises from the bottom and, once full, stretch upwards and spring back. Three hand-drawn latecomer swallows, with red throats, cream bellies and eyes with iris and shine, arrive from off screen, land on top of the letters (which dip a little under their weight) and sing: their beaks open and small drawn notes float away. Then the logo stays there with them: they breathe and blink, one turns round with a hop, another preens its chest and loses a feather, the third flies off into the sky, turns and comes back to its place. After a few seconds the latecomers leave, the colour of the letters withdraws from the top, the logo is made of birds again and the flock flies away in waves; then a new flock arrives, with a different whirl and a different order. A click starts it all again. A picture can take the place of the word: the birds take the shape of its solid pixels, and then the picture appears.

How it works

Four layers

The sky is a CSS gradient on the stage; on top of it there are a canvas for the clouds, the SVG of the logo, a canvas for the flock and a second SVG for the latecomers, the notes and the feathers. The clouds are drawn only once, blurred with the shadow trick (the shape sits outside the canvas and only its blurred shadow shows, which works where ctx.filter is missing too): first the lit rim underneath, then the shaded body a little higher. Every frame they move with the page clock.

The points of the logo

The letters are measured on a canvas in the same typeface (measureText, actualBoundingBoxAscent) and drawn on another canvas as big as the stage; getImageData tells which pixels are solid. From the solid area and the largest number of birds comes the distance between two places, then a honeycomb grid with a little disorder gives each swallow a place. The same reading finds the highest point of every column: the latecomers land where the top is flat for the width of their feet.

A flock computed, not simulated

Each bird has a position that is a function of time: the centre of the flock arrives along a curve and grows, each swallow turns on a tilted ring (faster in the middle, so the flock bends), the ring widens and narrows and a wave runs through it. The direction of flight is the difference between the position now and a moment later. No simulation: the scene can be run forwards and backwards like a timeline.

Birds on the canvas

Each pose (wings up, level, down, open, half folded, folded) is drawn once on a small canvas, at the resolution of the screen. Every frame each bird is a single drawImage with setTransform (place, facing, tilt and size in one matrix): that way hundreds of swallows stay at 60 frames a second. Their number depends on the screen area; for the landing a Bézier curve starts with the speed the bird had in the flock and ends on its point.

The letters filling up

The SVG logo has a mask with a vertical gradient, black above and white below, that rises with the timeline. The same number, the fill line, sets how visible the perched birds are: below the line they vanish, above it they stay, and in the soft band they cross-fade with the colour of the letter. On the way out the line goes down and the birds show again from the top, just before they take off.

The latecomers and your logo

The swallow is drawn once in the page, in pieces and with an outline, and the script clones it for each one. Each piece turns on its own joint worked out with getBBox (the shoulder, the neck, the hinge of the beak, the base of the tail); place, tilt and facing go into one object written as a transform attribute, and the flights follow Bézier curves. If IMAGE holds an address, the logo becomes that picture and the birds take the shape of its solid pixels; a picture from another site that cannot be read becomes a rectangle of birds.

Values to change

NameFileDefaultWhat it changes
NAMEscript.js'Wrenly'The logo as a word: the birds land on the points of its letters.
IMAGEscript.js''The logo as a picture: the address of a file, or upload it from your computer. If there is one, it takes the place of the word and the birds take the shape of its solid pixels.
BIRDSscript.js420How many birds in the flock, at most: fewer on a small screen, and never more than the logo can hold.
SWIRLscript.js1How much the flock swirls: 0 flies straight with a sway, 2 is a fast whirl.
PERCHEDscript.js3How many latecomer swallows stay perched on top of the logo (0 to 6).
SPEEDscript.js1The speed of the whole animation: 2 is twice as fast, 0.5 half as fast.
RESTscript.js5How many seconds the logo stays whole with the swallows on it before the flock takes it away.
LOOPscript.jstrueWhether the flock takes the logo away and starts again. With false the logo stays and the swallows keep blinking and looking round.

Try them in the Playground

When to use it

For the opening of a site or a video about nature, travel, spring, music or a name that takes flight; for a logo preview for a client, a welcome page, a social post. It works with a written wordmark and with a picture.

On phones

The same animation, with the sizes adapted: the logo takes more width, the birds are smaller and fewer (their number depends on the screen area), so they stay smooth. A tap restarts it.

With reduced motion

Nothing flies: the letters made of birds fade in, then fade into the solid letters, then the perched swallows fade in; the clouds stand still. If it starts again, the exit is a fade too.

Pitfalls

  • An SVG mask with maskUnits userSpaceOnUse and no x, y, width and height uses the default box, and the rectangle inside with no size draws nothing: the letters did not show at all. Mask and rectangle need the size of the stage (or more).
  • Hundreds of birds in SVG do not stay at 60 frames a second: the flock is a canvas, each pose is drawn once and each bird is a single drawImage with a matrix. Their number is also limited by the screen area, and the poses are drawn just above screen resolution, because drawing them bigger cost frames.
  • With the same minimum size on a long name, on a phone the birds were bigger than the strokes of the letters and the name could not be read: the minimum distance between two places went down.
  • On a picture (taller than a word) the latecomers were huge and overlapped: their size takes the picture and the logo width into account, and two places are at least one whole swallow apart.
  • A simulated flock cannot be run forwards or backwards: the position of every bird is a function of the timeline’s time, so a pause, a jump or a click always shows the right scene.
  • A picture from another site cannot be read on a canvas (getImageData throws): then the birds fill its rectangle.
  • The feather falling at the landing started from the chest and showed over the wing: now it starts behind, near the tail.

Libraries

GSAP 3.15.0, Outfit (font variabile) 5.3.0.

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

Testing

Tested on 10 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 animations