I have created a svg bar animation, but this motion is not looking similar like this , I know this can done with CSS3 animation. Here I need it with pure SVG code. How can I achieve with it?
Working Demo
<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"
viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<rect fill="#fff" width="3" height="100" transform="translate(0) rotate(180 3 50)">
<animate
attributeName="height"
attributeType="XML"
dur="1s"
from="30"
to="100"
repeatCount="indefinite"/>
</rect>
</svg>
Use values rather than from/to so that you can animate in both directions. I.e.
<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"
viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<rect fill="#fff" width="3" height="100" transform="translate(0) rotate(180 3 50)">
<animate
attributeName="height"
attributeType="XML"
dur="1s"
values="30;100;30"
repeatCount="indefinite"/>
</rect>
</svg>
Demo
Related
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>
My pattern is in Firefox not visible:
Top: Chrome
Bottom: Firefox
Svg Code (but please down a bit to see the image)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 120 120" version="1.1" viewBox="0 0 120 120" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{opacity:0.48;}
.st2{fill:#FFF99A;}
.st5{fill:url(#a);stroke:#007BFF;stroke-width:0.5;stroke-miterlimit:10;}
</style>
<pattern id="b" y="120" width="200" height="200" overflow="visible" patternUnits="userSpaceOnUse" viewBox="0 -200 200 200">
<rect class="st0" y="-200" width="200" height="200"/>
<rect class="st0" y="-200" width="200" height="200"/>
<g class="st1">
<rect class="st2" y="-100" width="200" height="100"/>
</g>
<g class="st1">
<rect class="st2" x="100" y="-200" width="100" height="200"/>
</g>
</pattern>
<pattern id="a" xlink:href="#b" patternTransform="matrix(.014142 -.014142 -.014142 -.014142 -16028 -559.29)">
</pattern>
<path class="st5" d="m87.5 87.5v23.1c0 3.5-2.6 6.4-6.1 6.8-21.7 2.6-42.3 0-50.3-1.2-2.1-0.3-3.6-2.1-3.6-4.2 0-5.6 0.1-16.7 0.5-24.4h23.5"/>
</svg>
Any idea why?
I found this question, but it really didn't change anything.
I've removed the pattern #aand now it works in FF too
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 120 120" version="1.1" viewBox="0 70 120 65" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{opacity:0.48;}
.st2{fill:#FFF99A;}
.st5{fill:url(#b);stroke:#007BFF;stroke-width:0.5;stroke-miterlimit:10;}
</style>
<pattern id="b" y="120" width="200" height="200" overflow="visible" patternUnits="userSpaceOnUse" viewBox="0 0 200 200" patternTransform="matrix(.014142 -.014142 -.014142 -.014142 -16028 -559.29)">
<rect class="st0" width="200" height="200"/>
<rect class="st0" width="200" height="200"/>
<g class="st1">
<rect class="st2" y="100" width="200" height="100"/>
</g>
<g class="st1">
<rect class="st2" x="100" width="100" height="200"/>
</g>
</pattern>
<path class="st5" d="m87.5 87.5v23.1c0 3.5-2.6 6.4-6.1 6.8-21.7 2.6-42.3 0-50.3-1.2-2.1-0.3-3.6-2.1-3.6-4.2 0-5.6 0.1-16.7 0.5-24.4h23.5"/>
</svg>
It's a bug in Firefox that affects patterns with viewBox x,y values that aren't 0 0.
So to fix this SVG replace the y value from the pattern's viewBox with 0 (viewBox="0 -200 200 200" -> viewBox="0 0 200 200"), and wrap the pattern contents in <g transform="translate(0, 200)"> which offsets the viewBox change.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 120 120" version="1.1" viewBox="0 0 120 120" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{opacity:0.48;}
.st2{fill:#FFF99A;}
.st5{fill:url(#a);stroke:#007BFF;stroke-width:0.5;stroke-miterlimit:10;}
</style>
<!-- remove negative -200 from viewBox -->
<pattern id="b" y="120" width="200" height="200" overflow="visible" patternUnits="userSpaceOnUse" viewBox="0 0 200 200">
<!-- wrap pattern contents with a group, offsetting the y value removed from viewBox -->
<g transform="translate(0, 200)">
<rect class="st0" y="-200" width="200" height="200"/>
<rect class="st0" y="-200" width="200" height="200"/>
<g class="st1">
<rect class="st2" y="-100" width="200" height="100"/>
</g>
<g class="st1">
<rect class="st2" x="100" y="-200" width="100" height="200"/>
</g>
</g>
</pattern>
<pattern id="a" xlink:href="#b" patternTransform="matrix(.014142 -.014142 -.014142 -.014142 -16028 -559.29)">
</pattern>
<path class="st5" d="m87.5 87.5v23.1c0 3.5-2.6 6.4-6.1 6.8-21.7 2.6-42.3 0-50.3-1.2-2.1-0.3-3.6-2.1-3.6-4.2 0-5.6 0.1-16.7 0.5-24.4h23.5"/>
</svg>
Looks like it has been reported here https://bugzilla.mozilla.org/show_bug.cgi?id=1193586
I want the yellow rectangle to be rotated 45 degrees (which it is), but I also want the direction of motion to rotate, so that the yellow rectangle appear to go "downhill" (down the blue line). I don't want it to keep moving horizontally.
<svg width="800" height="400" viewBox="0 0 800 400"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- decorative circles for the ends of the blue line. -->
<g transform="rotate(45, 400, 200)">
<path id="myPath" d="M150,200 L650,200" fill="none"
stroke="blue" stroke-width="5.6" />
<circle cx="150" cy="200" r="8.94" fill="blue" />
<circle cx="650" cy="200" r="8.94" fill="blue" />
</g>
<g>
<rect x="0" y="0"
fill="yellow" stroke="red" width="84" height="56"></rect>
<animateMotion dur="4s" repeatCount="1" rotate="45"
path="M150,200 L650,200" >
</animateMotion>
</g>
</svg>
Another way to do this is to put <mpath xlink:href="#myPath" /> as a sub-element of the animateMotion SVG element. In that case you can leave out path="M150,200 L650,200".
You mean like this? I've moved the animateMotion so it only applies to the rect and added a transform to the containing <g> element. I could have just put the rect in the other <g> element I guess which would have been simpler.
<svg width="800" height="400" viewBox="0 0 800 400"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- decorative circles for the ends of the blue line. -->
<g transform="rotate(45, 400, 200)">
<path id="myPath" d="M150,200 L650,200" fill="none"
stroke="blue" stroke-width="5.6" />
<circle cx="150" cy="200" r="8.94" fill="blue" />
<circle cx="650" cy="200" r="8.94" fill="blue" />
</g>
<g transform="rotate(45, 400, 200)">
<rect x="0" y="0"
fill="yellow" stroke="red" width="84" height="56">
<animateMotion dur="4s" repeatCount="1"
path="M150,200 L650,200" >
</animateMotion>
</rect>
</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 need help with this SVG code below that is beeing cut off in Firefox only. Chrome, IE work fine.
I tried several solutions already with no luck.
This SVG was exported from illustrator.
<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"
viewBox="0 0 13.4 30.3" style="enable-background:new 0 0 13.4 30.3;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_3_);}
.st1{clip-path:url(#SVGID_4_);fill:#76BE5A;}
.st2{clip-path:url(#SVGID_6_);fill:none;stroke:#76BE5A;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g>
<g>
<defs>
<rect id="SVGID_1_" x="-0.6" y="0.3" width="14" height="30"/>
</defs>
<defs>
<path id="SVGID_2_" d="M4.6,2c0.2-1.1,1.2-1.9,2.2-1.7c1,0.2,1.7,1.2,1.5,2.3L8.1,3.8C8,4.9,7,5.6,6,5.5c-1-0.2-1.7-1.2-1.5-2.3
L4.6,2"/>
</defs>
<clipPath id="SVGID_3_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<clipPath id="SVGID_4_" class="st0">
<use xlink:href="#SVGID_2_" style="overflow:visible;"/>
</clipPath>
<rect x="-0.6" y="-4.8" class="st1" width="14" height="15.3"/>
</g>
<g>
<defs>
<rect id="SVGID_5_" x="-0.6" y="0.3" width="14" height="30"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" style="overflow:visible;"/>
</clipPath>
<path class="st2" d="M12.4,17.5c-0.1-0.1-1.8-4.4-1.8-4.4L8.7,7.5L3.3,8.4l-0.5,4.7l-1.6,5.2 M5.1,16.6l1.8,12.7 M12.4,29.3
l-2.9-5.9l-0.8-5.9l-3.7-0.9"/>
</g>
</g>
</svg>
Thank you