Skip to content
animorio
IT
All components

The 3D printer loader

Loading, 3D, SVG, TransitionsCanvas, GSAPAdvancedCompressed weight: Demo 23 KBGSAP 28 KBFreeDownload the zip

A model export made as a small 3D printer seen from the front: press Export model and the plate comes up to the nozzle and the printer builds a twisted vase layer after layer. The nozzle runs along the layer, the fresh plastic is orange and cools through red and purple into the filament’s blue, the plate drops a layer at every lap and the spool turns. The vase is the progress; at the end the head parks, the plate comes down to you and a glint runs across the vase.

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, viewport-fit=cover">
  <title>The 3D printer loader</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/instrument-sans@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the 3D printer loader: the export of a model from a 3D modelling app, shown as a small printer seen from the
         front and a little from above. Pressed, the plate comes up to the nozzle, a purge line is laid along its
         front edge and a twisted vase is printed layer after layer: the nozzle runs round the current layer, the
         fresh plastic glows orange behind it and cools into the colour of the filament, the plate goes down a layer
         at every lap and the spool turns a little. The vase is the progress. The printer is drawn by script.js -->
    <section class="printer" aria-label="Model export" data-printer>
      <!-- four layers: the frame's back and the plate; the vase; the gantry and the print head; the frame's front,
           the spool and the tube -->
      <div class="printer__scene" role="progressbar" aria-label="Model export" aria-valuemin="0" aria-valuemax="100"
           aria-valuenow="0" aria-valuetext="Ready to export" data-scene>
        <svg class="printer__art" viewBox="0 6 300 256" aria-hidden="true" data-art="back"></svg>
        <canvas class="printer__art" aria-hidden="true" data-paint></canvas>
        <svg class="printer__art" viewBox="0 6 300 256" aria-hidden="true" data-art="head"></svg>
        <svg class="printer__art" viewBox="0 6 300 256" aria-hidden="true" data-art="front"></svg>
      </div>
      <p class="printer__status" aria-hidden="true">
        <svg class="printer__icon" viewBox="0 0 24 24" data-icon><path d="M5.5 12.6l4.2 4.2 8.8-9.4" pathLength="1"/></svg>
        <span class="printer__swap" data-status>Ready to export</span>
        <span class="printer__pct" data-pct></span>
        <span class="printer__left" data-left></span>
      </p>
      <div class="printer__buttons">
        <button class="pill is-quiet" type="button" hidden data-again><span class="pill__label">Export again</span></button>
        <button class="pill" type="button" data-go data-autoclic><span class="pill__label" data-label>Export model</span></button>
      </div>
      <p class="sr" role="status" aria-live="polite" data-live></p>
    </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.

47 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 3D printer loader” from Animorio and fit it into my site

What it does

On a white background, alone in the middle, a small 3D printer seen from the front and a little from above: a frame of black aluminium extrusions on a base with air vents and a knob, two lead screws at the back, at the top the gantry with its beam and carriage, and on the carriage the print head: the extruder motor with its gear, the light shroud with the little fan, the two air ducts, the heater block in its silicone sock and the brass nozzle. Below is the build plate, a gold textured sheet; next to it, on a stand, the spool of blue filament, joined to the head by a PTFE tube where the filament shows. Under it, the line Ready to export and the Export model button. Pointing at the button makes the head lean out of its corner and the fan start to turn. Pressed, the plate comes up to the nozzle while the head goes to the front left, the nozzle lays a purge line along the plate’s edge and then the vase begins: first the solid bottom, with the nozzle going back and forth in a zigzag, then the wall, one lap a layer. The bead just laid is nearly white under the nozzle, then orange, and it cools through red and purple into the filament’s blue, with a warm glow along the laps just made; at every lap, behind the vase, the plate drops a layer, and before every travel (from the purge line to the vase, between the two bottom layers) the head retracts the filament, which you see go back in the tube. The vase grows on the plate in thin layers, its ribs turning as they rise and the layer lines a fine texture; the line says Exporting model 54% · about 3 s left, the spool turns and from the second layer the fan runs at full speed. At the end the head retracts and goes back to its corner, the plate comes down to you, the fan slows down, a glint crosses the vase on a slant and the line becomes Model ready with a green tick, next to Download .stl and Export again. Cancel stops the printer where it is: the head parks, the unfinished piece stays on the plate and cools, and Canceled at 41% appears with Try again. Try again and Export again lift the piece off the plate, where it disappears, and the print starts over.

How it works

A parallel view, a little from above

Every point of the printer has three coordinates (x to the right, y towards you, z up) and lands in the drawing at x, −z·cos e + y·sin e, with sin e = 0.24: the printer is seen from 14 degrees above, with no perspective. So the plate is a squashed rectangle, the top of the frame a ring and the nozzle’s lap an ellipse. The frame, the plate, the head and the spool are SVG drawn once only; every frame the plate, the beam and the head move, the fan turns (and at speed becomes a blurred disc), the extruder’s gear turns, the tube is drawn again as a Bézier curve down to the head and the filament inside it runs with a dash pattern.

The profile and the twisted ribs

The vase’s profile is a smooth curve (cubic Hermite) through the points of PROFILE and gives the radius R at every height. The outline at every height is r(θ) = R·(1 + d·cos(n·(θ − φ))), with n ribs of depth d, and φ growing with the height up to TWIST: the ribs turn as they rise. Every layer is a band from the outline at its bottom to the outline at its top, so the side of the vase runs on without steps and the layers, 2.5 units tall (under 3 pixels), are left as a fine texture. The two bottom layers are solid: lines at 45 degrees, then the other way, clipped to the outline by intersecting a line with a 96 sided polygon.

The nozzle’s path, move by move

The path is a list of real moves: the plate coming up, the priming, the purge line and then, before every travel, the retraction, the plate dropping a little more (the hop), the travel, coming back down and the filament pushed back; in the bottom the zigzag, and the first layer at half speed so it sticks to the plate. Every lap starts at the back, where the twist has brought it, and there the plate drops a layer while the head slides a few degrees: no travels between one lap and the next. The fixed moves keep their time, the printing ones share what is left of SECONDS by their length. From there come the place of the head and of the plate at every moment, the percentage (the time done over the path’s time) and the time left.

Every layer, slice by slice

Every lap is cut into 120 slices. For each one the surface’s normal comes from the radius, its derivative along the lap (the ribs) and the slope of the profile; the light is diffuse (Lambert), darker towards the edges, with a narrow upright shine that follows the ribs. The light wraps a little round the ribs, so their shaded side is soft. It is painted in two passes: first the bottom and the inside of the back wall, seen through the opening, then the front walls from the bottom up and the rim on top. Over each bead a line of light, stronger on the lit side, under it a light shade and the fine crease where it sits on the layer below: those are the raised layer lines.

The heat that cools

Every slice knows the moment the nozzle laid it, so its heat is T = e^(−age ÷ COOL). The colour follows a thermal camera’s scale: nearly white, orange, red, purple and the filament’s colour; the hotter it is the less it is shaded, because it glows by itself. Along the hot part of the last two layers an orange glow is added (lighter). When the print is canceled the path stops but the clock does not, and the piece left on the plate cools all the same.

Only when needed, and those who cannot see

A finished, cold layer is added once only to two pictures of their own (the two passes); the plate moves in whole pixels of the canvas, so the pictures follow it without blurring, and every frame only the layers still warm are painted. When nothing moves and nothing is hot, the loop does not draw. The drawing is a role=progressbar with aria-valuenow and aria-valuetext («54 percent, about 6 seconds left») at most every 0.6 seconds, aria-busy while it prints and an aria-live line for the start, the cancel, the end and the download. Clicks from a script (the library preview’s) never cancel or download: once the print is done, after 2.5 seconds, they start it again.

Values to change

NameFileDefaultWhat it changes
SECONDSscript.js7How long the demo’s print takes, in seconds, from the plate coming up to the last lap (a real export follows the app’s work).
LAYERSscript.js36The vase’s layers, the two solid ones at the bottom included: more layers, finer lines and more laps of the nozzle, which goes faster.
PROFILEscript.js[[0, 19], [0.14, 24], [0.4, 32], …]The vase’s profile: for every point at what height (from 0, the foot, to 1, the rim) and the radius in drawing units (the plate is 148 wide).
RIBSscript.js8The vase’s ribs; 0 makes it smooth.
RIB_DEPTHscript.js0.04How far the ribs stand out, as a share of the radius.
TWISTscript.js80How many degrees the ribs turn from the foot to the rim; a negative number turns them the other way.
COOLscript.js0.35In how many seconds the fresh plastic loses nearly two thirds of its heat: the higher it is, the more layers stay lit under the nozzle.
LABELSscript.js{ busy: 'Cancel', done: 'Download .stl', saved: 'Downloaded', retry: 'Try again' }The button’s words while it prints, at the end, once downloaded and after a cancel; the one at rest, Export model, is changed in index.html.
WORDSscript.js{ warm: 'Warming up', busy: 'Exporting model', done: 'Model ready', canceled: 'Canceled at' }The line under the printer while it warms up, while it prints (followed by the percentage and the time left), at the end and after a cancel (followed by the percentage); the one at rest, Ready to export, is changed in index.html.

Try them in the Playground

When to use it

For a wait of a few seconds that ends with an object in hand: exporting a model from a 3D modelling or CAD app, generating a mesh or an object with AI, preparing an STL or 3MF file, a slicer’s work. It suits a product for makers, product designers or 3D printing studios, where the printer says at once what this is about and the vase says how far along things are even without reading the number. For a very short wait, or one that produces nothing to keep, it is too much.

On phones

The drawing is 330 pixels wide and fits whole on a phone (at 390, 16 pixels are left on each side); it is vector, so it stays sharp at any density, and the vase’s canvas paints at the screen’s real density, up to twice. The status stays on one line. The buttons are pills 44 tall: under a finger they squash and spring back; the pill that swells, the words that widen and the head that leans out on the way past are there only with the mouse (the head also with the keyboard).

With reduced motion

The head stays in its corner and the plate still at its end of print position; the fan, the extruder’s gear and the spool do not turn, no glow and no glint at the end. The vase grows all the same, because it is what says how far along things are: it comes in six steps, each fading in over the one before and always with a whole lap on top, already in the filament’s colour. The percentage and the time left update, the words change with a fade and the tick appears without drawing itself.

Pitfalls

  • With 72 slices a lap and a very narrow shine the twisted ribs came out as a checkerboard, like a vase made of pixels: there are now 120 slices, the shine is wider and softer and the ribs stand out a little less.
  • With 22 layers 4 units tall, each with its own radius, the finished vase looked like a stack of plates and its outline was a staircase; where a layer was set back even the white showed between the two: there are now 36 layers 2.5 units tall, and every band goes from the outline at its bottom to the outline at its top, so the side runs smooth and the lines are left as a fine texture.
  • The ribs had irregular dark patches that looked like holes: they now stand out a little less and the light wraps round them (the product with the light is shifted by 0.3 before it is cut at zero), so the shaded side is soft.
  • With a seam scattered by the golden angle the head jumped from one side of the vase to the other at every layer, with a retraction and a hop: with 36 layers in 7 seconds it was frantic and the fixed times ate half the print. Every lap now starts where the twist brought the one before, the plate drops a layer there, and the retraction and the travel stay where they are needed: from the purge line to the vase, between the two bottom layers and at the end.
  • With thin layers nearly the whole vase stayed warm and was painted whole every frame: a cold layer is now added once only to the two pictures kept aside, and the plate moves in whole pixels of the canvas so that the pictures, moved with it, do not blur.
  • The line of light along every bead was the same all round and on the shaded side it looked like a crack: it is now a gradient, strong on the lit side and next to nothing on the other.
  • The colour between the orange and the blue was a bright pink and the vase looked like chewing gum: it is now a red, and between the red and the blue a purple comes by itself, as in a thermal camera.
  • The purge line, long and thick on the plate’s edge, looked like a progress bar once it was cold: it is now short and low.
  • The glint at the end was wide and hardly slanted and nobody noticed it; narrow and strong it looked like a white smear: it is now a soft slanting band that crosses the vase in a second.
  • With reduced motion a step could fall half way round a lap and leave a notch in the rim: every step now ends with the last whole lap.
  • There was a gap between the percentage and the time left, because the number had a minimum width: the figures are now tabular and that is enough.

Libraries

GSAP 3.15.0, Instrument Sans (font variabile) 5.3.0.

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

Testing

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