1

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.

oligofren
  • 20,744
  • 16
  • 93
  • 180

1 Answers1

1

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>
Harry
  • 87,580
  • 25
  • 202
  • 214
  • 1
    You're welcome @oligofren. Happy to help. By the way, I read recently that even Chrome is reconsidering their decision about deprecating SMIL animations. So maybe all is not lost yet :) – Harry Feb 15 '17 at 12:16