Can i create a circle that follow an existing line in svg? - svg

As the title suggests, i'm trying to create an animation in svg with a point/circle that follows an irregular path. I am using the animateTransform, for example:
<animateTransform attributeName="transform"
attributeType="XML"
type="translate"
from="0 60 70"
to="360 60 70"
dur="10s"
repeatCount="definite"/>
Can i implement this method (in svg) to let the circle to follow the path, or i have to use necessarily javascript?
If i can do it in svg could you give me a basic example with an explanation?

You can use the <animateMotion> element.
Example adapted from MDN:
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<path id="path" fill="none" stroke="lightgrey"
d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
<circle r="5" fill="red">
<animateMotion dur="10s" repeatCount="indefinite">
<mpath xlink:href="#path"/>
</animateMotion>
</circle>
</svg>

Related

Svg alternate animateMotion

I want to have repeating alternate direction for the animation
<animateMotion keyPoints="0;1;0" keyTimes="0;0.5;1" dur="6s" repeatCount="indefinite" rotate="auto" >
<mpath href="#path1"/>
</animateMotion>
Keypoints and KeyTimes are not working
Full code:
<svg width="200" height="200" viewBox="0 0 700 700">
<g>
<path id="path1" d="M200,350 C 200,440 400,150 400,250 M200,350"
fill="none" stroke="blue" stroke-width="7.06" />
<path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z"
fill="yellow" stroke="red" stroke-width="7.06" />
<animateMotion keyPoints="0;1;0" keyTimes="0;0.5;1" dur="6s" repeatCount="indefinite" rotate="auto" >
<mpath href="#path1"/>
</animateMotion>
</g>
</svg>
First there is an issue with your code. You are animating a group of shapes and you are using one of those shapes as mpath.
In the next examples I'm animating the triangle over the integral like shape. In order to animate the triangle in both ways I'm rewriting the mpath so that the path will reverse to the starting point.
svg{width:90vh}
<svg viewBox="0 0 700 700">
<path id="path1" d="M200,350 C 200,440 400,150 400,250 C400,150 200,440 200,350" fill="none" stroke="blue" stroke-width="7.06" />
<path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z" fill="yellow" stroke="red" stroke-width="7.06" >
<animateMotion keyPoints="0;1;0" keyTimes="0;0.5;1" dur="6s" repeatCount="indefinite" rotate="auto" >
<mpath href="#path1"/>
</animateMotion>
</path>
</svg>
However if you want the triangle to stay the same side of the curve when reversing, in this case I'm using 2 animations, each one begining when the previous one ends. For the second animation I'm using rotate="auto-reverse"
svg{width:90vh}
<svg viewBox="0 0 700 700">
<path id="path1" d="M200,350 C 200,440 400,150 400,250" fill="none" stroke="blue" stroke-width="7.06" />
<path id="path2" d="M400,250 C400,150 200,440 200,350" fill="none" stroke="blue" stroke-width="7.06" />
<path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z" fill="yellow" stroke="red" stroke-width="7.06">
<animateMotion id="a1" dur="3s" rotate="auto" begin="0;a2.end">
<mpath href="#path1" />
</animateMotion>
<animateMotion id="a2" dur="3s" rotate="auto-reverse" begin="a1.end">
<mpath href="#path2" />
</animateMotion>
</path>
</svg>
Please observe that the path for the second animation is the path for the first animation reversed.

Animate SVG with animateTransform

Trying to animate an SVG element with the skewX. It works, however, not exactly the way I want it to.
Now: the bottom part moves to the left
Goal: the upper part should move to the right instead (and bottom stays in place)
I tried with transform-origin but it didn't work. Any ideas how to solve this mystery?
<svg xmlns="http://www.w3.org/2000/svg" width="102" height="102" viewBox="-50 -50 102 102">
<g>
<rect width="10%" height="50%"
style="fill:none; stroke:red; stroke-with:3;">
<animateTransform
attributeName="transform"
attributeType="XML"
type="skewX"
from="0"
to="-20"
begin="0.5s"
dur="0.2s"
repeatCount="1"
fill="freeze"
id="fallen"/>
</rect>
</g>
</svg>
Use another transform to move the whole thing to the right at the same time as the bottom moves left.
<svg xmlns="http://www.w3.org/2000/svg" width="102" height="102" viewBox="-50 -50 102 102">
<g>
<rect width="10%" height="50%"
style="fill:none; stroke:red; stroke-with:3;">
<animateTransform
attributeName="transform"
attributeType="XML"
type="skewX"
from="0"
to="-20"
begin="0.5s"
dur="0.2s"
repeatCount="1"
fill="freeze"
id="fallen"/>
<animateTransform
attributeName="transform"
attributeType="XML"
type="translate"
from="0"
to="20"
begin="0.5s"
dur="0.2s"
repeatCount="1"
fill="freeze"
additive="sum"/>
</rect>
</g>
</svg>

svg animation path direction

I'm using svg animation tags to animate a group tag along the coordinates of a path tag. Unfortunately, the animation is running in the opposite direction to what I require (I.E going from b to a instead of a to b). Does there exist any attribute which would amend this, something like:
<animateMotion
xlink:href="#group1"
dur="6s"
fill="freeze"
rotate="auto-reverse"
direction="reverse"
>
<mpath xlink:href="#path1" />
</animateMotion>
I know this could be achieved with snap or raphael but as far as I know it's not possible to use anything to the effect of 'rotate="auto-reverse"' in those libraries.
Alternatively, is there a way to reverse the way my path is calculated; can this be achieved with any software?
You could use the keyPoints attribute, along with keyTimes.
<?xml version="1.0"?>
<svg width="120" height="120" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<path d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110"
stroke="lightgrey" stroke-width="2"
fill="none" id="theMotionPath"/>
<!-- Here is a green circle which will be moved along the motion path. -->
<circle cx="" cy="" r="5" fill="green">
<!-- Define the motion path animation -->
<animateMotion dur="6s" repeatCount="indefinite" keyPoints="0;1" calcMode="linear"
keyTimes="0;1">
<mpath xlink:href="#theMotionPath"/>
</animateMotion>
</circle>
<!-- Here is a red one, using the same motionPath but reversed thanks to keyPoints -->
<circle cx="" cy="" r="5" fill="red">
<animateMotion dur="6s" repeatCount="indefinite" keyPoints="1;0" calcMode="linear"
keyTimes="0;1">
<mpath xlink:href="#theMotionPath"/>
</animateMotion>
</circle>
</svg>

SVG: animateMotion along animated path

When I use animateMotion along an animated path, Firefox (26) follow the original path while Opera (17) and Chrome (32) follow the changing path. For example, in the following svg the red rectangle ends at position of 100,10 in FF while at 50,10 in other browsers:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
<path id="p" stroke="black" stroke-width="1" d="M 0,10 100,10"/>
<rect id="r" x="-5" y="-5" width="10" height="10" fill ="red"/>
<animate xlink:href="#p" attributeName="d" to="M 0,10 50,10" dur="5s" fill="freeze" repeatCount="1"/>
<animateMotion xlink:href="#r" dur="5s" fill="freeze" repeatCount="1">
<mpath xlink:href="#p"/>
</animateMotion>
</svg>
What is the correct behavior according to the SVG spec?
The animated path should be used, there's an open Firefox bug on that.

how to repeat infinitely the whole svg

I mean after my SVG stops completing the animation I want the animation to start over again and end and then again start over and so on.
I tried:
<svg>
<animate repeatCount="indefinite"/>
</svg>
But it doesn't work.
See example animMotion01 in the w3 SVG spec for a fairly reduced example illustrating SVG animation (including use of repeatCount="indefinite"):
<svg width="5cm" height="3cm" viewBox="0 0 500 300"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<desc>Example animMotion01 - demonstrate motion animation computations</desc>
<rect x="1" y="1" width="498" height="298"
fill="none" stroke="blue" stroke-width="2" />
<!-- Draw the outline of the motion path in blue, along
with three small circles at the start, middle and end. -->
<path id="path1" d="M100,250 C 100,50 400,50 400,250"
fill="none" stroke="blue" stroke-width="7.06" />
<circle cx="100" cy="250" r="17.64" fill="blue" />
<circle cx="250" cy="100" r="17.64" fill="blue" />
<circle cx="400" cy="250" r="17.64" fill="blue" />
<!-- Here is a triangle which will be moved about the motion path.
It is defined with an upright orientation with the base of
the triangle centered horizontally just above the origin. -->
<path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z"
fill="yellow" stroke="red" stroke-width="7.06" >
<!-- Define the motion path animation -->
<animateMotion dur="6s" repeatCount="indefinite" rotate="auto" >
<mpath xlink:href="#path1"/>
</animateMotion>
</path>
</svg>

Resources