The whole drawing spins in from a half-turn back while it grows, overshooting slightly before it settles.
Every animation on the page redraws with the shape you pick.
<!-- 1. Markup -->
<svg viewBox="0 0 120 120" class="k-spin-in" aria-hidden="true">
<circle cx="60" cy="60" r="34" fill="none" stroke="currentColor" stroke-width="8" vector-effect="non-scaling-stroke" />
<line x1="60" y1="12" x2="60" y2="38" stroke="currentColor" stroke-width="8" stroke-linecap="round" vector-effect="non-scaling-stroke" />
<line x1="60" y1="82" x2="60" y2="108" stroke="currentColor" stroke-width="8" stroke-linecap="round" vector-effect="non-scaling-stroke" />
<circle cx="60" cy="60" r="10" fill="currentColor" />
</svg>
// 2. JS
function spinIn(svg) {
const _reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
const _duration = _reducedMotion ? 0.01 : 0.8
const _delay = _reducedMotion ? 0 : 0
// One group around the whole drawing, so it turns about its own centre as a
// single piece. A <title> stays where it is: it names the <svg>, and moving
// it into a group would take that name away.
const group = document.createElementNS('http://www.w3.org/2000/svg', 'g')
group.append(...[...svg.children].filter((el) => el.tagName !== 'title'))
svg.append(group)
// Without fill-box the group would turn about the SVG's top-left corner.
group.style.transformBox = 'fill-box'
group.style.transformOrigin = 'center'
const animation = group.animate([{ transform: 'rotate(-180deg) scale(0)' }, { transform: 'rotate(0deg) scale(1)' }], {
duration: _duration * 1000,
delay: _delay * 1000,
easing: 'linear(0.0000,0.0729,0.1426,0.2090,0.2724,0.3327,0.3900,0.4444,0.4960,0.5447,0.5908,0.6343,0.6752,0.7136,0.7496,0.7832,0.8145,0.8437,0.8707,0.8956,0.9185,0.9395,0.9587,0.9760,0.9916,1.0056,1.0180,1.0289,1.0384,1.0465,1.0532,1.0588,1.0632,1.0665,1.0688,1.0701,1.0706,1.0702,1.0691,1.0674,1.0650,1.0622,1.0588,1.0551,1.0511,1.0468,1.0423,1.0377,1.0331,1.0285,1.0241,1.0198,1.0157,1.0120,1.0086,1.0057,1.0033,1.0015,1.0004,1.0000)',
fill: 'both',
})
return () => {
animation.cancel()
group.replaceWith(...group.childNodes)
}
}
spinIn(document.querySelector('.k-spin-in'))