SVG: Vertical rotating animation - animation

I'm new to SVG and experimenting.
I have done an animation with a rotating circle and another circle that goes vertical. Now I'm trying to combine those animations into one circle, making it go vertical and rotate at the same time. I can't figure out how to do that. My code so far looks like below. The animations separately works but not together. Any tips?
<svg width="200px" height="300px">
<circle cx="50" cy="200" r="20" width="100" height="40"
style="stroke: #ff00ff; fill:none; stroke-dasharray:10, 5; stroke-width:2;" >
<animateTransform attributeName="transform"
type="rotate"
values="360 50 200; 0 50 200; 360 50 200"
begin="0s" dur="5s"
repeatCount="indefinite" />
<animate attributeName="cy"
begin="0s" dur="2"
values="20;250;20"
repeatCount="indefinite" />
</circle>
</svg>

Related

How to set an origin point for svg's animateTransform

If you view this SVG, I'm animating the transform property, and it moves from the top left by default. How do I change it to animate from the center instead?
<svg width="400" height="400" viewBox="0 0 400 400">
<rect width="400" height="400" fill="#495ade"/>
<g>
<circle cx="50" cy="50" r="50" fill="#49de7d"/>
<animateTransform attributeName="transform"
type="scale"
values="1 1;.5 .5;1 1"
begin="0s"
dur="1.5s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.5 1; 0.5 0 0.5 1"
/>
</g>
</svg>
What I tried already:
This answer says to just throw X & Y coords after each of the values listed. So I tried values="1 1 50 50;.5 .5 50 50;1 1 50 50" but that kills the animation.
You can also use from and to instead of values, and include an X & Y origin, but I need 3 animation states, not two.
Instead of the animation animateTransform type =" scale ", you can use the animation of increasing the radius of the circle
In this case, it will not be necessary to define the transform-origin since the circle is in the center of the canvas.
<svg width="400" height="400" viewBox="0 0 400 400">
<rect width="400" height="400" fill="#495ade"/>
<g>
<circle cx="200" cy="200" r="50" fill="#49de7d">
<animate attributeName="r"
values="50;25;50"
begin="0s"
dur="1.5s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.5 1; 0.5 0 0.5 1"
/>
</circle>
</g>
</svg>
Pause animation in intermediate states
<svg width="400" height="400" viewBox="0 0 400 400">
<rect width="400" height="400" fill="#495ade"/>
<g>
<circle cx="200" cy="200" r="50" fill="#49de7d">
<animate attributeName="r"
values="50;25;25;50;50"
begin="0s"
dur="1.5s"
repeatCount="indefinite"
/>
</circle>
</g>
</svg>
Update
Consider Implementing CSS Animations
#crc1 {
transform-origin:center;
transform-box:fill-box;
animation: scale 1.5s infinite;
}
#keyframes scale {
0%{transform:scale(1);}
50%{transform:scale(.5);}
100%{transform:scale(1);}
}
<svg width="400" height="400" viewBox="0 0 400 400">
<rect width="400" height="400" fill="#495ade"/>
<g>
<circle id="crc1" cx="200" cy="200" r="50" fill="#49de7d"/>
</g>
</svg>
Upd2
SMIL animation
On excellent advice from #Sphinxxx, add css rules to the group tag, thus keeping the animateTransform SVG
<svg width="400" height="400" viewBox="0 0 400 400">
<rect width="400" height="400" fill="#495ade"/>
<g style="transform-origin: center; transform-box: fill-box;">
<circle cx="200" cy="200" r="50" fill="#49de7d"/>
<animateTransform attributeName="transform"
type="scale"
values="1 1;.5 .5;1 1"
begin="0s"
dur="1.5s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.5 1; 0.5 0 0.5 1"
/>
</g>
</svg>
It's easiest to have the circle at the origin, that way the scale works from its centre.
Then we need to translate the <g> element instead so the circle appears at the same place.
Finally we need to actually animate the circle and not the <g> element by wrapping the animateTransform by the <circle> element.
<svg width="400" height="400" viewBox="0 0 400 400">
<rect width="400" height="400" fill="#495ade"/>
<g transform="translate(50, 50)">
<circle cx="0" cy="0" r="50" fill="#49de7d">
<animateTransform attributeName="transform"
type="scale"
values="1 1;.5 .5;1 1"
begin="0s"
dur="1.5s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.5 1; 0.5 0 0.5 1"
/>
</circle>
</g>
</svg>
Alternatively we could transform the circle itself and then use additive="sum" to apply the transform animation on top.
<svg width="400" height="400" viewBox="0 0 400 400">
<rect width="400" height="400" fill="#495ade"/>
<g>
<circle cx="0" cy="0" r="50" fill="#49de7d" transform="translate(50, 50)">
<animateTransform attributeName="transform"
type="scale"
values="1 1;.5 .5;1 1"
begin="0s"
dur="1.5s"
repeatCount="indefinite"
calcMode="spline"
keySplines="0.4 0 0.5 1; 0.5 0 0.5 1"
additive="sum"
/>
</circle>
</g>
</svg>

SVG animation: Delaying before repeating

I am trying to create an animation to ask users to rotate their phone.
I have made it rotate 90 degrees without issue, but i can't figure out how to make it delay for 0.2s before repeating. this is what i have so far (rectangle substitues the phone path for simplicity)
<svg>
<animateTransform
attributeType="xml"
attributeName="transform"
type="rotate"
from="0 0 0"
to="90 0 0"
begin="0s"
dur="0.85s"
additive="sum"
repeatCount="indefinite"
fill="freeze" />
<rect
style="fill:#888;"
id="rect"
width="60"
height="40"
x="45"
y="-95"
transform="rotate(90)" />
</svg>
You can use values rather than from/to to provide more values. And then keyTimes to explain when to use them.
Something like this...
<svg>
<animateTransform
attributeType="xml"
attributeName="transform"
type="rotate"
values="0; 90; 90"
keyTimes="0; 0.25; 1"
begin="0s"
dur="1.5s"
additive="sum"
repeatCount="indefinite"
fill="freeze" />
<rect
style="fill:#888;"
id="rect"
width="60"
height="40"
x="45"
y="-95"
transform="rotate(90)" />
</svg>

SVG synchronization of two animations involving scale and translate simultaneously

I am unable to synchronize a SVG transformation which involves scaling as well as translate. The vertex of a triangle translates from point (967, 491) to (900, 100), simultaneously a png image should also translate with the vertex, but should also scale down or up, as it moves.
To get the original position of the png image, I have correctly used the formula -centerX*(scale factor - 1), -centerY*(scaleFactor - 1). This is the original position before animation. But as the motion starts, I am unable to calculate it final position.
Could anyone help me with this problem.
<svg viewBox="0 0 1200 800">
<defs>
<g id="triangle">
<desc>Triangle</desc>
<polygon id="triangle_" points="967,491 738,449 724,603">
<animate attributeName="points" attributeType="XML"
begin="0s" dur="5s" from="967,491 738,449 724,603" to="900,100 738,449 724,603" fill="freeze" />
</polygon>
<g transform="translate(483,245)">
<image xlink:href="http://www.alegralabs.com/human.png" x="940" y="442" width="53" height="98" transform="scale(0.5)" style="fill:#FFF">
<animateTransform attributeName="transform" type="scale" attributeType="XML"
begin="0s" dur="5s" from="0.5" to="0.2" fill="freeze" />
</image>
<animateTransform attributeName="transform" type="translate" attributeType="XML"
begin="0s" dur="5s" to="773,80" fill="freeze" />
<!--<animateMotion from="0,0" to="241,122" dur="5s" fill="freeze" /> -->
</g>
<g>
<text x="940" y="442">1234</text>
<animateMotion from="0,0" to="-67,-391" dur="5s" fill="freeze" />
<g>
</g>
</defs>
<use xlink:href="#triangle" />
</svg>
First, make your own life easier and give the image a x/y position such that its center is at 0, i. e. x="-26.5" y="-48". Then the scale will not cause any change in positioning of the image. Move the <text> inside the <g> element, too, so the relative position of image and text remains constant.
Think of the coordinate origin of that group as the single point that is moved around, an it can be the same as the moving vertex of the triangle: transform="translate(967,491)".
After that, one animation can scale the image, and the other move the <g> element to its animated position. You can use the same coordinates as for the moving vertex.
<svg viewBox="0 0 1200 800">
<defs>
<g id="triangle">
<desc>Triangle</desc>
<polygon id="triangle_" points="967,491 738,449 724,603">
<animate attributeName="points" attributeType="XML"
begin="0s" dur="5s" from="967,491 738,449 724,603" to="900,100 738,449 724,603" fill="freeze" />
</polygon>
<g transform="translate(967,491)">
<animateTransform attributeName="transform" type="translate" attributeType="XML"
begin="0s" dur="5s" from="967,491" to="900,100" fill="freeze" />
<image xlink:href="http://www.alegralabs.com/human.png" x="-26.5" y="-48" width="53" height="98" transform="scale(0.5)" style="fill:#FFF">
<animateTransform attributeName="transform" type="scale" attributeType="XML"
begin="0s" dur="5s" from="0.5" to="0.2" fill="freeze" />
</image>
<text x="-27" y="-49">1234</text>
<g>
</g>
</defs>
<use xlink:href="#triangle" />
</svg>

scale to the right side

I'm trying an animation where a rectangle scales from 1 to 3 and then should scale back to 1.
But, the catch is the scaling should begin at top left corner and end at top right corner.
<rect x="10" y="10" width="40" height="20"
style="stroke: #000000; fill: none;">
<animateTransform attributeName="transform" attributeType="XML"
type="scale"
from="1" to="3"
begin="0s" dur="10s"
additive="sum"
/>
</rect>
I want to achieve this in pure SVG tags and no D3 or raphael.js. How can this be achieved?
I have tried many ways, but had got no good output.
Not quite sure if this is the effect you are after, you may need to clarify the description a little. But you could combine animations, and start one when another finishes with the begin tag... jsfiddle here... http://jsfiddle.net/kSYHH/ and http://jsfiddle.net/kSYHH/3/
<svg>
<rect x="10" y="10" width="40" height="20"
style="stroke: #000000; fill: none;">
<animateTransform attributeName="transform" attributeType="XML"
type="translate"
from="0" to="40"
begin="animout.end" dur="3s"
additive="sum"
fill="freeze"
/>
<animateTransform attributeName="transform" attributeType="XML"
id="animout"
type="scale"
from="1" to="3"
begin="0s" dur="3s"
additive="sum"
/>
<animateTransform attributeName="transform" attributeType="XML"
type="scale"
from="3" to="1"
begin="animout.end" dur="3s"
additive="sum"
fill="freeze"
/>
</rect>
</svg>
Its also worth anyone else looking into svg libs like Raphael.js Snap.js Pablo.js which make some bits easier, although you do mention you want to make it pure svg as such.

how to rotate rectangle in the centeral point of the circle

I try to rotate rectangle around his central point but I can't understand how it is working.
Is there simple code in svg that make the issue without Cos Sin function or complex code.
I try after some alot of testing and I finally sucsses but if I want to resize the retangle or to move it to centeral page all be mess,can you give me intentness how to do that?
thanks.
jsfiddle.net
my code:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="10" y="10" height="100" width="100"
style="stroke:#FF0000; fill: #9C4100">
<animateTransform
attributeName="transform"
begin="0s"
dur="40s"
type="rotate"
from="0 60 60"
to="360 60 60"
repeatCount="1"
/>
</rect>
<circle id="pointA" cx="60" cy="60" r="48" />
</svg>​
Center your images on origo and "transform" them to the desired position.
I believe you want something like this;
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g transform="translate(250,200)">
<rect x="-50" y="-50" height="100" width="100"
style="stroke:#FF0000; fill: #9C4100">
<animateTransform
attributeName="transform"
begin="0s"
dur="20s"
type="rotate"
from="0"
to="360"
repeatCount="1"
/>
<animateTransform attributeName="transform"
type="scale" from="1" to="2"
additive="sum" begin="0" dur="20s" fill="freeze"/>
</rect>
<circle id="pointA" cx="0" cy="0" r="48" />
</g>
</svg>

Resources