AnC
AnC

Reputation: 4201

animating SVG line transitions

Given two simple SVG icons, how would I animate the transition between them - ideally without complex JavaScript (e.g. GreenSock; toggling a class would be fine though):

svg {
    width: 10em;
    border: 1px solid #AAA;
    stroke: currentColor;
    stroke-width: 3;
    stroke-linecap: square;
    stroke-linejoin: bevel;
    fill: none;
}
<svg viewBox="0 0 24 24">
    <line x1="3" y1="6" x2="21" y2="6" />
    <line x1="3" y1="18" x2="21" y2="18" />
</svg>

<svg viewBox="0 0 24 24">
    <line x1="9" y1="6" x2="15" y2="12" />
    <line x1="9" y1="18" x2="15" y2="12" />
</svg>

(I assume both icons' <line>s would be merged into a single <svg> for animation purposes.)

Based on my own research, wading through a lot of seemingly conflicting documentation on the web, CSS transformations are insufficient here (translate + scale + rotate results in a skewed image) and SMIL is no longer recommended (I also struggle to figure out how to make it work properly).

Upvotes: 0

Views: 1688

Answers (1)

Zevan
Zevan

Reputation: 10235

This could probably use a little tweaking, but you can make CSS transitions work with the transform property. The key is the order in which translate, rotate and scale are applied.

var toggle = true;

document.addEventListener('click', function() {
  document.querySelector('svg').classList[toggle ? 'add' : 'remove']('arrow');
  toggle = !toggle;
});
svg {
  width: 10em;
  border: 1px solid #aaa;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linecap: square;
  stroke-linejoin: bevel;
  fill: none;
  cursor: pointer;
}

svg line {
  transition: transform 250ms ease-in;
}

.arrow .line-top {
  transform: translate(12px, 0px) rotate(45deg) scale(0.5, 1);
}

.arrow .line-bottom {
  transform: translate(-5px, 5.3px) rotate(-45deg) scale(0.5, 1);
}
click to toggle arrow class <br>
<svg viewBox="0 0 24 24">
    <line class="line-top" x1="3" y1="6" x2="21" y2="6" />
    <line class="line-bottom" x1="3" y1="18" x2="21" y2="18" />
</svg>

Upvotes: 6

Related Questions