oligofren
oligofren

Reputation: 22923

SMIL to CSS Animation: multiple animations on single element

Now that SMIL is dying I want to convert my simple animated SVGs to using CSS Animations, but I am not super sure how to do the mapping. In this specific svg there are two animation elements.

#embedded {
  color: red;
 }
   <svg id="embedded"  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
        <circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round"/>
        <circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round">
            <animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502"/>
            <animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4"/>
        </circle>
    </svg>

While I seemingly started out fine with these css rules I quickly got stuck

stroke-dasharray: 150.6 100.4 1 250 150.6 100.4;
animation-duration: 2s;
animation-iteration-count: infinite;
stroke-dashoffset: ?;

What would a complete mapping be like? Is it possible at all? Sara Soueidan says not all animations are possible using CSS that are possible using SMIL.

Upvotes: 1

Views: 613

Answers (1)

Harry
Harry

Reputation: 89750

The below is how you'd convert that SMIL animation into its equivalent CSS animation:

  • Both your animate tags have the dur="2s" and so the CSS animation's duration (animation-duration) would also be 2s. You can either specify this value using the long-hand property or using the short-hand property like in the below snippet.
  • There is no calcMode attribute specified for your animate element and so the interpolation mode is linear. Since the interpolation mode is linear, the animation-timing-function will also be linear.
  • The repeatCount is indefinite and so the animation-iteration-count will be infinite.
  • For the stroke-dashoffset, the animation has only a from (0%) and a to (100%) value. So, in the CSS animation's keyframes, we specify the stroke-dashoffset as 0 (from value) at 0% and as 502 (to value) at 100%.
  • For the stroke-dasharray, the animation makes use of values instead of just from and to. In this case, there are three semi-colon separated values and so the first value from the list is given within the 0% keyframe , the second value from the list is given at 50% keyframe and the last is given within the 100% keyframe selector.

#embedded, #embedded2 {
  color: red;
  width: 200px;
  height: 200px;
}
#embedded circle#animated {
  animation: demo 2s infinite linear;
}
@keyframes demo {
  0% {
    stroke-dashoffset: 0;
    stroke-dasharray: 150.6 100.4;
  }
  50% {
    stroke-dasharray: 1 250;
  }
  100% {
    stroke-dashoffset: 502;
    stroke-dasharray: 150.6 100.4;
  }
}
<svg id="embedded" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
  <circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round" />
  <circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round" id="animated">
  </circle>
</svg>

<svg id="embedded2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
  <circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round" />
  <circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round">
    <animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502" />
    <animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4" />
  </circle>
</svg>

Upvotes: 1

Related Questions