user3831325
user3831325

Reputation:

SVG and SMIL animate Ball bouncing 3 times and collision with wall

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.

enter image description here

Upvotes: 2

Views: 1946

Answers (2)

danyamachine
danyamachine

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:

bounce trajectory

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:

enter image description here

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"

what these mean:

  • 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 keySplineson 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

stropitek
stropitek

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

Related Questions