Skip to content
animorio
IT
Back to the library

The mischievous cat logo

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

A logo preview with a ginger cat playing on it: the letters drop and bounce like rubber balls, the cat crouches with its bottom wiggling, pounces on top of the logo and walks along it, the letters sinking under its paws; it bats one off, rubs on another, scratches a third, then looks at you and slowly pushes the last one down. It falls asleep up there, stretches, and the letters spring back into place. 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 mischievous cat logo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/bricolage-grotesque@5.3.0/standard.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="scena">
    <!-- the stage: the script measures it, writes the logo in it and moves the cat -->
    <svg class="palco" data-stage role="img" aria-label="PURRLO" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <!-- the scratches: everything white stays, the three black strokes are cut out of the letter -->
        <mask id="scratch" maskUnits="userSpaceOnUse" data-scratch-mask>
          <rect fill="#fff" data-scratch-full />
          <g fill="none" stroke="#000" stroke-linecap="round" data-scratch-lines></g>
        </mask>
        <!-- the cat's body, to keep the belly, the bib and the stripes inside it -->
        <clipPath id="cat-body-clip">
          <path d="M70 -120C82 -100 80 -76 58 -66C26 -54 -40 -56 -78 -66C-104 -74 -112 -100 -104 -122C-96 -146 -60 -150 -24 -144C10 -140 46 -146 70 -120Z" />
        </clipPath>
        <clipPath id="cat-sleep-clip">
          <path d="M-108 -2C-116 -56 -64 -100 -4 -100C56 -100 106 -70 108 -16C108 -6 102 -2 94 -2Z" />
        </clipPath>
        <clipPath id="cat-haunch-clip">
          <ellipse cx="-68" cy="-98" rx="29" ry="33" />
        </clipPath>
        <!-- a soft shade at the bottom of the body, over the fur and under the belly -->
        <linearGradient id="cat-shade" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" class="ombra-via" />
          <stop offset="1" class="ombra-piena" />
        </linearGradient>
        <!-- the irises are lighter around the pupil and darker at the rim -->
        <radialGradient id="cat-iris" cx="0.5" cy="0.5" r="0.5">
          <stop offset="0.25" class="iride-chiara" />
          <stop offset="0.7" class="iride-media" />
          <stop offset="1" class="iride-scura" />
        </radialGradient>
        <!-- the irises stay inside the whites of the eyes when they look around -->
        <clipPath id="cat-eyes-clip">
          <ellipse cx="78" cy="-166" rx="11.5" ry="12.5" />
          <ellipse cx="114" cy="-166" rx="11.5" ry="12.5" />
        </clipPath>
      </defs>

      <g data-world>
        <g data-ground></g>
        <g data-shadows></g>
        <g data-logo></g>
        <g data-crumbs></g>

        <!-- the cat: drawn facing right, the point between its paws is 0 0 -->
        <g data-cat-place>
          <g data-cat-flip>
            <g data-cat>
              <g data-torso>
                <!-- the tail: one path through a chain of joints, drawn three times (outline, fur, stripes), with a
                     dark fluffy tip that follows its last joint -->
                <g data-tail>
                  <path class="coda-bordo" data-tail-line />
                  <path class="ciuffo-bordo" d="M-12 -8Q-2 -12 8 -9L14 -10L13 -5L21 -3L15 0L21 4L13 6L14 10L7 9Q-2 12 -12 8Z" data-tail-tuft-line />
                  <path class="coda" data-tail-fur />
                  <path class="coda-righe" data-tail-stripes />
                  <path class="ciuffo" d="M-12 -8Q-2 -12 8 -9L14 -10L13 -5L21 -3L15 0L21 4L13 6L14 10L7 9Q-2 12 -12 8Z" data-tail-tuft />
                </g>
                <!-- the far legs, darker, behind the body -->
                <g data-leg-hb>
                  <path class="gamba-bordo" d="M-62 -84Q-76 -44 -50 -12" />
                  <path class="gamba gamba--lontana" d="M-62 -84Q-76 -44 -50 -12" />
                  <path class="righe-gamba" d="M-73.3 -44.3L-70.7 -43.9L-68.2 -43.9L-65.8 -44.3L-63.4 -45.0L-61.2 -46.0L-59.2 -47.4L-60.4 -49.3L-62.4 -48.4L-64.3 -47.9L-66.3 -47.7L-68.2 -47.7L-70.1 -48.1L-72.0 -48.7ZM-69.4 -30.2L-66.8 -30.3L-64.3 -30.8L-62.0 -31.6L-59.8 -32.8L-57.9 -34.3L-56.1 -36.0L-57.7 -37.7L-59.5 -36.4L-61.3 -35.5L-63.1 -34.9L-65.0 -34.6L-67.0 -34.5L-69.0 -34.8ZM-63.5 -18.3L-61.0 -18.9L-58.6 -19.8L-56.5 -21.0L-54.6 -22.5L-52.9 -24.3L-51.5 -26.3L-53.3 -27.6L-54.9 -26.1L-56.5 -24.9L-58.2 -24.0L-60.0 -23.3L-61.9 -23.0L-63.9 -22.9Z" />
                  <ellipse class="zampa zampa--lontana" cx="-44" cy="-7" rx="14" ry="8" />
                  <g class="cuscinetti" data-pads><ellipse cx="-44" cy="-5" rx="4.6" ry="2.8" /><circle cx="-51" cy="-9" r="2" /><circle cx="-46" cy="-11.5" r="2" /><circle cx="-40" cy="-11.5" r="2" /><circle cx="-35.5" cy="-9" r="2" /></g>
                  <path class="dita" d="M-44 -11L-44 -4M-37 -11L-37 -5" />
                </g>
                <g data-leg-fb>
                  <path class="gamba-bordo" d="M34 -96L38 -12" />
                  <path class="gamba gamba--lontana" d="M34 -96L38 -12" />
                  <path class="righe-gamba" d="M28.1 -63.3L30.6 -62.7L33.1 -62.4L35.6 -62.5L38.0 -63.0L40.3 -63.9L42.5 -65.0L41.4 -67.1L39.4 -66.4L37.4 -66.0L35.4 -66.0L33.5 -66.2L31.7 -66.8L29.8 -67.6ZM28.7 -49.9L31.3 -49.2L33.8 -49.0L36.2 -49.1L38.6 -49.6L40.9 -50.4L43.1 -51.6L42.0 -53.6L40.0 -53.0L38.0 -52.6L36.1 -52.5L34.2 -52.8L32.3 -53.3L30.5 -54.1ZM29.4 -36.4L31.9 -35.8L34.4 -35.5L36.9 -35.7L39.3 -36.1L41.5 -37.0L43.7 -38.2L42.7 -40.2L40.6 -39.5L38.6 -39.2L36.7 -39.1L34.8 -39.4L33.0 -39.9L31.1 -40.7Z" />
                  <ellipse class="zampa zampa--lontana" cx="42" cy="-7" rx="14" ry="8" />
                  <g class="cuscinetti" data-pads><ellipse cx="42" cy="-5" rx="4.6" ry="2.8" /><circle cx="35" cy="-9" r="2" /><circle cx="40" cy="-11.5" r="2" /><circle cx="46" cy="-11.5" r="2" /><circle cx="50.5" cy="-9" r="2" /></g>
                  <path class="dita" d="M42 -11L42 -4M49 -11L49 -5" />
                </g>
                <!-- the body breathes: the raised fur and the tufts behind it, the fur, then the shade, the belly, the
                     bib, the stripes and the light inside it, then its outline -->
                <g data-breath>
                  <!-- the fur along the back that stands up before the pounce: hidden behind the body until then -->
                  <path class="gatto" d="M-84 -124L-80 -150L-72 -140L-66 -158L-58 -146L-50 -162L-42 -149L-34 -163L-26 -147L-18 -161L-10 -145L-2 -158L6 -143L14 -156L22 -142L30 -154L36 -136L36 -124Z" data-hackles />
                  <!-- the tufts of the chest under the chin and of the belly between the legs -->
                  <path class="crema ciuffi" d="M64 -113Q82 -112 84 -105Q78 -107 64 -104ZM64 -102Q82 -101 88 -94Q78 -96 64 -93ZM64 -91Q82 -90 86 -83Q78 -85 64 -82ZM64 -81Q82 -80 80 -73Q78 -75 64 -72Z" />
                  <path class="crema ciuffi" d="M-28 -64Q-31 -55 -37 -52Q-35 -57 -39 -63ZM-16 -64Q-19 -55 -25 -52Q-23 -57 -27 -63ZM-4 -64Q-7 -55 -13 -52Q-11 -57 -15 -63ZM8 -64Q5 -55 -1 -52Q1 -57 -3 -63ZM20 -64Q17 -55 11 -52Q13 -57 9 -63ZM32 -64Q29 -55 23 -52Q25 -57 21 -63Z" />
                  <path class="gatto gatto--pieno" d="M70 -120C82 -100 80 -76 58 -66C26 -54 -40 -56 -78 -66C-104 -74 -112 -100 -104 -122C-96 -146 -60 -150 -24 -144C10 -140 46 -146 70 -120Z" />
                  <g clip-path="url(#cat-body-clip)">
                    <rect x="-120" y="-104" width="210" height="50" fill="url(#cat-shade)" />
                    <ellipse class="crema" cx="0" cy="-52" rx="78" ry="16" />
                    <ellipse class="crema" cx="76" cy="-98" rx="18" ry="30" />
                    <path class="righe-piene" d="M-88.4 -143.3L-87.4 -138.5L-86.7 -133.6L-86.3 -128.9L-86.2 -124.1L-86.4 -119.4L-86.9 -114.7L-87.7 -110.0L-88.9 -105.4L-90.4 -100.7L-92.3 -96.1L-91.7 -95.9L-89.1 -100.1L-86.8 -104.5L-84.8 -109.1L-83.0 -113.8L-81.6 -118.6L-80.6 -123.6L-79.8 -128.7L-79.4 -133.9L-79.3 -139.2L-79.6 -144.7ZM-64.9 -155.3L-63.9 -150.1L-63.1 -144.9L-62.6 -139.8L-62.5 -134.6L-62.6 -129.5L-63.1 -124.4L-63.9 -119.3L-65.0 -114.2L-66.5 -109.2L-68.3 -104.1L-67.7 -103.9L-65.1 -108.6L-62.7 -113.4L-60.6 -118.4L-58.8 -123.5L-57.4 -128.7L-56.3 -134.1L-55.5 -139.5L-55.0 -145.1L-54.8 -150.9L-55.1 -156.7ZM-41.0 -155.3L-39.9 -149.9L-39.1 -144.5L-38.5 -139.2L-38.3 -133.8L-38.4 -128.5L-38.7 -123.2L-39.4 -117.9L-40.4 -112.6L-41.7 -107.4L-43.3 -102.1L-42.7 -101.9L-40.2 -106.8L-38.0 -111.9L-36.1 -117.1L-34.5 -122.4L-33.1 -127.8L-32.1 -133.4L-31.4 -139.0L-30.9 -144.8L-30.8 -150.7L-31.0 -156.7ZM-16.9 -152.3L-15.8 -147.0L-15.0 -141.8L-14.4 -136.7L-14.2 -131.5L-14.1 -126.4L-14.4 -121.3L-14.9 -116.2L-15.8 -111.2L-16.9 -106.1L-18.3 -101.1L-17.7 -100.9L-15.4 -105.6L-13.4 -110.5L-11.6 -115.5L-10.1 -120.6L-8.9 -125.8L-7.9 -131.1L-7.3 -136.6L-6.9 -142.2L-6.8 -147.9L-7.1 -153.7ZM7.6 -150.3L8.6 -145.4L9.4 -140.6L10.0 -135.7L10.3 -131.0L10.4 -126.2L10.2 -121.6L9.7 -116.9L9.0 -112.3L8.0 -107.7L6.7 -103.1L7.3 -102.9L9.4 -107.2L11.2 -111.7L12.8 -116.2L14.1 -120.9L15.1 -125.8L15.9 -130.7L16.5 -135.8L16.7 -141.0L16.7 -146.3L16.4 -151.7ZM30.1 -152.3L31.1 -147.9L31.9 -143.6L32.4 -139.4L32.8 -135.2L32.9 -131.1L32.7 -127.0L32.3 -122.9L31.7 -118.9L30.8 -115.0L29.7 -111.1L30.3 -110.9L32.1 -114.6L33.7 -118.4L35.1 -122.3L36.2 -126.4L37.1 -130.6L37.8 -135.0L38.2 -139.5L38.4 -144.1L38.3 -148.8L37.9 -153.7ZM50.6 -148.2L51.6 -144.9L52.4 -141.7L53.0 -138.6L53.4 -135.6L53.6 -132.7L53.6 -129.8L53.5 -127.0L53.1 -124.3L52.5 -121.7L51.7 -119.1L52.3 -118.9L53.7 -121.3L54.9 -123.8L55.9 -126.5L56.8 -129.4L57.4 -132.4L57.8 -135.6L58.0 -138.9L58.0 -142.4L57.8 -146.0L57.4 -149.8ZM-52.3 -111.0L-51.6 -109.9L-51.1 -108.7L-50.7 -107.6L-50.3 -106.4L-50.1 -105.1L-50.1 -103.8L-50.2 -102.5L-50.4 -101.1L-50.7 -99.6L-51.3 -98.1L-50.7 -97.9L-49.8 -99.2L-49.0 -100.5L-48.3 -101.9L-47.8 -103.4L-47.4 -104.9L-47.1 -106.4L-47.0 -108.0L-47.1 -109.7L-47.3 -111.3L-47.7 -113.0ZM-28.3 -111.1L-27.7 -109.8L-27.1 -108.4L-26.7 -107.0L-26.3 -105.6L-26.1 -104.1L-26.1 -102.6L-26.2 -101.0L-26.4 -99.4L-26.8 -97.8L-27.3 -96.1L-26.7 -95.9L-25.8 -97.4L-25.0 -99.0L-24.3 -100.6L-23.8 -102.2L-23.4 -103.9L-23.1 -105.6L-23.0 -107.4L-23.1 -109.2L-23.3 -111.0L-23.7 -112.9ZM-4.3 -109.0L-3.6 -107.9L-3.1 -106.7L-2.7 -105.6L-2.3 -104.4L-2.1 -103.1L-2.1 -101.8L-2.2 -100.5L-2.4 -99.1L-2.7 -97.6L-3.3 -96.1L-2.7 -95.9L-1.8 -97.2L-1.0 -98.5L-0.3 -99.9L0.2 -101.4L0.6 -102.9L0.9 -104.4L1.0 -106.0L0.9 -107.7L0.7 -109.3L0.3 -111.0ZM17.8 -108.9L18.4 -108.0L18.9 -107.1L19.4 -106.1L19.7 -105.1L19.9 -104.1L19.9 -103.0L19.9 -101.9L19.6 -100.7L19.3 -99.5L18.8 -98.2L19.2 -97.8L20.2 -98.9L21.0 -100.1L21.7 -101.3L22.2 -102.6L22.6 -103.9L22.9 -105.3L23.0 -106.7L22.9 -108.1L22.7 -109.6L22.2 -111.1Z" />
                    <path class="lucido" d="M-90 -128Q-56 -146 16 -138" />
                    <path class="lucido lucido--fine" d="M24 -136Q44 -138 60 -128" />
                    <path class="pelo-segno" d="M60 -96L66 -92M62 -84L68 -82M-30 -68L-26 -72M-10 -66L-6 -70M10 -67L14 -71" />
                  </g>
                  <path class="gatto-linea" d="M70 -120C82 -100 80 -76 58 -66C26 -54 -40 -56 -78 -66C-104 -74 -112 -100 -104 -122C-96 -146 -60 -150 -24 -144C10 -140 46 -146 70 -120Z" />
                </g>
                <!-- the near hind leg: the lower leg, the round haunch over it, the paw -->
                <g data-leg-hf>
                  <path class="gamba-bordo" d="M-76 -84Q-90 -44 -64 -12" />
                  <path class="gamba" d="M-76 -84Q-90 -44 -64 -12" />
                  <path class="righe-gamba" d="M-87.3 -44.3L-84.7 -43.9L-82.2 -43.9L-79.8 -44.3L-77.4 -45.0L-75.2 -46.0L-73.2 -47.4L-74.4 -49.3L-76.4 -48.4L-78.3 -47.9L-80.3 -47.7L-82.2 -47.7L-84.1 -48.1L-86.0 -48.7ZM-83.4 -30.2L-80.8 -30.3L-78.3 -30.8L-76.0 -31.6L-73.8 -32.8L-71.9 -34.3L-70.1 -36.0L-71.7 -37.7L-73.5 -36.4L-75.3 -35.5L-77.1 -34.9L-79.0 -34.6L-81.0 -34.5L-83.0 -34.8ZM-77.5 -18.3L-75.0 -18.9L-72.6 -19.8L-70.5 -21.0L-68.6 -22.5L-66.9 -24.3L-65.5 -26.3L-67.3 -27.6L-68.9 -26.1L-70.5 -24.9L-72.2 -24.0L-74.0 -23.3L-75.9 -23.0L-77.9 -22.9Z" />
                  <ellipse class="gatto" cx="-68" cy="-98" rx="29" ry="33" />
                  <g clip-path="url(#cat-haunch-clip)">
                    <ellipse class="ombra-pelo" cx="-62" cy="-66" rx="30" ry="14" />
                    <path class="righe-piene" d="M-85.2 -133.6L-83.0 -131.0L-81.2 -128.3L-79.9 -125.7L-79.1 -122.9L-78.6 -120.1L-78.7 -117.2L-79.3 -114.1L-80.4 -110.9L-82.0 -107.6L-84.2 -104.2L-83.8 -103.8L-80.9 -106.8L-78.5 -109.9L-76.6 -113.1L-75.2 -116.4L-74.4 -119.9L-74.1 -123.5L-74.3 -127.1L-75.2 -130.9L-76.7 -134.6L-78.8 -138.4ZM-100.5 -115.5L-98.3 -113.6L-96.5 -111.6L-95.1 -109.5L-94.1 -107.3L-93.4 -104.9L-93.1 -102.3L-93.2 -99.5L-93.8 -96.6L-94.8 -93.4L-96.3 -90.2L-95.7 -89.8L-93.7 -92.9L-92.0 -95.9L-90.8 -99.0L-89.9 -102.0L-89.6 -105.1L-89.8 -108.3L-90.4 -111.4L-91.6 -114.5L-93.3 -117.5L-95.5 -120.5ZM-64.7 -133.8L-62.8 -131.8L-61.2 -129.9L-60.0 -127.9L-59.0 -125.9L-58.4 -123.8L-58.1 -121.7L-58.1 -119.5L-58.4 -117.1L-59.1 -114.7L-60.2 -112.2L-59.8 -111.8L-58.0 -114.1L-56.6 -116.5L-55.6 -118.9L-54.9 -121.5L-54.6 -124.2L-54.7 -126.9L-55.2 -129.7L-56.2 -132.5L-57.6 -135.4L-59.3 -138.2Z" />
                    <path class="lucido" d="M-90 -112Q-84 -126 -68 -129" />
                  </g>
                  <ellipse class="zampa" cx="-58" cy="-7" rx="15" ry="8.5" />
                  <g class="cuscinetti" data-pads><ellipse cx="-58" cy="-5" rx="5" ry="3" /><circle cx="-65.5" cy="-9" r="2.2" /><circle cx="-60.5" cy="-12" r="2.2" /><circle cx="-54.5" cy="-12" r="2.2" /><circle cx="-49.5" cy="-9" r="2.2" /></g>
                  <path class="dita" d="M-58 -11L-58 -4M-51 -11L-51 -5" />
                </g>
                <!-- the near front leg: the one that bats, scratches and pushes -->
                <g data-leg-ff>
                  <path class="gamba-bordo" d="M50 -96L54 -12" />
                  <path class="gamba" d="M50 -96L54 -12" />
                  <path class="righe-gamba" d="M44.1 -63.3L46.6 -62.7L49.1 -62.4L51.6 -62.5L54.0 -63.0L56.3 -63.9L58.5 -65.0L57.4 -67.1L55.4 -66.4L53.4 -66.0L51.4 -66.0L49.5 -66.2L47.7 -66.8L45.8 -67.6ZM44.7 -49.9L47.3 -49.2L49.8 -49.0L52.2 -49.1L54.6 -49.6L56.9 -50.4L59.1 -51.6L58.0 -53.6L56.0 -53.0L54.0 -52.6L52.1 -52.5L50.2 -52.8L48.3 -53.3L46.5 -54.1ZM45.4 -36.4L47.9 -35.8L50.4 -35.5L52.9 -35.7L55.3 -36.1L57.5 -37.0L59.7 -38.2L58.7 -40.2L56.6 -39.5L54.6 -39.2L52.7 -39.1L50.8 -39.4L49.0 -39.9L47.1 -40.7Z" />
                  <g data-paw>
                    <path class="unghia" d="M66 -12Q74 -13 78 -9Q72 -10 67 -8ZM67 -7Q75 -6 79 -2Q73 -3 67 -3ZM64 -2Q71 0 74 4Q69 2 63 1Z" data-claws />
                    <ellipse class="zampa" cx="57" cy="-7" rx="15" ry="8.5" />
                    <g class="cuscinetti" data-pads><ellipse cx="57" cy="-5" rx="5" ry="3" /><circle cx="49.5" cy="-9" r="2.2" /><circle cx="54.5" cy="-12" r="2.2" /><circle cx="60.5" cy="-12" r="2.2" /><circle cx="65.5" cy="-9" r="2.2" /></g>
                    <path class="dita" d="M58 -11L58 -4M65 -11L65 -5" />
                  </g>
                </g>
                <!-- the head turns on the neck: the ears behind it, the collar under the chin, then the face -->
                <g data-head>
                  <g data-ear-l>
                    <path class="gatto" id="ear-l-art" d="M54 -178L56 -232L90 -204Z" />
                    <path class="orecchio" id="ear-l-in" d="M62 -188L63 -218L81 -203Z" />
                    <path class="ciuffetti" id="ear-l-tuft" d="M65 -190Q62 -198 58 -205M69 -191Q68 -200 64 -209M74 -193Q74 -200 71 -208" />
                  </g>
                  <g data-ear-r>
                    <path class="gatto" id="ear-r-art" d="M138 -178L136 -232L102 -204Z" />
                    <path class="orecchio" id="ear-r-in" d="M130 -188L129 -218L111 -203Z" />
                    <path class="ciuffetti" id="ear-r-tuft" d="M127 -190Q130 -198 134 -205M123 -191Q124 -200 128 -209M118 -193Q118 -200 121 -208" />
                  </g>
                  <!-- the collar and its tag, which swings -->
                  <path class="collare-bordo" d="M58 -124Q82 -106 108 -113" />
                  <path class="collare" d="M58 -124Q82 -106 108 -113" />
                  <g data-tag>
                    <circle class="anello" cx="86" cy="-108" r="2.6" />
                    <circle class="medaglia" cx="86" cy="-100" r="6" />
                    <path class="medaglia-luce" d="M82.6 -102Q84 -104.6 87 -105" />
                  </g>
                  <path class="gatto" id="head-shape" d="M48 -164C46 -194 70 -210 96 -210C122 -210 146 -194 144 -164L150 -157L145 -152L153 -145L146 -140L151 -132L140 -128C128 -112 64 -112 52 -128L41 -132L46 -140L39 -145L47 -152L42 -157Z" />
                  <g id="head-stripes">
                    <path class="righe righe--fini" d="M80 -190L84 -201L90 -193L96 -204L102 -193L108 -201L112 -190" />
                    <path class="righe-piene" d="M45.6 -157.8L47.7 -157.7L49.8 -157.5L52.1 -157.2L54.6 -156.8L57.2 -156.3L59.9 -155.6L60.1 -156.4L57.6 -157.6L55.2 -158.7L52.9 -159.8L50.6 -160.7L48.5 -161.5L46.4 -162.2ZM45.0 -147.8L46.9 -148.0L48.9 -148.2L51.0 -148.2L53.2 -148.1L55.5 -147.9L57.9 -147.6L58.1 -148.4L55.9 -149.3L53.6 -150.1L51.5 -150.8L49.3 -151.4L47.1 -151.9L45.0 -152.2ZM46.4 -138.2L47.9 -138.7L49.4 -139.1L51.0 -139.4L52.6 -139.6L54.2 -139.7L55.9 -139.6L56.1 -140.4L54.4 -140.9L52.7 -141.3L51.0 -141.6L49.2 -141.8L47.5 -141.8L45.6 -141.8ZM145.6 -162.2L143.5 -161.5L141.4 -160.7L139.1 -159.8L136.8 -158.7L134.4 -157.6L131.9 -156.4L132.1 -155.6L134.8 -156.3L137.4 -156.8L139.9 -157.2L142.2 -157.5L144.3 -157.7L146.4 -157.8ZM147.0 -152.2L144.9 -151.9L142.7 -151.4L140.5 -150.8L138.4 -150.1L136.1 -149.3L133.9 -148.4L134.1 -147.6L136.5 -147.9L138.8 -148.1L141.0 -148.2L143.1 -148.2L145.1 -148.0L147.0 -147.8ZM146.4 -141.8L144.5 -141.8L142.8 -141.8L141.0 -141.6L139.3 -141.3L137.6 -140.9L135.9 -140.4L136.1 -139.6L137.8 -139.7L139.4 -139.6L141.0 -139.4L142.6 -139.1L144.1 -138.7L145.6 -138.2Z" />
                    <path class="lucido" d="M60 -192Q70 -203 86 -206" />
                  </g>
                  <!-- the features slide a little towards where it walks, and to the middle when it looks at you -->
                  <g data-face>
                    <path class="crema" id="muzzle" d="M76 -140C76 -152 92 -152 96 -146C100 -152 116 -152 116 -140C116 -128 104 -124 96 -128C88 -124 76 -128 76 -140Z" />
                    <path class="crema crema--mento" id="chin" d="M88 -127Q96 -118 104 -127Q96 -124 88 -127Z" />
                    <g data-blush>
                      <ellipse class="guancia" cx="66" cy="-148" rx="8" ry="4.5" />
                      <ellipse class="guancia" cx="126" cy="-148" rx="8" ry="4.5" />
                    </g>
                    <ellipse class="occhio" cx="78" cy="-166" rx="11.5" ry="12.5" />
                    <ellipse class="occhio" cx="114" cy="-166" rx="11.5" ry="12.5" />
                    <g clip-path="url(#cat-eyes-clip)">
                      <g data-look>
                        <circle class="iride" cx="78" cy="-166" r="9.5" />
                        <circle class="iride" cx="114" cy="-166" r="9.5" />
                        <ellipse class="pupilla" cx="78" cy="-166" rx="3" ry="8.5" data-pupil />
                        <ellipse class="pupilla" cx="114" cy="-166" rx="3" ry="8.5" data-pupil />
                        <circle class="riflesso" cx="81.5" cy="-170.5" r="2.6" />
                        <circle class="riflesso" cx="117.5" cy="-170.5" r="2.6" />
                        <circle class="riflesso riflesso--piccolo" cx="74.6" cy="-161.6" r="1.3" />
                        <circle class="riflesso riflesso--piccolo" cx="110.6" cy="-161.6" r="1.3" />
                      </g>
                    </g>
                    <ellipse class="occhio-bordo" cx="78" cy="-166" rx="11.5" ry="12.5" />
                    <ellipse class="occhio-bordo" cx="114" cy="-166" rx="11.5" ry="12.5" />
                    <g data-lid><ellipse class="palpebra" cx="78" cy="-166" rx="13.8" ry="14.2" /><path class="ciglio" d="M65 -166Q78 -139 91 -166" /></g>
                    <g data-lid><ellipse class="palpebra" cx="114" cy="-166" rx="13.8" ry="14.2" /><path class="ciglio" d="M101 -166Q114 -139 127 -166" /></g>
                    <!-- the long hairs over the eyes -->
                    <g data-brows><path class="baffi baffi--sopra" d="M70 -181Q64 -192 56 -199M75 -182Q72 -194 66 -203M114 -182Q120 -194 126 -203M119 -181Q128 -192 136 -199" /></g>
                    <g data-yawn>
                      <ellipse class="bocca" cx="96" cy="-126" rx="9" ry="10" />
                      <path class="dente" d="M89.5 -133.4L91.5 -128.6L93.5 -134.6ZM98.5 -134.6L100.5 -128.6L102.5 -133.4Z" />
                      <path class="lingua" d="M89 -121Q96 -126 103 -121Q101 -116 96 -116Q91 -116 89 -121Z" />
                      <path class="lingua-riga" d="M96 -122L96 -118" />
                    </g>
                    <path class="naso" id="nose" d="M96 -139C92 -141.5 88.5 -144 89 -146.6C89.5 -148.8 93 -149.4 96 -147C99 -149.4 102.5 -148.8 103 -146.6C103.5 -144 100 -141.5 96 -139Z" />
                    <ellipse class="naso-luce" id="nose-shine" cx="92.6" cy="-146.4" rx="1.8" ry="1.1" />
                    <path class="bocca-linea" id="mouth" d="M96 -139L96 -134.5M87 -132.5Q91.5 -129 96 -134.5Q100.5 -129 105 -132.5" />
                    <path class="radici" id="whisker-roots" d="M84.6 -136.4h0.01M81.6 -133.4h0.01M85 -131.4h0.01M107.4 -136.4h0.01M110.4 -133.4h0.01M107 -131.4h0.01" />
                    <path class="baffi" d="M81 -137Q56 -145 28 -146M80 -134Q54 -136 24 -132M81 -131Q58 -126 30 -116" data-whisk-l />
                    <path class="baffi" d="M111 -137Q136 -145 164 -146M112 -134Q138 -136 168 -132M111 -131Q134 -126 162 -116" data-whisk-r />
                  </g>
                </g>
              </g>
            </g>

            <!-- the same cat curled up asleep: a round loaf, the tail wrapped in front, the head on its paws -->
            <g data-sleep>
              <g data-sleep-breath>
                <path class="gatto gatto--pieno" d="M-108 -2C-116 -56 -64 -100 -4 -100C56 -100 106 -70 108 -16C108 -6 102 -2 94 -2Z" />
                <g clip-path="url(#cat-sleep-clip)">
                  <rect x="-120" y="-50" width="240" height="50" fill="url(#cat-shade)" />
                  <path class="righe-piene" d="M-82.4 -86.9L-81.0 -82.7L-80.1 -78.6L-79.6 -74.5L-79.5 -70.5L-79.8 -66.4L-80.6 -62.4L-81.8 -58.3L-83.5 -54.2L-85.6 -50.2L-88.2 -46.2L-87.8 -45.8L-84.4 -49.4L-81.5 -53.1L-79.0 -57.0L-76.9 -61.0L-75.2 -65.3L-73.9 -69.7L-73.1 -74.3L-72.8 -79.1L-73.0 -84.1L-73.6 -89.1ZM-56.9 -102.8L-55.5 -98.3L-54.4 -93.8L-53.8 -89.3L-53.5 -84.9L-53.6 -80.4L-54.1 -76.0L-55.0 -71.5L-56.3 -67.0L-58.1 -62.6L-60.2 -58.2L-59.8 -57.8L-56.7 -61.8L-54.1 -66.0L-51.8 -70.3L-49.9 -74.8L-48.4 -79.5L-47.3 -84.3L-46.6 -89.3L-46.4 -94.5L-46.5 -99.7L-47.1 -105.2ZM-28.9 -107.9L-27.4 -103.1L-26.3 -98.3L-25.5 -93.6L-25.0 -88.9L-24.9 -84.3L-25.1 -79.6L-25.6 -75.0L-26.5 -70.4L-27.7 -65.7L-29.3 -61.1L-28.7 -60.9L-26.3 -65.1L-24.1 -69.6L-22.3 -74.1L-20.8 -78.9L-19.6 -83.7L-18.8 -88.7L-18.3 -93.9L-18.2 -99.2L-18.5 -104.6L-19.1 -110.1ZM-0.9 -107.8L0.6 -103.2L1.8 -98.6L2.8 -94.0L3.4 -89.5L3.9 -85.1L4.0 -80.6L3.9 -76.2L3.4 -71.8L2.7 -67.4L1.7 -63.1L2.3 -62.9L4.2 -67.0L5.8 -71.2L7.2 -75.6L8.3 -80.2L9.1 -84.8L9.7 -89.6L9.9 -94.6L9.9 -99.7L9.5 -104.9L8.9 -110.2ZM27.6 -102.9L29.1 -98.5L30.4 -94.2L31.5 -90.0L32.4 -85.8L33.1 -81.7L33.6 -77.7L33.9 -73.7L34.1 -69.8L34.0 -65.9L33.7 -62.1L34.3 -61.9L35.4 -65.7L36.3 -69.5L37.1 -73.6L37.6 -77.7L37.9 -82.0L38.0 -86.4L37.9 -90.9L37.6 -95.5L37.1 -100.3L36.4 -105.1ZM54.2 -92.8L55.6 -89.2L56.9 -85.6L58.0 -82.1L59.0 -78.7L59.9 -75.4L60.5 -72.2L61.1 -69.0L61.4 -66.0L61.7 -63.0L61.7 -60.0L62.3 -60.0L63.0 -62.9L63.5 -65.9L63.9 -69.1L64.1 -72.4L64.1 -75.9L64.0 -79.5L63.7 -83.2L63.3 -87.1L62.6 -91.1L61.8 -95.2Z" />
                  <path class="coscia" d="M-100 -8C-104 -46 -80 -66 -50 -64C-28 -62 -14 -44 -18 -24" />
                  <path class="lucido" d="M-90 -52Q-60 -92 0 -94" />
                  <path class="lucido lucido--fine" d="M14 -94Q50 -90 74 -70" />
                </g>
                <path class="gatto-linea" d="M-108 -2C-116 -56 -64 -100 -4 -100C56 -100 106 -70 108 -16C108 -6 102 -2 94 -2Z" />
              </g>
              <g data-sleep-tail>
                <path class="coda-bordo" data-sleep-tail-line />
                <path class="ciuffo-bordo" d="M-12 -8Q-2 -12 8 -9L14 -10L13 -5L21 -3L15 0L21 4L13 6L14 10L7 9Q-2 12 -12 8Z" data-sleep-tail-tuft-line />
                <path class="coda" data-sleep-tail-fur />
                <path class="coda-righe" data-sleep-tail-stripes />
                <path class="ciuffo" d="M-12 -8Q-2 -12 8 -9L14 -10L13 -5L21 -3L15 0L21 4L13 6L14 10L7 9Q-2 12 -12 8Z" data-sleep-tail-tuft />
              </g>
              <ellipse class="zampa" cx="36" cy="-7" rx="14" ry="8" />
              <ellipse class="zampa" cx="60" cy="-6" rx="14" ry="8" />
              <path class="dita" d="M38 -11L38 -4M45 -10L45 -4M62 -10L62 -3M69 -9L69 -3" />
              <g data-sleep-head>
                <g transform="translate(70 -58) rotate(-8) scale(0.9) translate(-96 164)">
                  <g data-sleep-ear-l><use href="#ear-l-art" /><use href="#ear-l-in" /><use href="#ear-l-tuft" /></g>
                  <g data-sleep-ear-r><use href="#ear-r-art" /><use href="#ear-r-in" /><use href="#ear-r-tuft" /></g>
                  <use href="#head-shape" />
                  <use href="#head-stripes" />
                  <use href="#muzzle" />
                  <use href="#chin" />
                  <path class="occhio-chiuso" d="M68 -164Q78 -157 88 -164M104 -164Q114 -157 124 -164" />
                  <use href="#nose" />
                  <use href="#nose-shine" />
                  <use href="#mouth" />
                  <use href="#whisker-roots" />
                  <path class="baffi" d="M81 -137Q58 -143 34 -142M80 -134Q56 -134 30 -129M111 -137Q134 -143 158 -142M112 -134Q136 -134 162 -129" />
                </g>
              </g>
            </g>
          </g>
        </g>

        <g data-fx></g>
      </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.

31 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 mischievous cat logo” from Animorio and fit it into my site

What it does

On cream paper the logo of a made-up brand, PURRLO, arrives in a heavy black grotesque: the letters drop from above one after the other and bounce like rubber balls, squashing at every touch and stretching in the air, each with its own shadow shrinking and growing on the floor. The logo moves aside and a ginger tabby walks in from the left: striped body, cream belly, muzzle and paws, green eyes, a tail that never stops swaying. It sees the logo, its ears prick up, its pupils open wide; it crouches, its bottom wiggles, the tip of its tail quivers, and it pounces on top of the letters. As it lands the letters sink and bounce like a mattress, and as it walks the ones under its paws dip under its weight. Then it plays: it taps the last letter, which rocks on its foot while the cat follows it with its head, winds up its paw and with a firm swipe knocks it off: the letter falls, bounces on the floor and rolls away. It rubs its cheek on another letter, eyes shut and cheeks pink, and the letter leans a little more at every rub. It puts its claws out and scratches a third from top to bottom: three claw marks are left in the letter and crumbs fall. At last it turns to you, looks you straight in the eye with huge pupils and, without looking away, rests its paw on one last letter and slowly pushes it down, in two goes, until it slips and falls; then it gives you a slow, pleased blink. It turns round twice, curls up on the logo and falls asleep: its belly breathes, an ear twitches, the tip of its tail moves, little zeds float up. After a few seconds it wakes up, stretches outrageously with a yawn, shakes its fur, jumps down and walks off: the fallen letters spring back up, the leaning one straightens, the scratches close and the story starts again, a little different every time. A click restarts it from the beginning. A picture can take the place of the word, cut into upright strips that act as letters.

How it works

A stage to size

The stage is an SVG whose viewBox is as big as the window, so one unit is one pixel. Each letter is measured on a canvas in the same typeface (measureText, with the four actualBoundingBox values for its true box), and that gives a single size for everything: the logo, the room on the left for the pounce, the room on the right for the letter that rolls away and the height of the cat above the letters. On a tall screen the cat is a little bigger and crouches half past the edge.

The weight on the letters

The cat’s place, facing and size live in one object that GSAP animates and that a function called by gsap.ticker writes as a transform. When the cat is on the logo its height is not animated: it is worked out every frame from the highest letter under its paws, and every letter under a paw sinks and squashes a little; a landing adds a weight that goes back to zero with an elastic, and the letters bounce like a mattress. Every letter is made of three nested groups: one for flight, one for the bounces and the rocking on its foot, one for the weight.

The letter that falls and rolls

A letter knocked off is not animated with x and y: what is animated is its height above the floor, its rotation and its shift, and its position comes from its turned box, which meets the floor at half its true height (width times the sine plus height times the cosine). So it bounces on the right corner and, rolling a quarter turn at a time over a distance equal to the arc, it always comes to rest on one side.

The scratches

The scratches are an SVG mask on the letter: a white rectangle and three black strokes drawn with stroke-dashoffset, together with the paw stretching down (the leg stretches with scaleY and the foot shrinks back with the inverse scale, so it stays round). Where to scratch is chosen by reading the letter’s pixels on a canvas: the column with the most ink under the three strokes, because a U is empty in the middle. The cat stops with its paw right there.

The cat

It is drawn only once in the page, in pieces and with an outline, like the dinosaur: four striped legs, cream paws with toes and pink pads underneath (they only show when the leg lifts far enough to turn the sole: their opacity is worked out every frame from the leg’s rotation), the haunch with its stripes, shade and light, the body with its belly, its chest, a soft shade at the bottom and solid stripes that taper as they follow the flank, the tufts of fur on chest and belly, tufted cheeks, the M on the forehead, the pink inside of the ears with little tufts, the collar with a swinging tag, the heart-shaped nose with its shine, the three-shaped mouth, the whisker roots, long whiskers and the ones over the eyes, the eyes with a shaded iris, an upright pupil that widens and two highlights, the eyelids, the yawn with tongue and little teeth. Stripes, shades and lights stay inside the shape with a clipPath, which moves with the piece. Each piece turns on its joint, a point of the drawing that joint() turns into percentages of the piece’s box with getBBox. The tail is a chain of six joints: one path worked out every frame, drawn three times (outline, fur, stripes with stroke-dasharray), swaying with the timeline’s clock; a dark tuft follows the last joint, the tip curls (hook) and when the cat crouches the whole tail puffs up (puff, which widens the strokes). Before the pounce the fur on its back stands up for an instant: a row of spikes hidden behind the body that rises and drops back. The features of the face slide towards where it walks and back to the middle when it looks at you. Asleep it is a second drawing, a loaf with its haunch, its stripes and its head on its paws, reusing the same head pieces with use.

Direction and your logo

The whole story is one timeline, with timeScale for the speed and a label for every moment. Where to stand for each trick is decided beforehand, letter by letter: on the side that needs less walking and fewer turns, with real letters under the paws. At the end the scene is rebuilt from the «arrive» label. If IMAGE holds an address, the picture is cut into upright strips with clipPaths and every strip acts as a letter; in the Playground, next to the field, there is a button to upload a file from your computer, which goes into the code as a data: address.

Values to change

NameFileDefaultWhat it changes
NAMEscript.js'PURRLO'The logo as a word: every letter is a piece the cat walks on and can knock off, scratch or push.
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 is cut into upright strips that act as letters.
KNOCKEDscript.js5The letter the cat bats and knocks off, counting from 0 without spaces. Past the last one, the last one.
SCRATCHEDscript.js1The letter the cat scratches, counting from 0 without spaces. If it is the same as KNOCKED, it scratches the one next to it.
CATscript.js1.2How tall the cat is to the tips of its ears, in letter heights.
SPEEDscript.js1The speed of the whole story: 2 is twice as fast, 0.5 half as fast.
RESTscript.js4How many seconds the cat sleeps on the logo before it wakes up.
LOOPscript.jstrueWhether the cat wakes up, the letters go back into place and the story starts again. With false it sleeps on and on.

Try them in the Playground

When to use it

To present a logo with a smile: a preview for a client, the opening of a site, a pet shop or a video, a 404 page or a loading screen people actually watch, a social post. It works with a written wordmark and with a picture.

On phones

The same story, with the sizes adapted: the logo takes almost the whole width, the cat is a little bigger and crouches half past the left edge before it pounces; the knocked letter rolls less, so as to stay on screen. A tap restarts it.

With reduced motion

Nothing moves: the logo fades in, then the cat next to it; then the cat asleep on the logo fades in, with the letters fallen on the floor, the leaning one and the scratches. If the story starts again, the letters going back are a fade too. Tail, whiskers and breath stay still.

Pitfalls

  • The cat on the logo cannot have an animated height: the letters sink under its weight, and it would end up floating or sinking into them. Its height is worked out every frame from the letters under its paws, and GSAP only animates how much the cat «stands on top» (ride) to go from the jump to the logo.
  • The U is empty in the middle: scratches placed in the centre of the letter fell into the hole and did not show. The right column is found by reading the letter’s pixels on a canvas.
  • A letter falling while turning, animated with y, went into the floor or stayed hanging: its height comes from its turned box, and the roll stops at a multiple of a quarter turn, so it ends up resting on one side.
  • Eyelids with an outline, closed, became two empty circles in place of the eyes: now they are fur with no outline and a single line at the bottom, which when closed is the sleeping eye.
  • The scratching leg stretches with scaleY, and the paw turned into a long oval: the paw has the inverse scale around its centre.
  • Crouched too close to the logo, the cat’s head ended up in front of the first letter: the place for the pounce allows for how far the head sticks out past the paws.
  • A picture cut into strips side by side would show a thin line between them: the cuts overlap by half a pixel.
  • With so many details, pieces of the same colour vanished into one another and the stripes went past the shape: stripes, shades and lights sit inside a clipPath of the shape (body, haunch, loaf), the chest and belly tufts and the raised fur sit behind the body so that only their tips show, and the tail, which changes shape every frame, has its tuft drawn twice (outline under the fur, colour over it) so that no outline line shows where it joins.
  • Ears that «really» turn cannot use rotation in a second tween: it would clash with the story’s own and the ear would jump. The flick only uses scaleX (the ear narrows as if turning), a property no other tween touches.

Libraries

GSAP 3.15.0, Bricolage Grotesque (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 27 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