Skip to content
animorio
IT
Back to the library

The inkjet-printer logo

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

A logo intro with an inkjet printer seen from above: the print head runs back and forth row by row, spraying dots of cyan, magenta, yellow and black that swell and blend into the brand colour, and the sheet comes out and lands on the desk with a little bounce. 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 inkjet-printer logo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/lexend@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="scena">
    <!-- the stage: the script measures it, builds the printer and the sheet, and prints the logo row by row -->
    <svg class="palco" data-stage role="img" aria-label="Mixtone" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <!-- soft shadows on the desk -->
        <filter id="soft" x="-30%" y="-60%" width="160%" height="220%">
          <feGaussianBlur stdDeviation="6" data-soft-blur />
        </filter>
        <!-- the shade the printer's lip throws on the paper coming out of the slot -->
        <linearGradient id="lip-grad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" class="labbro-stop" />
          <stop offset="1" class="labbro-stop labbro-stop--via" />
        </linearGradient>
        <!-- the shine of fresh ink -->
        <linearGradient id="gloss-grad" x1="0" y1="0" x2="1" y2="0">
          <stop offset="0" class="lucido-stop lucido-stop--via" />
          <stop offset="0.5" class="lucido-stop" />
          <stop offset="1" class="lucido-stop lucido-stop--via" />
        </linearGradient>
        <!-- while it prints, the sheet shows only below the slot -->
        <clipPath id="paper-clip">
          <rect data-paper-clip />
        </clipPath>
      </defs>

      <g data-world>
        <!-- the printer: shadow, paper trays, body, the window with the rail and the print head -->
        <g data-printer-place>
          <g data-printer></g>
        </g>
        <!-- the sheet, with the dots and the print on it -->
        <g clip-path="url(#paper-clip)">
          <g data-paper></g>
        </g>
        <!-- the shade of the printer's lip, over the paper -->
        <g data-printer-over-place>
          <g data-printer-over></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.

32 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 inkjet-printer logo” from Animorio and fit it into my site

What it does

On a blue-grey desk an inkjet printer, seen from above, drops in from the top: it hits the desk, squashes and springs back, the cartridges hop and two puffs of air come out at its feet. A button goes down, the output tray slides out with a bounce and the print head, a carriage with the four cartridges of cyan, magenta, yellow and black, runs along its rail to the start of the line; the top sheet of the stack is pulled in and comes out of the slot in two jerks. Then the printing, row by row, from the bottom of the logo up (the sheet comes out towards us): on each row the head runs to the right spraying tiny drops of the four colours, which land on the paper as a halftone of dots (each colour at its own angle, as in a print shop, and as big as its share of the brand colour); then it runs back and behind it the dots swell, overlap and blend into the solid brand colour, a bright coral. The sheet steps forward, the printer gives a little kick on every pass and the cartridges jolt at every turn. After the last row the head goes home and the sheet comes all the way out; the printer lifts off and flies away, the tray slides back in, and the sheet with the logo of a made-up brand, Mixtone, glides to the middle of the desk, lands, gives a little bounce and quivers. A glint of fresh ink runs over the logo. The sheet stays there, breathing and glinting now and then; after a few seconds it slides away and the printer comes back for a new sheet. A click restarts it. A picture can take the place of the word: it is printed in the brand colour, or in its own colours.

How it works

One size

The 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 everything is counted in letter heights: the sheet is as wide as the logo plus a margin, the printer a little wider, with a rail long enough for the head to run past both ends of the logo. The size is chosen so that, while it prints, the input tray, the printer and the sheet hanging from the slot all fit. The sheet is drawn in the coordinates of its final place, in the middle: while printing it is only moved up and clipped below the slot by a clipPath that stays still.

The four-colour halftone

Every row has four SVG patterns, one per ink, with one circle per tile and a patternTransform that turns it by 15, 75, 0 and 45 degrees: the screens of a print shop. The four rectangles filled with the patterns have mix-blend-mode multiply, so where the dots touch the colours mix like inks. An alpha mask holding a use of the logo keeps them inside the letters. The brand colour, read from the CSS variable, is split into cyan, magenta, yellow and black, and the area of each dot follows its share: a coral gives big magenta and yellow dots and small cyan and black ones.

The head and the rows

Every pass of the head is an object with a value v that a tween takes from 0 to 1 with sine.inOut. A single function draws everything from those values: the head stands where the last pass that has started has brought it; for each row one clipPath shows the dots from the start up to the head, another shows the solid colour from the end up to just behind the head on its way back, and the radius of the dots grows with the second pass, so they are seen swelling and blending before they turn solid. The same function also runs on gsap.ticker: a timeline moved with seek does not call onUpdate.

The sheet that lands

Between one row and the next the sheet moves forward by a row's height with back.out, while the printer gives a little kick and the cartridges jolt one after the other. At the end the slot's clip goes away, the printer lifts off with back.in and the sheet, which sits above it, grows a little and spreads its shadow (it rises towards us), glides to the middle and comes down: it squashes a touch, rises a little and drops back with bounce.out, while its outline, a path of four quadratic curves, quivers through a series of dying curves.

Direction and your logo

The whole intro is one timeline, with the labels start, land, wake, print, eject, release, reveal, rest and timeScale for the speed. Once the printing is done the rows give way to the whole logo in one piece, so no seam is left between them. If IMAGE holds an address, the logo becomes that picture: its transparency masks the dots, and a filter prints it in the brand colour (the light parts and the transparent background stay paper), or it keeps its own colours. In the Playground, next to the field, there is a button to upload a file, which goes into the code as a data: address.

Values to change

NameFileDefaultWhat it changes
NAMEscript.js'Mixtone'The logo as a word: the printer prints it row by row.
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.
ROWSscript.js6In how many rows the logo is printed: each row is one pass of drops and one pass back that blends them. More rows, a longer and finer print.
DOTSscript.js1How big the dots of the four colours are before they blend: 0.6 fine, 1.8 coarse.
BOUNCEscript.js1How much the sheet bounces as it lands on the desk (0 = it settles gently).
TINTscript.jstrueA picture is printed in the brand colour; with false it keeps its own colours.
SPEEDscript.js1The speed of the whole animation: 2 is twice as fast, 0.5 half as fast.
RESTscript.js4How many seconds the printed logo stays on show before the sheet slides away.
LOOPscript.jstrueWhether the sheet slides away and the printer comes back for a new one. With false the logo stays, the sheet breathing and glinting.

Try them in the Playground

When to use it

To present a logo with a gesture that smells of printing and colour: the opening of the site of a print shop, a copy shop, a design studio or a stationery brand, a logo preview for a client, a loading screen, a social post. It works with a written wordmark and with a picture.

On phones

The same animation with the sizes adapted: on a tall screen the margins of the sheet and of the printer are narrower, so the logo is almost three quarters of the screen wide. A tap restarts it.

With reduced motion

Nothing moves: the printer fades in, then fades away and the sheet with the logo already printed fades in in its place. If the animation starts again, the sheet leaves with a fade too.

Pitfalls

  • The functions that draw by hand (the head, the row clips, the sheet) only ran in onUpdate: with the timeline moved by seek, as the tests and the thumbnails do, the head stood still and the logo never showed. Now they also run on gsap.ticker.
  • A picture printed in a tint has semi-transparent areas: the rows, which overlap by half a pixel so as to leave no gaps, left darker stripes. Once the printing is done the rows give way to the whole logo, and the tint filter makes the colours solid.
  • Where the solid colour was transparent (the white hole in a picture) the dots still showed underneath: the dots of each row now stop where the solid colour begins.
  • The sheet's shadow, blurred and moved down, peeked out below the slot before the sheet came out: at the start the sheet sits higher up inside the printer.
  • The row printed first is the bottom one: the sheet comes out towards the viewer, so the first part out is the bottom of the logo. Printing from the top, the logo would have come out upside down.
  • The first print is always the same (same screen angles and same turn of the sheet), so the poster frame always falls on the sheet just landed; from the second one they vary a little.

Libraries

GSAP 3.15.0, Lexend (font variabile) 5.3.0.

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

Testing

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