
The UFO-abducted logo
Intro, SVG, Text
NewFree
A logo preview in three acts: the letters drop and land with a squash, then a dinosaur walks in from the right, roars and bites off the end of the logo, which bleeds in thick drips; a stomp cracks a letter in two. In the Playground you type your own name or upload your own logo.
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 dinosaur-bitten logo</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/unbounded@5.3.0/index.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 dinosaur -->
<svg class="palco" data-stage role="img" aria-label="Brambly" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- the bite: everything white stays, the black circles are the hole -->
<mask id="bite" maskUnits="userSpaceOnUse" data-bite-mask>
<rect fill="#fff" data-bite-full />
<g fill="#000" data-hole></g>
</mask>
<!-- the wound shows only where there is still logo -->
<mask id="on-logo" maskUnits="userSpaceOnUse" style="mask-type: alpha" data-on-logo>
<use href="#logo" />
</mask>
<!-- the piece of logo that ends up in the mouth -->
<clipPath id="chunk-cut" data-cut></clipPath>
<radialGradient id="wound-fill" gradientUnits="userSpaceOnUse" data-wound-fill>
<stop offset="0" class="ferita-scura" />
<stop offset="0.66" class="ferita-scura" />
<stop offset="0.74" class="ferita" />
<stop offset="1" class="ferita ferita--via" />
</radialGradient>
<!-- the drips melt into each other like a thick liquid -->
<filter id="goo" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB" data-goo>
<feGaussianBlur in="SourceGraphic" stdDeviation="5" data-goo-blur />
<feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 22 -9" />
</filter>
<!-- the dinosaur's body and tail, to keep the belly, the stripes and the spots inside them -->
<clipPath id="dino-body-clip">
<path d="M176 64C192 88 214 100 246 104C278 108 300 118 318 128L336 170L316 222C296 252 246 262 200 254C156 246 128 210 126 168C126 140 132 116 146 98Z" />
</clipPath>
<clipPath id="dino-tail-clip">
<path d="M296 126C340 122 400 108 462 80C456 110 424 148 384 176C360 194 334 212 300 230Z" />
</clipPath>
</defs>
<g data-world>
<g data-ground></g>
<g id="logo" data-logo></g>
<g mask="url(#on-logo)"><circle class="ferita-disco" fill="url(#wound-fill)" data-wound /></g>
<g class="sangue" filter="url(#goo)" data-blood></g>
<g data-shine></g>
<!-- the dinosaur: drawn facing left, the point between its feet is 0 0 -->
<g data-dino-place>
<ellipse class="dino-ombra" cx="0" cy="2" rx="120" ry="10" data-dino-shadow />
<g data-dino-flip>
<g data-dino-body>
<g transform="translate(-250 -300)">
<!-- the far leg, darker, behind everything -->
<g data-leg-back>
<path class="dino-lontano" d="M258 190C252 160 302 156 318 186C330 210 318 238 298 246L294 280L304 284C313 288 313 300 304 300L250 300C240 300 238 290 248 287L270 282L272 246C258 238 260 212 258 190Z" />
<path class="unghia" d="M250 300L239 302L248 294ZM262 300L252 303L260 295Z" />
</g>
<!-- the tail: its spikes behind it, its stripes and spots inside it -->
<g data-tail>
<path class="dino-cresta" d="M324.7 126Q332.6 114.8 338.5 108Q339.1 117.8 343.3 126ZM355.9 118Q362.8 107.8 367.9 102Q368.4 110.5 372.1 118ZM386.2 108Q392 99 396.3 94Q396.8 101.2 399.8 108ZM415.4 98Q420.2 90 423.7 86Q424.1 91.8 426.6 98ZM439.7 89Q443.3 82.2 446.1 79Q446.4 83.5 448.3 89Z" />
<path class="dino" d="M296 126C340 122 400 108 462 80C456 110 424 148 384 176C360 194 334 212 300 230Z" />
<g clip-path="url(#dino-tail-clip)">
<path class="dino-pancia" d="M300 232C334 214 362 196 386 178C420 152 452 116 470 80L470 260L300 260Z" />
<path class="dino-macchia" d="M352 132C360 126 372 126 374 132C372 138 358 140 352 132ZM392 118C398 113 408 113 409 118C407 123 396 124 392 118ZM424 104C429 100 436 100 437 104C435 108 427 109 424 104Z" />
</g>
</g>
<!-- the spikes along the back, half hidden by the body -->
<path class="dino-cresta" d="M185.9 87Q192.8 76.8 197.9 71Q198.4 79.5 202.1 87ZM207.5 99Q216.4 86.7 223.1 79Q223.8 90 228.5 99ZM233.2 106Q243.2 92.5 250.7 84Q251.5 96.3 256.8 106ZM261.8 111Q271.3 98.1 278.4 90Q279.1 101.7 284.2 111ZM289.1 120Q297.5 108.2 303.8 101Q304.5 111.4 308.9 120Z" />
<!-- the throat swells when it swallows -->
<circle class="dino" cx="150" cy="110" r="0" data-gulp />
<!-- body and neck in one piece; the outline is drawn apart, so that it stops where the tail starts -->
<path class="dino dino--pieno" d="M176 64C192 88 214 100 246 104C278 108 300 118 318 128L336 170L316 222C296 252 246 262 200 254C156 246 128 210 126 168C126 140 132 116 146 98Z" />
<g clip-path="url(#dino-body-clip)">
<path class="dino-pancia" d="M128 150C140 206 186 244 250 252C276 255 300 248 318 234L318 300L100 300L100 150Z" />
<path class="dino-righe" d="M124 174Q137 179 148 173M130 198Q147 205 162 198M143 220Q163 229 180 221M164 238Q187 247 207 240M196 250Q220 257 244 250" />
<path class="dino-macchia" d="M226 118C234 111 248 112 250 119C247 126 232 127 226 118ZM260 126C266 121 276 122 277 127C275 132 264 133 260 126ZM204 104C209 100 217 101 218 105C216 109 208 110 204 104ZM288 138C293 134 300 135 301 139C299 143 292 144 288 138Z" />
<path class="dino-lucido" d="M196 96C218 110 252 116 296 126" />
</g>
<path class="dino-linea" d="M176 64C192 88 214 100 246 104C278 108 300 118 318 128M316 222C296 252 246 262 200 254C156 246 128 210 126 168C126 140 132 116 146 98" />
<!-- the far arm, darker, over the chest -->
<g data-arm-back>
<path class="braccio-bordo" d="M174 190Q160 200 156 212Q148 210 140 206" />
<path class="braccio braccio--lontano" d="M174 190Q160 200 156 212Q148 210 140 206" />
<path class="unghia" d="M136 202L129 201L135 207ZM137 208L131 211L138 211Z" />
</g>
<!-- the head: it turns on the neck; the inside of the mouth, the piece it bites, the jaw, then the skull -->
<g data-head>
<g data-mouth>
<path class="bocca" d="M158 104L64.5 98L64.5 182.4Z" />
<path class="lingua" d="M152 110C132 114 104 124 86 142C82 148 92 151 99 146C114 135 134 124 154 117Z" />
</g>
<g data-chunk-slot></g>
<g data-jaw>
<path class="dente" d="M42 106L47 93L53 106ZM58 106L63 94L69 106ZM74 106L79 94L85 106ZM90 106L95 94L101 106ZM106 106L111 95L117 106ZM122 106L127 96L132 106Z" />
<path class="dino" d="M158 104L36 104C25 104 20 114 28 122C44 136 104 140 144 132C166 128 170 112 158 104Z" />
<path class="dino-righe" d="M48 124Q90 132 136 124" />
</g>
<path class="dente" d="M34 100L39 113L45 100ZM50 100L55 113L61 100ZM66 100L71 113L77 100ZM82 100L87 113L93 100ZM98 100L103 113L109 100ZM114 100L119 112L125 100ZM130 100L135 111L141 100Z" />
<path class="dino" d="M182 82C184 56 168 38 140 34C128 26 108 24 96 32C70 32 36 42 18 62C8 74 10 94 24 100L158 104C176 104 184 96 182 82Z" />
<path class="dino-macchia" d="M146 50C151 45 160 46 161 51C159 56 150 57 146 50ZM164 62C168 59 174 60 174 64C172 68 166 68 164 62ZM58 46C62 43 68 43 69 46C67 50 61 50 58 46Z" />
<path class="dino-lucido" d="M30 58C48 44 72 38 92 37" />
<path class="dino-scuro" d="M26 60C29 56 36 57 37 60C35 64 28 64 26 60Z" />
<ellipse class="guancia" cx="142" cy="88" rx="13" ry="7" data-blush />
<ellipse class="orbita" cx="114" cy="60" rx="19" ry="16" />
<circle class="occhio" cx="112" cy="60" r="13" />
<g data-pupil>
<circle class="iride" cx="107.5" cy="61" r="8" />
<circle class="pupilla" cx="106.5" cy="61" r="4.6" />
<circle class="riflesso" cx="104" cy="57.6" r="2.4" />
</g>
<ellipse class="palpebra" cx="112" cy="60" rx="15.6" ry="15.6" data-lid />
<path class="ciglio" d="M95 42Q112 33 131 42" data-brow />
</g>
<!-- the near arm, in front of the chest -->
<g data-arm>
<path class="braccio-bordo" d="M166 184Q151 194 146 207Q137 205 128 199" />
<path class="braccio" d="M166 184Q151 194 146 207Q137 205 128 199" />
<path class="unghia" d="M124 195L117 194L123 200ZM125 201L119 204L126 204Z" />
</g>
<!-- the near leg, with its thigh -->
<g data-leg-front>
<path class="dino" d="M182 206C176 176 226 166 244 194C258 216 246 246 224 252L220 282L232 286C241 290 241 300 232 300L176 300C166 300 164 290 174 287L198 282L198 250C186 242 184 222 182 206Z" />
<path class="dino-righe" d="M196 220C204 236 222 242 238 232M200 284L218 284" />
<path class="unghia" d="M176 300L165 302L174 294ZM188 300L178 303L186 295Z" />
</g>
</g>
</g>
</g>
</g>
<g data-crumbs></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>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.
25 values to change
With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:
Take “The dinosaur-bitten logo” from Animorio and fit it into my siteThe stage is an SVG whose viewBox is as big as the window, so one unit is one pixel. The letters are measured on a canvas in the same typeface (measureText, actualBoundingBoxAscent for the true height), and that gives a single size for everything: logo, bite and dinosaur always sit side by side. On a tall screen the dinosaur is a little bigger and, once stopped, shows only its head and chest: the rest stays past the edge.
The bite is an SVG mask: a white rectangle and, in black, a circle with seven small circles on its left edge, the tooth marks. It sits on every bitten letter and, with maskUnits userSpaceOnUse, follows the letter when it moves. The same shape, as a clipPath, cuts out a copy of the bitten piece that goes inside the dinosaur’s head: it gets the inverse of the head’s transform (getCTM), so it starts exactly where it was bitten and then follows the mouth as it chews.
The wound is a radial gradient that spreads from the edge of the hole, shown only where there is still logo thanks to an alpha mask holding a use of the logo. The drips are a rectangle and a circle growing downwards, under a filter that makes them run like a thick liquid (a blur and then a matrix that hardens the alpha). Where they start is found by drawing the bitten letters on a canvas and reading the pixels along the edge of the bite. The drops fall with power2.in and each one widens the puddle.
The letter that breaks has two copies, each cut by a clipPath that follows the same zigzag, and the zigzag drawn on top in the colour of the paper: it is traced with stroke-dashoffset. Until it cracks the whole letter is shown, because two halves side by side leave a thin line. Then each half turns around its outer bottom corner and falls to the floor with bounce.out.
It is drawn only once in the page, in pieces and with an outline: legs with thighs and claws, tail with spikes and spots, little arms, striped belly, head with the jaw, the tongue, the yellow eye, the eyelid and the brow. Each piece turns around its own joint: a point of the drawing (the hip, the shoulder, the hinge of the jaw) that the script turns into percentages of the piece’s box with getBBox. Once in the mouth, the bitten piece slides to the tip of the snout and stays held between the teeth while it chews. The walk is a nested timeline that repeats; place, size and facing go into one object written as a transform attribute. The inside of the mouth is a triangle stretched by the cosine and sine of the opening, so its corner stays behind the tip of the jaw.
The whole story is one timeline, with timeScale for the speed. At the end the logo heals and the scene is rebuilt from the «arrive» label, with new drips every time. If IMAGE holds an address, the logo becomes that picture: a single piece, bitten on the right and cracked at four tenths of its width. 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.
| Name | File | Default | What it changes |
|---|---|---|---|
NAME | script.js | 'Brambly' | The logo as a word: every letter is a piece the dinosaur can bite or break. |
IMAGE | script.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. |
BREAKS | script.js | 2 | The letter that cracks, counting from 0. If the bite has already taken it, the nearest whole one breaks. A picture cracks at four tenths of its width. |
BITE | script.js | 1.3 | How wide the bite is, in letter heights. |
DRIPS | script.js | 5 | How many drips run from the bite, at most: they only start where there is still logo around the hole. |
DINO | script.js | 2.4 | How tall the dinosaur is, in letter heights. |
SPEED | script.js | 1 | The speed of the whole story: 2 is twice as fast, 0.5 half as fast. |
REST | script.js | 4 | How many seconds the logo stays bitten and dripping before it heals. |
LOOP | script.js | true | Whether the logo heals and the story starts again. With false it stays bitten and keeps dripping. |
To present a logo in a way nobody forgets: a preview for a client, the opening of a studio’s site or video, a 404 page or a loading screen with a sense of humour, a social post. It works with a written wordmark and with a picture.
The same story, with the sizes adapted: on a tall screen the dinosaur is a little bigger and, when it stops, only its head and chest are in view. A tap restarts it.
Nothing moves: the logo fades in, then the dinosaur next to it, then the bite, the blood and the crack fade in, and the dinosaur fades away. If the story starts again, the healing is a fade too.
GSAP 3.15.0, Unbounded (font variabile) 5.3.0.
Compressed with gzip, the three demo files weigh 16 KB; the libraries: GSAP 28 KB.
Tested on 10 October 2026
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.
With your account’s email and password.
or with your email
You’re signed in as .
With your account, you can download the zip of every animation and every pack, for free.