AI CSS Animations

Robot Arm Pick and Place

An isometric hairline robot arm lowers onto the accent part, grips it, swings it across on a soft spring and sets it down on the far pad. Two @property joint angles and CSS trig drive the arm.

Also known as: hairline animation, isometric robot arm, pick and place animation css, hairline claude.

HTML

<div class="hln-robot-arm-pick" role="img" aria-label="A robot arm moving a part between two pads">
  <svg viewBox="-110 -60 220 120" aria-hidden="true">
    <g transform="translate(0 15) scale(1.15)">
      <g><polygon points="-40,-15 -30,-10 -30,-12 -40,-17"/><polygon points="-20,-15 -30,-10 -30,-12 -20,-17"/><polygon points="-30,-22 -20,-17 -30,-12 -40,-17"/></g>
      <g><polygon points="20,15 30,20 30,18 20,13"/><polygon points="40,15 30,20 30,18 40,13"/><polygon points="30,8 40,13 30,18 20,13"/></g>
      <g><path d="M-14.14,-4 V0 A14.14,7.07 0 0 0 14.14,0 V-4 Z"/><ellipse cx="0" cy="-4" rx="14.14" ry="7.07"/></g>
      <g><path d="M-9.19,-11 V-4 A9.19,4.6 0 0 0 9.19,-4 V-11 Z"/><ellipse cx="0" cy="-11" rx="9.19" ry="4.6"/></g>
      <g transform="matrix(1 .5 0 -1 3.2 -17.6)"><g class="hln-robot-arm-pick-s"><rect x="-3" y="-3" width="30" height="6" rx="3"/><circle class="hln-robot-arm-pick-l" cx="0" cy="0" r="1.6"/><g transform="translate(24 0)"><g class="hln-robot-arm-pick-e"><rect x="-2.6" y="-2.6" width="27.2" height="5.2" rx="2.6"/><circle class="hln-robot-arm-pick-l" cx="0" cy="0" r="1.4"/><g transform="translate(22 0)"><g class="hln-robot-arm-pick-w"><rect x="-6.4" y="-1.2" width="12.8" height="2.4" rx="0.8"/><g class="hln-robot-arm-pick-fl"><rect x="-6" y="-8" width="1.6" height="7.4" rx="0.6"/></g><g class="hln-robot-arm-pick-fr"><rect x="4.4" y="-8" width="1.6" height="7.4" rx="0.6"/></g></g></g></g></g></g></g>
      <g class="hln-robot-arm-pick-pa"><g class="hln-robot-arm-pick-a"><polygon points="-36,-17 -30,-14 -30,-20 -36,-23"/><polygon points="-24,-17 -30,-14 -30,-20 -24,-23"/><polygon points="-30,-26 -24,-23 -30,-20 -36,-23"/></g></g>
      <g class="hln-robot-arm-pick-pb"><g class="hln-robot-arm-pick-a"><polygon points="24,13 30,16 30,10 24,7"/><polygon points="36,13 30,16 30,10 36,7"/><polygon points="30,4 36,7 30,10 24,7"/></g></g>
      <g><polygon points="-5,-10.3 -1.4,-8.5 -1.4,-11.9 -5,-13.7"/><polygon points="5,-11.7 -1.4,-8.5 -1.4,-11.9 5,-15.1"/><polygon points="1.4,-16.9 5,-15.1 -1.4,-11.9 -5,-13.7"/></g>
      <g transform="matrix(1 .5 0 -1 -3.2 -14.4)"><g class="hln-robot-arm-pick-s"><rect x="-3" y="-3" width="30" height="6" rx="3"/><circle class="hln-robot-arm-pick-l" cx="0" cy="0" r="1.6"/><g transform="translate(24 0)"><g class="hln-robot-arm-pick-e"><rect x="-2.6" y="-2.6" width="27.2" height="5.2" rx="2.6"/><circle class="hln-robot-arm-pick-l" cx="0" cy="0" r="1.4"/><g transform="translate(22 0)"><g class="hln-robot-arm-pick-w"><rect x="-6.4" y="-1.2" width="12.8" height="2.4" rx="0.8"/><g class="hln-robot-arm-pick-held" transform="matrix(1 .5 0 -1 0 0)"><g transform="translate(3.2 8.4)"><g class="hln-robot-arm-pick-a"><polygon points="-6,0 0,3 0,-3 -6,-6"/><polygon points="6,0 0,3 0,-3 6,-6"/><polygon points="0,-9 6,-6 0,-3 -6,-6"/></g></g></g><g class="hln-robot-arm-pick-fl"><rect x="-6" y="-8" width="1.6" height="7.4" rx="0.6"/></g><g class="hln-robot-arm-pick-fr"><rect x="4.4" y="-8" width="1.6" height="7.4" rx="0.6"/></g></g></g></g></g></g></g>
    </g>
  </svg>
</div>

CSS

.hln-robot-arm-pick {
  --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;
}
.hln-robot-arm-pick svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: #ffffff;
  stroke: #1c1d21;
  stroke-width: 1.25;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.hln-robot-arm-pick svg * {
  vector-effect: non-scaling-stroke;
}
.hln-robot-arm-pick .hln-robot-arm-pick-l {
  stroke: #9a9ca3;
}
.hln-robot-arm-pick .hln-robot-arm-pick-w {
  fill: #ffffff;
  stroke: none;
}
.hln-robot-arm-pick .hln-robot-arm-pick-a {
  stroke: var(--c);
}
@property --hln-robot-arm-pick-a {
  syntax: "<angle>";
  inherits: true;
  initial-value: 144.56deg;
}
@property --hln-robot-arm-pick-b {
  syntax: "<angle>";
  inherits: true;
  initial-value: -117.28deg;
}
.hln-robot-arm-pick svg {
  animation: hln-robot-arm-pick-move 6s infinite;
}
.hln-robot-arm-pick .hln-robot-arm-pick-s {
  transform: rotate(var(--hln-robot-arm-pick-a));
}
.hln-robot-arm-pick .hln-robot-arm-pick-e {
  transform: rotate(var(--hln-robot-arm-pick-b));
}
.hln-robot-arm-pick .hln-robot-arm-pick-w {
  transform: rotate(calc(-1 * (var(--hln-robot-arm-pick-a) + var(--hln-robot-arm-pick-b))));
}
.hln-robot-arm-pick .hln-robot-arm-pick-held {
  opacity: 0;
  animation: hln-robot-arm-pick-held 6s infinite;
}
.hln-robot-arm-pick .hln-robot-arm-pick-pa {
  animation: hln-robot-arm-pick-pa 6s infinite;
}
.hln-robot-arm-pick .hln-robot-arm-pick-pb {
  opacity: 0;
  animation: hln-robot-arm-pick-pb 6s infinite;
}
.hln-robot-arm-pick .hln-robot-arm-pick-fl {
  animation: hln-robot-arm-pick-fl 6s infinite;
}
.hln-robot-arm-pick .hln-robot-arm-pick-fr {
  animation: hln-robot-arm-pick-fr 6s infinite;
}
@keyframes hln-robot-arm-pick-move {
  0% { --hln-robot-arm-pick-a: 144.56deg; --hln-robot-arm-pick-b: -117.28deg; }
  3.33% { --hln-robot-arm-pick-a: 144.56deg; --hln-robot-arm-pick-b: -117.28deg; }
  4.67% { --hln-robot-arm-pick-a: 35.64deg; --hln-robot-arm-pick-b: 117.49deg; }
  6% { --hln-robot-arm-pick-a: 37.11deg; --hln-robot-arm-pick-b: 118.9deg; }
  7.33% { --hln-robot-arm-pick-a: 41.75deg; --hln-robot-arm-pick-b: 122.22deg; }
  8.67% { --hln-robot-arm-pick-a: 53.37deg; --hln-robot-arm-pick-b: 126.29deg; }
  10% { --hln-robot-arm-pick-a: 77.16deg; --hln-robot-arm-pick-b: 125.29deg; }
  11.33% { --hln-robot-arm-pick-a: 100.91deg; --hln-robot-arm-pick-b: 115.18deg; }
  12.67% { --hln-robot-arm-pick-a: 114.02deg; --hln-robot-arm-pick-b: 105.42deg; }
  14% { --hln-robot-arm-pick-a: 120.45deg; --hln-robot-arm-pick-b: 99.45deg; }
  15.33% { --hln-robot-arm-pick-a: 122.79deg; --hln-robot-arm-pick-b: 97.09deg; }
  16.67% { --hln-robot-arm-pick-a: 123.12deg; --hln-robot-arm-pick-b: 96.74deg; }
  16.67% { --hln-robot-arm-pick-a: 123.12deg; --hln-robot-arm-pick-b: 96.74deg; }
  17.33% { --hln-robot-arm-pick-a: 123.18deg; --hln-robot-arm-pick-b: 96.77deg; }
  18% { --hln-robot-arm-pick-a: 123.62deg; --hln-robot-arm-pick-b: 96.95deg; }
  18.67% { --hln-robot-arm-pick-a: 124.82deg; --hln-robot-arm-pick-b: 97.39deg; }
  19.33% { --hln-robot-arm-pick-a: 127.29deg; --hln-robot-arm-pick-b: 98.07deg; }
  20% { --hln-robot-arm-pick-a: 131.66deg; --hln-robot-arm-pick-b: 98.66deg; }
  20.67% { --hln-robot-arm-pick-a: -223.66deg; --hln-robot-arm-pick-b: 98.6deg; }
  21.33% { --hln-robot-arm-pick-a: -220.69deg; --hln-robot-arm-pick-b: 98.25deg; }
  22% { --hln-robot-arm-pick-a: -219.13deg; --hln-robot-arm-pick-b: 97.97deg; }
  22.67% { --hln-robot-arm-pick-a: -218.55deg; --hln-robot-arm-pick-b: 97.85deg; }
  23.33% { --hln-robot-arm-pick-a: -218.47deg; --hln-robot-arm-pick-b: 97.84deg; }
  27.5% { --hln-robot-arm-pick-a: -218.47deg; --hln-robot-arm-pick-b: 97.84deg; }
  28.17% { --hln-robot-arm-pick-a: -218.55deg; --hln-robot-arm-pick-b: 97.85deg; }
  28.83% { --hln-robot-arm-pick-a: -219.13deg; --hln-robot-arm-pick-b: 97.97deg; }
  29.5% { --hln-robot-arm-pick-a: -220.69deg; --hln-robot-arm-pick-b: 98.25deg; }
  30.17% { --hln-robot-arm-pick-a: -223.66deg; --hln-robot-arm-pick-b: 98.6deg; }
  30.83% { --hln-robot-arm-pick-a: 131.66deg; --hln-robot-arm-pick-b: 98.66deg; }
  31.5% { --hln-robot-arm-pick-a: 127.29deg; --hln-robot-arm-pick-b: 98.07deg; }
  32.17% { --hln-robot-arm-pick-a: 124.82deg; --hln-robot-arm-pick-b: 97.39deg; }
  32.83% { --hln-robot-arm-pick-a: 123.62deg; --hln-robot-arm-pick-b: 96.95deg; }
  33.5% { --hln-robot-arm-pick-a: 123.18deg; --hln-robot-arm-pick-b: 96.77deg; }
  34.17% { --hln-robot-arm-pick-a: 123.12deg; --hln-robot-arm-pick-b: 96.74deg; }
  34.17% { --hln-robot-arm-pick-a: 123.12deg; --hln-robot-arm-pick-b: 96.74deg; }
  36% { --hln-robot-arm-pick-a: 85.01deg; --hln-robot-arm-pick-b: 128.8deg; }
  37.83% { --hln-robot-arm-pick-a: 134.58deg; --hln-robot-arm-pick-b: -143.23deg; }
  39.67% { --hln-robot-arm-pick-a: 83.93deg; --hln-robot-arm-pick-b: -121.5deg; }
  41.5% { --hln-robot-arm-pick-a: 62.83deg; --hln-robot-arm-pick-b: -103.04deg; }
  43.33% { --hln-robot-arm-pick-a: 55.09deg; --hln-robot-arm-pick-b: -94.75deg; }
  45.17% { --hln-robot-arm-pick-a: 53.69deg; --hln-robot-arm-pick-b: -93.17deg; }
  47% { --hln-robot-arm-pick-a: 54.53deg; --hln-robot-arm-pick-b: -94.12deg; }
  48.83% { --hln-robot-arm-pick-a: 55.64deg; --hln-robot-arm-pick-b: -95.37deg; }
  50.67% { --hln-robot-arm-pick-a: 56.4deg; --hln-robot-arm-pick-b: -96.22deg; }
  52.5% { --hln-robot-arm-pick-a: 56.88deg; --hln-robot-arm-pick-b: -96.74deg; }
  52.5% { --hln-robot-arm-pick-a: 56.88deg; --hln-robot-arm-pick-b: -96.74deg; }
  53.17% { --hln-robot-arm-pick-a: 56.82deg; --hln-robot-arm-pick-b: -96.77deg; }
  53.83% { --hln-robot-arm-pick-a: 56.38deg; --hln-robot-arm-pick-b: -96.95deg; }
  54.5% { --hln-robot-arm-pick-a: 55.18deg; --hln-robot-arm-pick-b: -97.39deg; }
  55.17% { --hln-robot-arm-pick-a: 52.71deg; --hln-robot-arm-pick-b: -98.07deg; }
  55.83% { --hln-robot-arm-pick-a: 48.34deg; --hln-robot-arm-pick-b: -98.66deg; }
  56.5% { --hln-robot-arm-pick-a: 43.66deg; --hln-robot-arm-pick-b: -98.6deg; }
  57.17% { --hln-robot-arm-pick-a: 40.69deg; --hln-robot-arm-pick-b: -98.25deg; }
  57.83% { --hln-robot-arm-pick-a: 39.13deg; --hln-robot-arm-pick-b: -97.97deg; }
  58.5% { --hln-robot-arm-pick-a: 38.55deg; --hln-robot-arm-pick-b: -97.85deg; }
  59.17% { --hln-robot-arm-pick-a: 38.47deg; --hln-robot-arm-pick-b: -97.84deg; }
  63.33% { --hln-robot-arm-pick-a: 38.47deg; --hln-robot-arm-pick-b: -97.84deg; }
  64% { --hln-robot-arm-pick-a: 38.55deg; --hln-robot-arm-pick-b: -97.85deg; }
  64.67% { --hln-robot-arm-pick-a: 39.13deg; --hln-robot-arm-pick-b: -97.97deg; }
  65.33% { --hln-robot-arm-pick-a: 40.69deg; --hln-robot-arm-pick-b: -98.25deg; }
  66% { --hln-robot-arm-pick-a: 43.66deg; --hln-robot-arm-pick-b: -98.6deg; }
  66.67% { --hln-robot-arm-pick-a: 48.34deg; --hln-robot-arm-pick-b: -98.66deg; }
  67.33% { --hln-robot-arm-pick-a: 52.71deg; --hln-robot-arm-pick-b: -98.07deg; }
  68% { --hln-robot-arm-pick-a: 55.18deg; --hln-robot-arm-pick-b: -97.39deg; }
  68.67% { --hln-robot-arm-pick-a: 56.38deg; --hln-robot-arm-pick-b: -96.95deg; }
  69.33% { --hln-robot-arm-pick-a: 56.82deg; --hln-robot-arm-pick-b: -96.77deg; }
  70% { --hln-robot-arm-pick-a: 56.88deg; --hln-robot-arm-pick-b: -96.74deg; }
  70% { --hln-robot-arm-pick-a: 56.88deg; --hln-robot-arm-pick-b: -96.74deg; }
  71.33% { --hln-robot-arm-pick-a: 76.73deg; --hln-robot-arm-pick-b: -113.66deg; }
  72.67% { --hln-robot-arm-pick-a: 111.1deg; --hln-robot-arm-pick-b: -126.71deg; }
  74% { --hln-robot-arm-pick-a: 133.99deg; --hln-robot-arm-pick-b: -124.24deg; }
  75.33% { --hln-robot-arm-pick-a: 142.6deg; --hln-robot-arm-pick-b: -119.16deg; }
  76.67% { --hln-robot-arm-pick-a: 36.49deg; --hln-robot-arm-pick-b: 116.68deg; }
  78% { --hln-robot-arm-pick-a: 37.29deg; --hln-robot-arm-pick-b: 116.21deg; }
  79.33% { --hln-robot-arm-pick-a: 36.81deg; --hln-robot-arm-pick-b: 116.49deg; }
  80.67% { --hln-robot-arm-pick-a: 36.17deg; --hln-robot-arm-pick-b: 116.87deg; }
  82% { --hln-robot-arm-pick-a: 35.72deg; --hln-robot-arm-pick-b: 117.12deg; }
  83.33% { --hln-robot-arm-pick-a: 144.56deg; --hln-robot-arm-pick-b: -117.28deg; }
  100% { --hln-robot-arm-pick-a: 144.56deg; --hln-robot-arm-pick-b: -117.28deg; }
}
@keyframes hln-robot-arm-pick-held {
  0% { opacity: 0; }
  25% { opacity: 0; }
  25.17% { opacity: 1; }
  60.83% { opacity: 1; }
  61% { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes hln-robot-arm-pick-pa {
  0% { transform: matrix(1, 0, 0, 1, 0, 0); opacity: 1; }
  25% { transform: matrix(1, 0, 0, 1, 0, 0); opacity: 1; }
  25.17% { transform: matrix(1, 0, 0, 1, 0, 0); opacity: 0; }
  88.33% { transform: matrix(1, 0, 0, 1, 0, -10); opacity: 0; animation-timing-function: cubic-bezier(.22,1,.36,1); }
  90.83% { transform: matrix(1, 0, 0, 1, 0, -4); opacity: 1; animation-timing-function: cubic-bezier(.55,0,.85,.3); }
  94.17% { transform: matrix(1, 0, 0, 1, 0, 0); opacity: 1; }
  100% { transform: matrix(1, 0, 0, 1, 0, 0); opacity: 1; }
}
@keyframes hln-robot-arm-pick-pb {
  0% { opacity: 0; }
  60.83% { opacity: 0; }
  61% { opacity: 1; }
  81.67% { opacity: 1; }
  86.67% { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes hln-robot-arm-pick-fl {
  0% { transform: matrix(1, 0, 0, 1, 0, 0); }
  23.33% { transform: matrix(1, 0, 0, 1, 0, 0); animation-timing-function: cubic-bezier(.65,0,.35,1); }
  25.83% { transform: matrix(1, 0, 0, 1, 1.4, 0); }
  59.17% { transform: matrix(1, 0, 0, 1, 1.4, 0); animation-timing-function: cubic-bezier(.65,0,.35,1); }
  61.67% { transform: matrix(1, 0, 0, 1, 0, 0); }
  100% { transform: matrix(1, 0, 0, 1, 0, 0); }
}
@keyframes hln-robot-arm-pick-fr {
  0% { transform: matrix(1, 0, 0, 1, 0, 0); }
  23.33% { transform: matrix(1, 0, 0, 1, 0, 0); animation-timing-function: cubic-bezier(.65,0,.35,1); }
  25.83% { transform: matrix(1, 0, 0, 1, -1.4, 0); }
  59.17% { transform: matrix(1, 0, 0, 1, -1.4, 0); animation-timing-function: cubic-bezier(.65,0,.35,1); }
  61.67% { transform: matrix(1, 0, 0, 1, 0, 0); }
  100% { transform: matrix(1, 0, 0, 1, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .hln-robot-arm-pick * {
    animation: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hln-robot-arm-pick, .hln-robot-arm-pick *, .hln-robot-arm-pick::before, .hln-robot-arm-pick::after, .hln-robot-arm-pick *::before, .hln-robot-arm-pick *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --hln-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --hln-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar hairline animations