A cartesian gantry robot moves only along its three axes: the bridge rolls in x, the carriage in y, the z-axis drops, grips the accent part and sets it on a fixture across the table.
Also known as: pick and place animation, robot arm animation, isometric factory, hairline animation.
<div class="hln-gantry-picker" role="img" aria-label="A gantry robot picks a part and places it on a fixture"><svg viewBox="-52 -25.77 122 66.55" aria-hidden="true"><g><polygon points="-38,15 18,43 18,42 -38,14"/><polygon points="56,24 18,43 18,42 56,23"/><polygon points="0,-5 56,23 18,42 -38,14"/></g><g><polygon points="-30,14 18,38 18,33 -30,9"/><polygon points="48,23 18,38 18,33 48,18"/><polygon points="0,-6 48,18 18,33 -30,9"/></g><line x1="6" y1="-3" x2="-24" y2="12" class="hln-gantry-picker-l"/><line x1="12" y1="0" x2="-18" y2="15" class="hln-gantry-picker-l"/><line x1="18" y1="3" x2="-12" y2="18" class="hln-gantry-picker-l"/><line x1="24" y1="6" x2="-6" y2="21" class="hln-gantry-picker-l"/><line x1="30" y1="9" x2="0" y2="24" class="hln-gantry-picker-l"/><line x1="36" y1="12" x2="6" y2="27" class="hln-gantry-picker-l"/><line x1="42" y1="15" x2="12" y2="30" class="hln-gantry-picker-l"/><g><polygon points="-2,-4 0,-3 0,-21 -2,-22"/><polygon points="2,-4 0,-3 0,-21 2,-22"/><polygon points="0,-23 2,-22 0,-21 -2,-22"/></g><g><polygon points="42,18 44,19 44,1 42,0"/><polygon points="46,18 44,19 44,1 46,0"/><polygon points="44,-1 46,0 44,1 42,0"/></g><g><polygon points="-3,-22.5 45,1.5 45,0 -3,-24"/><polygon points="47.5,0.25 45,1.5 45,0 47.5,-1.25"/><polygon points="-0.5,-25.25 47.5,-1.25 45,0 -3,-24"/></g><polygon class="hln-gantry-picker-l" points="-1,-0.5 8,4 0,8 -9,3.5"/><g><polygon points="8.5,21.75 15.5,25.25 15.5,24.65 8.5,21.15"/><polygon points="22.5,21.75 15.5,25.25 15.5,24.65 22.5,21.15"/><polygon points="15.5,17.65 22.5,21.15 15.5,24.65 8.5,21.15"/></g><g class="hln-gantry-picker-part"><g class="hln-gantry-picker-pop"><g class="hln-gantry-picker-a"><polygon points="-4.5,3.75 -0.5,5.75 -0.5,1.75 -4.5,-0.25"/><polygon points="3.5,3.75 -0.5,5.75 -0.5,1.75 3.5,-0.25"/><polygon points="-0.5,-2.25 3.5,-0.25 -0.5,1.75 -4.5,-0.25"/></g></g></g><g><polygon points="-29.5,-9.25 18.5,14.75 18.5,13.25 -29.5,-10.75"/><polygon points="21,13.5 18.5,14.75 18.5,13.25 21,12"/><polygon points="-27,-12 21,12 18.5,13.25 -29.5,-10.75"/></g><g class="hln-gantry-picker-bx"><g><polygon points="-26,-8.5 -22,-6.5 -22,-8.5 -26,-10.5"/><polygon points="8,-21.5 -22,-6.5 -22,-8.5 8,-23.5"/><polygon points="4,-25.5 8,-23.5 -22,-8.5 -26,-10.5"/></g><g class="hln-gantry-picker-cy"><g class="hln-gantry-picker-bz"><g><polygon points="-2.5,-0.25 -0.5,0.75 -0.5,-12.25 -2.5,-13.25"/><polygon points="1.5,-0.25 -0.5,0.75 -0.5,-12.25 1.5,-13.25"/><polygon points="-0.5,-14.25 1.5,-13.25 -0.5,-12.25 -2.5,-13.25"/></g><g><polygon points="-4.4,0 0.2,2.3 0.2,1.5 -4.4,-0.8"/><polygon points="3.4,0.7 0.2,2.3 0.2,1.5 3.4,-0.1"/><polygon points="-1.2,-2.4 3.4,-0.1 0.2,1.5 -4.4,-0.8"/></g></g><g><polygon points="-4.5,-8.75 -1,-7 -1,-14 -4.5,-15.75"/><polygon points="4,-9.5 -1,-7 -1,-14 4,-16.5"/><polygon points="0.5,-18.25 4,-16.5 -1,-14 -4.5,-15.75"/></g></g></g><g><polygon points="-28,9 -26,10 -26,-8 -28,-9"/><polygon points="-24,9 -26,10 -26,-8 -24,-9"/><polygon points="-26,-10 -24,-9 -26,-8 -28,-9"/></g><g><polygon points="16,31 18,32 18,14 16,13"/><polygon points="20,31 18,32 18,14 20,13"/><polygon points="18,12 20,13 18,14 16,13"/></g></svg></div>
.hln-gantry-picker {
--c: var(--hln-color, #ff4f2e);
font-size: var(--hln-size, 16px);
position: relative;
display: grid;
place-items: center;
width: 22em;
height: 12em;
border-radius: 0.75em;
background: #f6f5f1;
overflow: hidden;
--u: 1px;
}
.hln-gantry-picker svg {
width: 100%;
height: 100%;
overflow: visible;
fill: #ffffff;
stroke: #1c1d21;
stroke-width: 1.25;
stroke-linejoin: round;
stroke-linecap: round;
}
.hln-gantry-picker svg * {
vector-effect: non-scaling-stroke;
}
.hln-gantry-picker-l {
stroke: #9a9ca3;
}
.hln-gantry-picker-a {
fill: var(--c);
}
.hln-gantry-picker-bx {
animation: hln-gantry-picker-bx 6s linear infinite;
}
.hln-gantry-picker-cy {
animation: hln-gantry-picker-cy 6s linear infinite;
}
.hln-gantry-picker-bz {
animation: hln-gantry-picker-bz 6s linear infinite;
}
.hln-gantry-picker-part {
animation: hln-gantry-picker-part 6s linear infinite;
}
.hln-gantry-picker-pop {
transform-box: fill-box;
transform-origin: 50% 100%;
animation: hln-gantry-picker-pop 6s linear infinite;
}
@keyframes hln-gantry-picker-bx {
0% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
8% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
12% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
22% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
34% { transform: translate(calc(var(--u) * 26), calc(var(--u) * 13)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
42% { transform: translate(calc(var(--u) * 26), calc(var(--u) * 13)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
50% { transform: translate(calc(var(--u) * 26), calc(var(--u) * 13)); }
54% { transform: translate(calc(var(--u) * 26), calc(var(--u) * 13)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
62% { transform: translate(calc(var(--u) * 26), calc(var(--u) * 13)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
70% { transform: translate(calc(var(--u) * 26), calc(var(--u) * 13)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
80% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
100% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
}
@keyframes hln-gantry-picker-cy {
0% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
8% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
12% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
22% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
34% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
42% { transform: translate(calc(var(--u) * -10), calc(var(--u) * 5)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
50% { transform: translate(calc(var(--u) * -10), calc(var(--u) * 5)); }
54% { transform: translate(calc(var(--u) * -10), calc(var(--u) * 5)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
62% { transform: translate(calc(var(--u) * -10), calc(var(--u) * 5)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
70% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
80% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
100% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
}
@keyframes hln-gantry-picker-bz {
0% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
8% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
12% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
22% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
34% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
42% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
50% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
54% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
62% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
70% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
80% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); }
100% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); }
}
@keyframes hln-gantry-picker-part {
0% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
8% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
12% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
22% { transform: translate(calc(var(--u) * 0), calc(var(--u) * -8)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
34% { transform: translate(calc(var(--u) * 26), calc(var(--u) * 5)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
42% { transform: translate(calc(var(--u) * 16), calc(var(--u) * 10)); animation-timing-function: cubic-bezier(.4, 0, .3, 1.1); }
50% { transform: translate(calc(var(--u) * 16), calc(var(--u) * 18)); }
54% { transform: translate(calc(var(--u) * 16), calc(var(--u) * 18)); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
89.9% { transform: translate(calc(var(--u) * 16), calc(var(--u) * 18)); }
90%, 100% { transform: translate(calc(var(--u) * 0), calc(var(--u) * 0)); }
}
@keyframes hln-gantry-picker-pop {
0%, 84% { transform: scale(1); opacity: 1; animation-timing-function: ease-in; }
90% { transform: scale(1); opacity: 0; }
90.1% { transform: scale(0); opacity: 1; animation-timing-function: cubic-bezier(.3, 1.45, .5, 1); }
97%, 100% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.hln-gantry-picker * {
animation-play-state: paused !important;
animation-delay: calc(var(--delay, 0s) - 3.4s) !important;
}
}
@media (prefers-reduced-motion: reduce) {
.hln-gantry-picker, .hln-gantry-picker *, .hln-gantry-picker::before, .hln-gantry-picker::after, .hln-gantry-picker *::before, .hln-gantry-picker *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hln-color on the element or a parent.
Currently previewing #3b82f6.--hln-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.