Search code examples
csssvgcss-transforms

Animating composite svg with multiple paths using css only


I am trying to animate one of the path of an svg with multiple path. the effect I am trying to achieve is the arrow path stays in it position and rotates 180 around its own center.

Other answers at stack Overflow suggest using transform origin but those trick doesn't seem to help.

SVG snippet

.arrow{
    animation:inboxToOutbox 5s infinite
}

@keyframes inboxToOutbox {
    
    50% {
        
        
        transform: rotate(-180deg);
    }
  }
<svg width ='50px' height='50px' viewBox="166.588 216.37 99.996 85.641" xmlns="http://www.w3.org/2000/svg">
  <path id = "box" style={{fill:"#ffff"}} d="M 99.404 68.401 C 98.855 67.087 97.904 65.946 96.719 65.222 L 80.784 54.5 L 70.968 54.5 L 87.97 67.543 L 70.247 67.543 C 69.701 67.543 69.255 67.842 68.996 68.292 L 68.965 68.335 L 69.042 68.227 L 64.964 79.383 L 35.042 79.383 L 30.963 68.225 L 31.01 68.292 C 30.751 67.84 30.221 67.538 29.676 67.54 L 14.983 67.543 L 12.036 67.543 L 29.04 54.5 L 19.222 54.5 L 3.311 65.208 C 2.127 65.932 1.153 67.086 0.604 68.401 C 0.017 69.697 -0.151 71.134 0.151 72.434 L 2.957 87.793 C 3.297 89.085 4.141 90.31 5.279 91.127 C 6.392 91.987 7.819 92.497 9.24 92.5 L 90.788 92.5 C 92.209 92.497 93.615 91.987 94.729 91.127 C 95.871 90.305 96.702 89.139 97.039 87.854 L 99.85 72.462 C 100.154 71.163 99.992 69.697 99.404 68.401 Z" transform="matrix(1, 0, 0, 1, 166.584211, 209.511274)"/>
  
  <path class='arrow' style={{fill:"#ffff"}} d="M 226.109 238.851 L 242.609 238.851 L 216.609 264.011 L 190.609 238.851 L 207.109 238.851 L 207.258 216.37 L 226.698 216.665 L 226.109 238.851 Z">
  
    </path>
  
</svg>

I want to animate this inbox into outbox on hover. By rotating the arrow at its own center.


Solution

  • You need to use transform-origin: center but this will not work as expected in SVG. You should use transform-box: fill-box also.

    .arrow {
      transform-box: fill-box;/* view-box default value */
      transform-origin:center center;
      animation: inboxToOutbox 5s infinite
    }
    
    @keyframes inboxToOutbox {
      50% {
        transform: rotate(-180deg);
      }
    }
    <svg width='50px' height='50px' viewBox="166.588 216.37 99.996 85.641" xmlns="http://www.w3.org/2000/svg">
      <path id = "box" d="M 99.404 68.401 C 98.855 67.087 97.904 65.946 96.719 65.222 L 80.784 54.5 L 70.968 54.5 L 87.97 67.543 L 70.247 67.543 C 69.701 67.543 69.255 67.842 68.996 68.292 L 68.965 68.335 L 69.042 68.227 L 64.964 79.383 L 35.042 79.383 L 30.963 68.225 L 31.01 68.292 C 30.751 67.84 30.221 67.538 29.676 67.54 L 14.983 67.543 L 12.036 67.543 L 29.04 54.5 L 19.222 54.5 L 3.311 65.208 C 2.127 65.932 1.153 67.086 0.604 68.401 C 0.017 69.697 -0.151 71.134 0.151 72.434 L 2.957 87.793 C 3.297 89.085 4.141 90.31 5.279 91.127 C 6.392 91.987 7.819 92.497 9.24 92.5 L 90.788 92.5 C 92.209 92.497 93.615 91.987 94.729 91.127 C 95.871 90.305 96.702 89.139 97.039 87.854 L 99.85 72.462 C 100.154 71.163 99.992 69.697 99.404 68.401 Z" transform="matrix(1, 0, 0, 1, 166.584211, 209.511274)"/>
      <path class='arrow' d="M 226.109 238.851 L 242.609 238.851 L 216.609 264.011 L 190.609 238.851 L 207.109 238.851 L 207.258 216.37 L 226.698 216.665 L 226.109 238.851 Z" />
    </svg>