In this SVG below, a circle moves on the given path linearly at a constant speed. I want it to move according to the curve (like a projectile, since this curve is a parabola). I have read about keySplines, keyPoints and keyTimes but cannot apply them correctly to obtain a smooth projectile motion. Is there a way to achieve this?
<svg viewBox="0 0 500 500" width="300px">
<path fill="none" stroke="black" d="M250,250 Q356.06601717798213,143.93398282201787 462.13203435596427,487.86796564403573">
</path>
<circle r="5" fill="red">
<animateMotion dur="5s" path="M250,250 Q356.06601717798213,143.93398282201787 462.13203435596427,487.86796564403573" fill="freeze">
</animateMotion>
</circle>
</svg>
You need to use keyPoints. I added an <mpath> element because they are easier to maintain.
<svg viewBox="0 0 500 500" width="300px">
<path fill="none" stroke="black" id="motionPath" d="M250,250 Q356.06601717798213,143.93398282201787 462.13203435596427,487.86796564403573"/>
<circle r="5" fill="red">
<animateMotion dur="5s" keyPoints="0;0.22;0.3;1" keyTimes="0;0.45;0.55;1" calcMode="linear" fill="freeze">
<mpath xlink:href="#motionPath"/>
</animateMotion>
</circle>
</svg>
I want it to move according to the curve (like a projectile, since this curve is a parabola).
I changed the motion path to look like a parabola.
Using the attributes keyPoints="0;0.4;0.6;1" and keyTimes="0;0.3;0.7;1" made the movement of the projectile along the trajectory uneven:
The projectile moves quickly to the top of the parabola
In the upper part, the projectile slows down and accelerates again on the descent
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="svg4" width="500" height="500" viewBox="0 250 500 500">
<path id="trace" d="M47.9 460.6C120.2 238.4 380 226.7 450.7 456" fill="none" stroke="#000" stroke-dasharray="5 5"/>
<circle cx="0" cy="0" r="5" fill="red" >
<animateMotion begin="0s" dur="3s" rotate="auto"
keyPoints="0;0.4;0.6;1"
keyTimes="0;0.3;0.7;1"
calcMode="linear"
repeatCount="5">
<mpath xlink:href="#trace"/>
</animateMotion>
</circle>
</svg>
The example below is a bit more realistic. A projectile is drawn that flies out of a cannon barrel. During the shot, the gun rolls back and returns. The animation starts after the click.

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="svg4" width="1000" height="1000" viewBox="0 150 500 500">
<defs>
<linearGradient id="Lg1">
<stop offset="0%" stop-color="white" />
<stop offset="100%" stop-color="black" />
</linearGradient >
<linearGradient id="Lg2" x1="0" y1="0" y2="1">
<stop offset="10%" stop-color="#D8BB00" />
<stop offset="100%" stop-color="#685A00" />
</linearGradient >
<linearGradient id="Lg3" x1="0" x2="0" y1="0" y2="1">
<stop offset="80%" stop-color="dodgerblue" stop-opacity="0.8"/>
<stop offset="95%" stop-color="green" />
<stop offset="100%" stop-color="brown" />
</linearGradient >
</defs>
<rect width="100%" height="100%" fill="url(#Lg3)" />
<path id="trace" d="M47.9 460.6C120.2 238.4 380 226.7 450.7 456" fill="none" stroke-width="0.8" stroke="#000" stroke-dasharray="5 5"/>
<g id="cannon">
<path id="wheel" d="M59.2 475.4c0 10-7 18.1-15.7 18.1-8.6 0-15.6-8-15.6-18s7-18.2 15.6-18.2c8.7 0 15.7 8.1 15.7 18.1z" opacity="1" fill="none" fill-opacity="1" stroke="#414141" stroke-width="2" stroke-miterlimit="4" />
<path id="barrel" fill="url(#Lg1)" d="M54.3 434.3 39 478.5h6.2l14.6-41.3z" stroke="none" stroke-width="1" />
<g stroke-width="3" stroke="#000" opacity="0.8">
<path d="M26 479.4h29.4" id="path848" />
<path d="M40.6 462.3v33.9" id="path850" />
<path d="M30.3 491.4 51 467" id="path852" />
<path d="m30.4 467.1 20.9 24.5" id="path854" />
</g>
<path id="wheel" d="M56.3 479.2c0 10-7 18-15.6 18s-15.6-8-15.6-18S32 461 40.7 461c8.7 0 15.6 8 15.6 18z" opacity="1" fill="#8B8B8B" fill-opacity="0.5" stroke="#414141" stroke-width="2" stroke-miterlimit="4" />
<path id="lafet" d="m40.6 479.4-16.6 16-18.7.2" fill="none" stroke="#2C2C2C" stroke-width="5" stroke-linecap="round" />
</g>
<g id="projectile">
<path fill="url(#Lg2)" transform="translate(0 -4)" d="M.8 1 .7 5.9l9.2.3s3.7-.4 3.7-2.4c.1-1.9-3.3-2.6-3.3-2.6z" stroke="#A08B00" stroke-width="1" >
<animateMotion id="anPop"
begin="svg1.click;rollback.end+2s"
dur="3s" rotate="auto"
keyPoints="0;0.4;0.6;1"
keyTimes="0;0.3;0.6;1"
calcMode="linear"
repeatCount="1"
restart="whenNotActive">
<mpath xlink:href="#trace"/>
</animateMotion>
</path>
</g>
<animateTransform id="rollback" xlink:href="#cannon" attributeName="transform" type="translate" begin="anPop.begin+0.25s" dur="0.8s" values="0,0;-20,0;0,0" repeatCount="1" />
</svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With