SVG animation opacity on loop - animation

I would like to make an svg path's opacity to go from 0 to 100 back to 0 and to 100 on a continuous loop.
So far i can get it to animate from 0 to 100 but not back again,
Any ideas?
Thanks

You can animate any number of values using the values attribute, like this:
<rect x="10" y="10" width="20" height="20">
<animate attributeName="opacity"
values="0;1;0" dur="1s"
repeatCount="indefinite"/>
</rect>
That will animate from opacity 0 to opacity 1 (100%), and then back to 0 again, over the course of 1 second.

You have two separate animations - one for opacity increasing and one for it decreasing. Each begins when the other ends, but the first one also begins at 0s. Here's an example for a rect:
<rect x="10" y="10" width="20" height="20">
<animate id="animation1"
attributeName="opacity"
from="0" to="1" dur="1s"
begin="0s;animation2.end" />
<animate id="animation2"
attributeName="opacity"
from="1" to="0" dur="1s"
begin="animation1.end" />
</rect>

Related

Offseting animation start point for SVG AnimateMotion

I have a path in my SVG, and I want to animate 2 rect elements along it, using animateMotion. However, I want the two rectangles to start at different points along the path.
I've gotten close by using begin to offset the start time, but that means that one rectangle gets stuck until its time starts - which is non ideal. Is there something similar to begin, like startOffset for text that would work?
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="lightgrey" id="motionPath"
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="#motionPath"/>
</animateMotion>
</circle>
<circle r="5" fill="red">
<animateMotion dur="10s" repeatCount="indefinite"
begin="2s"
>
<mpath xlink:href="#motionPath"/>
</animateMotion>
</circle>
</svg>
For your case of a indefinitely repeated motion, the easiest solution is to set the begin time to a negative value. At document start time, the motion is computed to have already begun, and the animated element starts at an offset.
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<path fill="none" stroke="lightgrey" id="motionPath"
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="#motionPath"/>
</animateMotion>
</circle>
<circle r="5" fill="red">
<animateMotion dur="10s" repeatCount="indefinite"
begin="-2s"
>
<mpath xlink:href="#motionPath"/>
</animateMotion>
</circle>
</svg>
Note: for a non-repeated motion, you can also use the notation keyPoints="0.2;1". This way, during the simple duration, the animated element moves from 20% to 100% along the path, but never is shown at its start.

Simple SVG scaling of a path

I currently have the following SVG, and wish to animate the path:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="112.5px" height="115.4px" viewBox="0 0 112.5 115.4" enable-background="new 0 0 112.5 115.4" xml:space="preserve">
<g>
<ellipse fill="#333333" cx="56.3" cy="56.3" rx="56.3" ry="56.3"/>
</g>
<g>
<path fill="none" class="iphone-feature-icon-heart-path" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" d="M82.6,50L82.6,50c-0.2-8.1-6.9-15.2-15.1-15.2
c-4.8,0-9,2.4-11.8,6c-2.8-3.6-7-6-11.8-6c-8.3,0-15,7.2-15.1,15.2h0c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.2,0.1,0.4,0.1,0.6
c0.7,20.5,26.6,29,26.6,29s26.3-8.4,27.1-28.9c0-0.2,0.1-0.4,0.1-0.6c0,0,0-0.1,0-0.1C82.6,50.1,82.6,50.1,82.6,50z"/>
</g>
A 'pulse' animate along the origin point of the path is what is desired. I've tried dropping this between the last group, however there are a couple of problems with that. First of all, it doesn't animate back to original scale.
<animateTransform attributeType="XML"
attributeName="transform" type="scale"
from="1 1" to="1.5 1.5"
begin="0s" dur="2s" fill="freeze"/>
Second of all it doesn't scale along the center point of the path. I had thought about using transform-origin 50%, 50% and doing the pulse in css, however this doesn't work in firefox (or at least it doesn't animate along the true origin.)
See Fiddle: http://jsfiddle.net/y1kdna46/3/
From reading around there appears to be a transform matrix that can be used to do this cross browser. Anyone any tips / advice? As best I can I wish to avoid CSS / javascript to perform this. i.e. do it all within the code of the SVG.
This seems about right. I've transformed the path so it scales about the origin and used values to do and then undo the scaling. Note also the additive="sum" so I don't overwrite my initial transform.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="112.5px" height="115.4px" viewBox="0 0 112.5 115.4" xml:space="preserve">
<g>
<ellipse fill="#333333" cx="56.3" cy="56.3" rx="56.3" ry="56.3"/>
</g>
<g transform="translate(50, 50)">
<path transform="translate(-50, -50)" fill="none" class="iphone-feature-icon-heart-path" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" d="M82.6,50L82.6,50c-0.2-8.1-6.9-15.2-15.1-15.2
c-4.8,0-9,2.4-11.8,6c-2.8-3.6-7-6-11.8-6c-8.3,0-15,7.2-15.1,15.2h0c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.2,0.1,0.4,0.1,0.6
c0.7,20.5,26.6,29,26.6,29s26.3-8.4,27.1-28.9c0-0.2,0.1-0.4,0.1-0.6c0,0,0-0.1,0-0.1C82.6,50.1,82.6,50.1,82.6,50z"/>
<animateTransform attributeType="XML"
attributeName="transform" type="scale"
values="1;1.5;1" additive="sum"
begin="0s" dur="2s" repeatCount="indefinite"/>
</g>
</svg>

how to make svg animation scaling around a center of a figure?

I'm trying to pulsate a star by using animateTransform with type="scale", but instead of scaling around a center of the star, it scales to left and down. How to scale the star around the center?
Svg code:
<svg version="1.1" id="star" xmlns="http://www.w3.org/2000/svg" x="170px" y="385px" width="100px" height="100px" viewBox="0 0 60 60" xml:space="preserve">
<g>
<polygon fill="#DAC978" points="18.832,36.694 5.903,25.156 23.146,23.419 30.125,7.557 37.104,23.419 54.347,25.155 41.417,36.694 45.095,53.629 30.125,44.898 15.155,53.63" />
<path fill="#A58144" d="M30.125,13.765l4.104,9.327l1.175,2.669l2.901,0.292l10.139,1.021l-7.603,6.785L38.665,35.8l0.618,2.851 l2.162,9.957l-8.801-5.134l-2.519-1.469l-2.52,1.469l-8.803,5.134l2.162-9.957l0.619-2.85l-2.175-1.942l-7.603-6.785l10.139-1.021 l2.901-0.292l1.174-2.669L30.125,13.765 M30.125,1.35l-8.681,19.729L0,23.237l16.08,14.352l-4.574,21.063l18.62-10.858 l18.618,10.858L44.17,37.589l16.081-14.352l-21.445-2.159L30.125,1.35L30.125,1.35z" />
<animateTransform
attributeType="xml"
attributeName="transform"
type="scale"
from="0"
by="1"
dur="1s"
repeatCount="10"
/>
</g>
</svg>
jsFiddle with working code.
animateTransform type scale seems to scale always from origin at (0, 0). One possible solution can be in translating your polygon so that its center is in (0, 0).
Here is working jsFiddle example.
Changes made to your original code:
The viewbox is changed from viewBox="0 0 60 60" to viewBox="-30 -30 60 60" in order to have center of the viewBox at (0, 0) (for more on viewBoxes you can see this tutorial)
polygon and path are grouped and then translated so that their center is at (0, 0) too:
<g transform="translate(-30,-30)">
<polygon ... />
<path ... />
</g>

How to specify the x-y rotation point when using animateTransform?

I want to use animateTransform to rotate an SVG image continuously. So here we go:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="1024px" height="768px" enable-background="new 0 0 100 100" xml:space="preserve">
<g transform="translate(100, 100)">
<rect fill="#FE9FFF" width="100px" height="100px">
<animateTransform attributeName="transform" type="rotate"
from="0" to="360" dur="20s" repeatDur="indefinite"/>
</rect>
</g>
</svg>
This works.
Now: I would like to change the above, so that the block rotates around its center and not its top left corner. I know that if I want to rotate the block statically around its center, I can do this:
<g transform="rotate(30, 50, 50)">
<rect fill="#FE9FFF" width="100px" height="100px">
</rect>
</g>
My question is - how do I manage a continuous animated rotation around the block's center? I have looked at the spec and a couple of other related questions on SO, but I'm having trouble implementing the explanations supplied.
Thanks in advance.
http://www.w3.org/TR/SVG/animate.html#AnimateTransformElement
The ‘from’, ‘by’ and ‘to’ attributes take a value expressed using the same syntax that is available for the given transformation type:
(...)
For a type="rotate", each individual value is expressed as <rotate-angle> [<cx> <cy>]
You can specify the center for the rotation if you provide 2 additional values, cx and cy.
So, for your piece of code, I add "50 50" in the "from" and "to" attribute :
<rect fill="#FE9FFF" width="100px" height="100px">
<animateTransform attributeName="transform" type="rotate"
from="0 50 50" to="360 50 50" dur="20s" repeatDur="indefinite"/>
</rect>
It work with latest version of Opera, Safari and Chrome, also Firefrox 4 Beta and Batik.
To be clear: what we are trying to achieve is rotation around a center which is itself being translated. I find that if I have an <animateTransform type=rotate>, I cannot use <animateMotion>, nor <animateTransform type=translate> to perform simultaneous translation. It (latest Chrome or Firefox) does not interpolate the center of rotation as desired, resulting in a "loop de loop" instead. However, using a simple <animate> for each of the x,y coordinates does work as desired; in this case, <animateTransform type=rotate> interpolates the center along the x,y path, as long as you set the from= parameter to the start angle, start x and start y position, and set the to= parameter to the ending values.

How to loop SVG animation sequence?

I have sequence of animationTransform:
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="30" begin="0s" dur="0.4s" fill="freeze"/>
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="30" to="0" begin="0.4s" dur="0.4s" fill="freeze"/>
If it possible to loop this sequence without using script?
I can set individual animation to loop by using repeatCount="indefinite" by I want to loop the whole sequence in order.
Figured it out already. Solution for those who are interested:
<animateTransform id="anim1" attributeName="transform" attributeType="XML" type="rotate" from="0" to="30" begin="0s; anim2.end" dur="0.4s" fill="freeze"/>
<animateTransform id="anim2" attributeName="transform" attributeType="XML" type="rotate" from="30" to="0" begin="anim1.end" dur="0.4s" fill="freeze"/>
You can also just loop within a single animateTransform by providing a values attribute with a semi-colon separated list:
<animateTransform attributeName="transform" type="rotate"
values="0;30;0" begin="0s" dur="0.8s" fill="freeze"
repeatCount="indefinite" />
Here's an example (checked in Firefox 4.0 and Chrome).
it's also possible to add/subtract (milli)seconds:
begin="anim2.end-500ms"

Resources