Flip Reveal

transform

The drawing swings round from edge-on, in perspective. It is the <svg> that turns, not a group inside it: the outer <svg> is an ordinary CSS box that takes a real 3D transform.

Demo shape

Every animation on the page redraws with the shape you pick.

Align
Ease
Duration
s
0.13
Stagger
s
00.2
Delay
s
02
<!-- 1. Markup -->
<svg viewBox="0 0 120 120" class="k-flip-reveal" 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 flipReveal(svg) {
  const _reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
  const _duration = _reducedMotion ? 0.01 : 0.8
  const _delay = _reducedMotion ? 0 : 0

  // The outer <svg> is a CSS box, so it takes a true 3D transform, and the
  // perspective travels with it rather than depending on a parent's style.
  const animation = svg.animate(
    [{ transform: 'perspective(600px) rotateY(-90deg)' }, { transform: 'perspective(600px) rotateY(0deg)' }],
    { duration: _duration * 1000, delay: _delay * 1000, easing: 'linear(0.0000,0.0987,0.1899,0.2740,0.3513,0.4224,0.4874,0.5467,0.6008,0.6499,0.6943,0.7343,0.7703,0.8025,0.8311,0.8566,0.8790,0.8987,0.9159,0.9308,0.9437,0.9546,0.9639,0.9717,0.9781,0.9834,0.9877,0.9910,0.9937,0.9957,0.9972,0.9982,0.9990,0.9994,0.9997,0.9999,1.0000,1.0000,1.0000,1.0000)', fill: 'both' },
  )

  return () => animation.cancel()
}


flipReveal(document.querySelector('.k-flip-reveal'))