svg animateMotion is offset from path

这一生的挚爱 提交于 2021-02-05 06:44:24

问题


I have this svg:

My goal is to make the box move along the path while keeping its rotation. To make that happen I added an <animateMotion /> element to the square with the same path as the circle. (demo here). The path of both the circle and the animateMotion starts with M which as far as I know signals an absolute position within the SVG. For some reason, though the square is rotated by 90deg and is moving way outside of the circle (while still following a circular path).

<svg width="133" height="131" viewBox="0 0 266 131"  fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M102.242 63.2475C102.242 43.3399 86.105 27.202 66.197 27.202C46.2889 27.202 30.151 43.3399 30.151 63.2475C30.151 83.154 46.2889 99.2939 66.1965 99.2939C86.105 99.2939 102.243 83.154 102.243 63.248" stroke="#00F" stroke-width="1"/>
  
  <path d="M95.0596 24.2323L79.2727 43.3838L73.0606 38.2323L88.8177 19.0823L95.0601 24.2333" fill="red">
      <animateMotion
    path="M102.242 63.2475C102.242 43.3399 86.105 27.202 66.197 27.202C46.2889 27.202 30.151 43.3399 30.151 63.2475C30.151 83.154 46.2889 99.2939 66.1965 99.2939C86.105 99.2939 102.243 83.154 102.243 63.248"
    rotate="auto"
    dur="6s" repeatCount="indefinite" fill="freeze"/>
  </path>
</svg>

How can I make it work and why is it not working?


回答1:


You need to adjust the path of the object you will rotate to make it the closest possible to the (0,0) point (origin) of your SVG to avoid the translation effect.

Here is an approximation where the object is following the path. Still not perfect so I applied a rotation to correct the final position. I also considered the use of <mpath /> to avoid repeatig the same path twice:

svg {
  border:1px solid;
}
<svg width="133" height="131" viewBox="0 0 133 131"  fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M102.242 63.2475C102.242 43.3399 86.105 27.202 66.197 27.202C46.2889 27.202 30.151 43.3399 30.151 63.2475C30.151 83.154 46.2889 99.2939 66.1965 99.2939C86.105 99.2939 102.243 83.154 102.243 63.248" stroke="#00F" stroke-width="1" id="path"/>
  
  <path d="M21.0596 -13.7677 L5.2727 5.3838 L-0.9394 0.2323 L14.8177 -18.9177 L21.0601 -13.7667" fill="red" transform="rotate(-50,10,20)">
     <animateMotion 
    dur="6s" repeatCount="indefinite" fill="freeze" rotate="auto-reverse">
      <mpath xlink:href="#path"/>
    </animateMotion>
  </path>
</svg>

And since it's a rectangle you can simplify like below:

svg {
  border:1px solid;
}
<svg width="133" height="131" viewBox="0 0 133 131"  fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M102.242 63.2475C102.242 43.3399 86.105 27.202 66.197 27.202C46.2889 27.202 30.151 43.3399 30.151 63.2475C30.151 83.154 46.2889 99.2939 66.1965 99.2939C86.105 99.2939 102.243 83.154 102.243 63.248" stroke="#00F" stroke-width="1" id="path"/>
  

  <rect x="-5" y="-15" width="10" height="30" fill="red" >
     <animateMotion 
    dur="6s" repeatCount="indefinite" fill="freeze" rotate="auto">
      <mpath xlink:href="#path"/>
    </animateMotion>
  </rect>
</svg>


来源:https://stackoverflow.com/questions/58471983/svg-animatemotion-is-offset-from-path

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!