Reputation:
I need to animate a circle that bounce 3 times and hits a wall and return. it should follow a given path. i have tried it with animateMotion
. This is how it is so far,
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>animation</title>
<!--<rect x="15" y="5" rx="5" ry="5" width="20" height="10" style="fill:#CCCCFF;stroke:#000099">-->
<circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1">
<animateMotion dur="6s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#path1"/>
</animateMotion>
</circle>
<!--</rect>-->
<path id="path1" d="m21,39c0,0 46,-44 79,-1c33,43 62,58 97,26c35,-32 86,-30 86,
-31c0,-1 61,-9 29,43c-32,52 -19,51 -87,51c-68,0 -158,-5 -158,-6c0,-1 -40,-11 -41,-12 Z"
stroke-width="5" stroke="#000000" fill="none"/>
</svg>
actually something like below is what i am expecting, as i am new to the area, appreciate any guidance or support.
Upvotes: 2
Views: 1946
Reputation: 1908
In order to create the impression that the ball is bouncing organically, you probably want a trajectory that looks a bit more like this:
In addition, you do not want a linear timing function. A linear timing function means the element will move at the same speed throughout the animation. But, the closer a ball is to the apex of a bounce, the slower the ball is going. Also consider that it is going faster at the start and end of the tallest bounce than it is at the start and end of the shortest bounce.
Based on the aforementioned info about the behaviour of a bouncing ball, we might guess that the timing function for one bounce should look something like this:
It starts out fast, slows down, and then speeds up again.
This diagram represents a cubic-bezier curve, also known as a spline. This particular cubic-bezier can be written as 0.1 0.8 1 0.3
- the x and y coords of the first control point (P1) followed by the x and y coords of the second control point (P2).
Combining the trajectory and the timing function: jsfiddle. The timing needs to be refined a bit, but that's the general idea.
The <animateMotion>
element requires four additional attributes to make this happen:
keyPoints="0;0.5;0.75;1"
keyTimes="0;0.35;0.6;1"
calcMode="spline"
keySplines="0.3 0.5 0.8 0.7;0.3 0.5 0.8 0.7;0.3 0.5 0.8 0.7"
keyPoints="0;0.5;0.75;1"
- I've decided to split up the path into three sections, each leg of which is associated with a start and end time (from keyTimes
) and a timing function (from keySplines
). The values are between 0
and 1
, separated by semi-colons, where 0
is start of path and 1
is end of path. keyTimes="0;0.35;0.6;1"
- the total duration of the animation is segmented according to these times. There should be exactly as many keyTimes
times as there are keyPoints
. The values are between 0
and 1
, separated by semi-colons, where 0
is start and 1
is the total duration of the animation. calcMode="spline"
- indicates that we want the timing function to be cubic-bezier. setting calcMode
to spline
means we also have to set keySplines
on this element. keySplines="0.3 0.5 0.8 0.7;0.3 0.5 0.8 0.7;0.3 0.5 0.8 0.7"
- each leg of the trajectory gets its own timing function. (So, there should be one fewer keySplines
value than there are keyTimes
. Here, I've used the same timing function for each, 0.3 0.5 0.8 0.7
. Since there are four keyTimes
, there are three keySplines
values because the trajectory has three legs. (Again, the actual values that I used need to be refined but that's the general idea.)Upvotes: 4
Reputation: 1344
If you want your circle to follow the path, you need the circle's position to be (0,0), since the motion animation will be relative to the circle's current position:
<circle cx="0" cy="0"...
You can also remove rotate="auto"
since it isn't of any use in this case.
See jsfiddle
Upvotes: 0