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>
Related
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>
below i create a simple fiddle with svg animation:
<svg width="250" height="250" viewbox="0 0 20 20">
<line x1="10" y1="0" x2="10" y2="10"style="stroke:rgb(255,0,0); stroke-width:1">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 10 10" to="360 10 10" dur="7.5s" repeatCount="indefinite" />
</line>
<circle cx="5" cy="5" r="1" style="fill:rgb(0,255,0);"/>
<circle cx="15" cy="15" r="1" style="fill:rgb(0,0,255);"/>
</svg>
My question is: is there a way that I can make blue and red point bump (change their color for example) when red line hover them?
Thank you
This is my solution: I'm creating a mask with the line. There are 2 extra circles (fill:gold) that are masked by the line.
I'm putting the animated line inside a <g stroke="red"> because I want the used line to be white.
svg{border:1px solid;}
<svg width="250" height="250" viewbox="0 0 20 20">
<circle cx="5" cy="5" r="1" style="fill:rgb(0,255,0);" />
<circle cx="15" cy="15" r="1" style="fill:rgb(0,0,255);"/>
<mask id="mask">
<use xlink:href="#L" style="stroke:white"/>
</mask>
<g stroke="red">
<line id="L" x1="10" y1="0" x2="10" y2="10" >
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 10 10" to="360 10 10" dur="7.5s" repeatCount="indefinite" />
</line>
</g>
<g style="fill:gold;mask: url(#mask)">
<circle cx="5" cy="5" r="1" />
<circle cx="15" cy="15" r="1"/>
</g>
</svg>
How do I use animateTransform in an SVG to scale an object from the center point instead of the upper-left corner?
Example:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px">
<circle style="fill:blue;" cx="50" cy="50" r="45">
<animateTransform attributeName="transform"
type="scale"
from="0 0"
to="1 1"
begin="0s"
dur="1s"
repeatCount="indefinite"
/>
</circle>
</svg>
(Codepen: http://codepen.io/anon/pen/wKwrPg?editors=100)
Change your scaling transform to use additive="sum" and apply an additional transform that translates the circle to the center of the image. So instead of defining the shape at the center of the image, define its center to be 0 0 and then use the transform attribute to translate it to 50, 50 (the exact center of your particular image).
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px">
<circle style="fill:blue;" cx="0" cy="0" r="45" transform="translate(50 50)">
<animateTransform attributeName="transform"
type="scale"
additive="sum"
from="0 0"
to="1 1"
begin="0s"
dur="1s"
repeatCount="indefinite"
/>
</circle>
</svg>
Here's another example using the defs and use tags to reuse the circle definition:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px">
<defs>
<circle id="def-circle" style="fill:blue;" cx="0" cy="0" r="45" />
</defs>
<use xlink:href="#def-circle" transform="translate(50 50)">
<animateTransform attributeName="transform"
type="scale"
additive="sum"
from="0 0"
to="1 1"
beg="0s"
dur="1s"
repeatCount="indefinite" />
</use>
</svg>
You could also have done that with the help of CSS styles and transform-origin property.
The benefit is that you do not have to calculate coordinates and translate your objects.
<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<style>
#logo { transform-origin: center; }
</style>
<g id="logo">
<animateTransform attributeName="transform" begin="0s" type="scale" dur="2s" from="1" to=".5" repeatCount="indefinite"/>
<circle r="8" cx="12" cy="12" />
</g>
</svg>
#logo {
transform-origin: center;
}
<svg version="1.1" viewBox="0 0 24 24" width="100%" height="100px" xmlns="http://www.w3.org/2000/svg">
<g id="logo">
<animateTransform attributeName="transform" begin="0s" type="scale" dur="2s" from="1" to=".5" repeatCount="indefinite"/>
<circle r="8" cx="12" cy="12" />
</g>
</svg>
In your specific case, yet another way would be to animate the radius of the circle itself:
<circle r="0" cx="50" cy="50">
<animate attributeName="r" from="0" to ="10" begin="1s" dur="300ms" fill="freeze" />
</circle>
Thanks to Robert Longson for this answer.
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.
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>