I'm trying to make an object in an animated SVG image move in a perfect sine motion in one axis (up and down or left and right). For instance: x(t) = a + b * sin(t * 2PI*f)
(I'm also trying to animate one attribute of a spline in this way, but that seems to even harder or impossible).
I know you can use splines to ease motion, but that is only an approximation. I want a perfect sine.
I tried several things:
First I tried to make animateMotion to follow an elliptical path. You can use two ellipses to make a perfect circle. The problem is that it linearly moves along its path. So if you set the width or height to zero the motion is linear!
Second I tried to stretch the motion by scaling the viewbox width independent of height. This does scale the motion properly, but also the object. You can compensate the object scaling by scaling the object with the inverse of the scaling, but you can never get this scaling to reach 0 as that would require an finitely large object. Below is my code snippet that does this
<svg viewBox="0 0 5000 5000" width="2000" height="200" preserveAspectRatio="none">
<path d="M25,-250v500h-50v-500z">
<animateMotion path="M1000,600 A200,200 0 1 1 300,600 A200,200 0 1 1 1000,600"
width="5000"
height="500"
preserveAspectRatio="none"
begin="0s" dur="3s" repeatCount="indefinite"/>
</path>
<path d="M1000,600 A200,200 0 1 1 300,600 A200,200 0 1 1 1000,600" fill="none"
stroke="black" stroke-width="20"/>
</svg>
I'm not experienced enough with SVG animation to solve this, but I came up with some ideas:
How can it be done? (Again, I'm not looking for approximations.)
I was able to get it to work by using grouping. With grouping you can nest elements and then you can apply animateMotion twice on the same object.
I used the same arc for both animations, but one is vertically flipped and both are half amplitude. Horizontally they add up to full amplitude and vertically they will cancel each other out.
I used a half a unit circle and use the viewbox for scaling to simplify the calculations (total length of motion is 1).
<svg xmlns="http://www.w3.org/2000/svg" width="175" height="175" viewBox="-0.1 -0.1 1.2 1.2" border="1px solid blue">
<path id="lineAC" d="M0,0.5 A0.5,0.5 0 1,1 1,0.5" stroke="blue" stroke-width="0.02" fill="none"/>
<path id="lineAC" d="M0,0.5 A0.5,0.5 0 1,0 1,0.5" stroke="green" stroke-width="0.02" fill="none"/>
<g>
<g>
<rect width="0.1" height="0.1" x="-0.05" y="-0.05" rx="0" ry="0" fill="black" />
<animateMotion path="M0,0.25 A0.25,0.25 0 1,1 0.5,0.25
A0.25,0.25 0 1,1 0.0,0.25" dur="3s" repeatCount="indefinite"/>
</g>
<animateMotion path="M0,0.25 A0.25,0.25 0 1,0 0.5,0.25
A0.25,0.25 0 1,0 0.0,0.25" dur="3s" repeatCount="indefinite"/>
</g>
</svg>