Capital letters in html attributs - html

I want to add animation on my chart.I'm using jquery(append) to add animation tag on my html page but the animation doesn't work.
The animation tag attributs such as attributename or repeatcount have one capital letter and if i add this with attr method or another the capital letter is ignored and the animation doesn't work.
<rect fill="#555" width="2" height="2" x="0" y="0">
<animate attributename="x" from="0" to="0" attributename="XML" dur="1.5s" repeatcount="indefinite"></animate>
<animate attributename="y" from="0" to="0" attributetype="XML" dur="1.5s" repeatcount="indefinite"></animate>
</rect>

That's because you're moving from 0 to 0. If you try to put the capital letters and tell the box to move (let's say from 0 to 2) you'll see something :)
<svg viewBox="0 0 10 10">
<rect fill="#555" width="2" height="2" x="0" y="0">
<animate attributeName="x" from="0" to="2" attributeName="XML" dur="1.5s" repeatCount="indefinite"></animate>
<animate attributeName="y" from="0" to="2" attributeType="XML" dur="1.5s" repeatCount="indefinite"></animate>
</rect>
</svg>

Related

How to make transparent text appear in SVG

<svg>
<text x="0" y="50" font-family="Verdana" font-size="35" fill="blue" opacity="0">Hello</text>
<animate attributeName="opacity" begin="click" dur="0.3s" from="0" to="1" restart="never" fill="freeze"></animate>
</svg>
Above is the code, I want to use SVG to make a transparent text appear. I am new to coding especially SVG, thanks for any help and creative thoughts.
The easiest thing is to make the animate element a child of the text element.
<svg>
<text x="0" y="50" font-family="Verdana" font-size="35" fill="blue" opacity="0">Hello
<animate attributeName="opacity" begin="click" dur="0.3s" from="0" to="1" restart="never" fill="freeze"></animate>
</text>
</svg>
Otherwise you could add a href or xlink:href attribute to the animate tag to tell it that it's the text element you want to affect
<svg>
<text id="t" x="0" y="50" font-family="Verdana" font-size="35" fill="blue" opacity="0">Hello
</text>
<animate attributeName="opacity" href="#t" begin="click" dur="0.3s" from="0" to="1" restart="never" fill="freeze"></animate>
</svg>

Svg fill animation for the given path

I am trying to animate an arrow from left to right.The code of my arrow's path is given below:
<svg id="svg_circle" width="100%" height="100%" viewBox = '0 0 450 400'>
<g transform = "translate(0,0)">
<path class="path" stroke="#F0F0F0" fill="#fff" stroke-width="1" opacity="1" d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,-13.57138l34.2665,-0.47295l-0.0208,-7.14282l14.50618,14.42226l-14.95643,15.04345l-0.20382,-8.74944z" id="svg_1">
<animate id="project_anim1" attributeName="fill" from="#fff" to="#4DAF4C" begin="1s" dur="1s" fill="freeze" repeatCount="1"></animate>
</path>
</g>
</svg>
The above is the svg path content of my arrow.
Kindly anyone help me how to fill the path from left to right. Waiting for quick response
You can do this by just animating the <stop>s in a <linear gradient>.
<svg id="svg_circle" width="100%" height="100%" viewBox = '0 0 450 400'>
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#4DAF4C">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="#fff">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<path class="path" stroke="#F0F0F0" fill="url(#left-to-right)" stroke-width="1" opacity="1" d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,-13.57138l34.2665,-0.47295l-0.0208,-7.14282l14.50618,14.42226l-14.95643,15.04345l-0.20382,-8.74944z" id="svg_1" />
</svg>
How this works is that we have a linear gradient representing an abrupt change from green to white. The <animation> elements move the position, of that abrupt change, from the left of the arrow (offset=0) to the right (offset="1").
Note that SVG <animate> elements will not work in IE. If you need to support IE, you will need to use the FakeSmile library or use a different method (such as a JS animation library).
Building upon andreas' answer. You can cover your arrow with a shape that is animated to uncover it.
<svg id="svg_circle" width="450" height="400" viewBox='0 0 450 400'>
<path class="path" stroke="#F0F0F0" fill="#fff"
stroke-width="1" opacity="1" id="svg_1"
d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,
-13.57138l34.2665,-0.47295l-0.0208,-7.14282
l14.50618,14.42226l-14.95643,15.04345l-0.20382,
-8.74944z">
<animate id="project_anim1" attributeName="fill"
from="#fff" to="#4DAF4C" begin="0s" dur="3s"
fill="freeze" repeatCount="indefinite" />
</path>
<rect x="0" y="0" width="53" height="34" fill="#fff">
<animate attributeType="XML" attributeName="x"
from="0" to="53" begin="0s" dur="3s"
repeatCount="indefinite" />
<animate attributeType="XML" attributeName="width"
from="53" to="0" begin="0s" dur="3s"
repeatCount="indefinite" />
</rect>
</svg>
I don't think this is possible with the fill attribute. But instead, you can invert your SVG path to a rectangle with a triangle like hole. Now you just need a second element behind that path, where you can simply animate the scale in x-direction, to fill the hole from left to right.
Here is an image showing the technique:
An here is a working example:
<svg width="100%" height="100%" viewBox='0 0 450 400'>
<rect x="0" y="0" width="1" height="22" style="fill: black;" >
<animateTransform attributeName="transform" type="scale" from="1 1" to="50 1" begin="0s" dur="2s" repeatCount="indefinite" />
</rect>
<path fill="#ffffff" d="M0,0v29.8h86V0H0z M6.5,25V5.5L48.8,25H6.5z"/>
</svg>
Note: The answer was updated from triangle to arrow, I won't update my answer as the technique is the same for every shape.
<svg id="svg_circle" width="100%" height="100%" viewBox = '0 0 450 400'>
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#4DAF4C">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="#fff">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<path class="path" stroke="#F0F0F0" fill="url(#left-to-right)" stroke-width="1" opacity="1" d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,-13.57138l34.2665,-0.47295l-0.0208,-7.14282l14.50618,14.42226l-14.95643,15.04345l-0.20382,-8.74944z" id="svg_1" />
</svg>

Toggle SVG animation effect when click the button

I'm a SVG beginner so please bear with me.
Basically, I wish to animate a triangle to move from top to bottom when click and move from bottom to top if click again.
My problem is now I can only move a triangle from top to bottom by clicking it. Can anyone suggest a solution to this issue? Any guidance would be appreciated.
<svg viewBox="0 0 24 24" preserveAspectRatio="none">
<polygon points="2,-5 12,6 22,-5" fill="#000">
<animate attributeName="points" attributeType="XML"
from="2,-5 12,6 22,-5" to="2,0 12,11 22,0"
begin="click" dur="0.5s"
fill="freeze">
</animate>
</polygon>
</svg>
Or click this link: jsfiddle
Here's a SMIL only answer. If you want IE support, add fakeSmile.
<svg viewBox="0 0 24 24" preserveAspectRatio="none">
<polygon points="2,0 12,11 22,0" fill="#000" display="none">
<animate id="a2" attributeName="points" attributeType="XML"
from="2,0 12,11 22,0" to="2,-5 12,6 22,-5"
begin="click" dur="0.5s"
fill="freeze">
</animate>
<set attributeName="display" to="block" begin="a1.end" fill="freeze" />
<set attributeName="display" to="none" begin="a2.end" fill="freeze" />
<set attributeName="points" to="2,0 12,11 22,0" begin="a2.end" fill="freeze" />
</polygon>
<polygon points="2,-5 12,6 22,-5" fill="#000">
<animate id="a1" attributeName="points" attributeType="XML"
from="2,-5 12,6 22,-5" to="2,0 12,11 22,0"
begin="click" dur="0.5s"
fill="freeze">
</animate>
<set attributeName="display" to="none" begin="a1.end" fill="freeze" />
<set attributeName="points" to="2,-5 12,6 22,-5" begin="a1.end" fill="freeze" />
<set attributeName="display" to="block" begin="a2.end" fill="freeze" />
</polygon>
</svg>
I think that it's not possible with basic svg animate elements, you will need javascript.
(Actually there is what R.Longson proposed in comment)
A dirty way could consist to add a second animate, which will make your element animate to the original step, and trigger the right animate.beginElement() method on click of your <polygon>.
But you will need to keep a reference of the current state you are in, so in the following example, I added a big_state property to the polygon object.
var poly = document.querySelector('polygon');
poly.onclick = function() {
var anims = this.querySelectorAll('animate');
anims[+!!this.big_state].beginElement();
this.big_state = !this.big_state;
}
<svg viewBox="0 0 24 24" preserveAspectRatio="none">
<script type="text/ecmascript" xlink:href="FakeSmile-master/smil.user.js" />
<polygon points="2,-5 12,6 22,-5" fill="#000">
<animate attributeName="points" attributeType="XML" from="2,-5 12,6 22,-5" to="2,0 12,11 22,0" begin="indefinite" dur="0.5s" fill="freeze" id="bigger" />
<animate attributeName="points" attributeType="XML" from="2,0 12,11 22,0" to="2,-5 12,6 22,-5" begin="indefinite" dur="0.5s" fill="freeze" id="smaller" />
</polygon>
</svg>

SVG animation pattern - Traffic light

I want to animate a repeating traffic light just like in real life. I am changing the opacity from dark to brighter to display which light is on. Which works but it doesn't repeat.
Pattern I want
Redlight for 6 seconds...turn off
then begin Yellowlight for 3 seconds...turn off
then begin Greenlight for 6 seconds...turn off
Then back to Yellowlight for 3 seconds...turn off
Then back to Redlight for 6 seconds ...turn off
and the pattern keeps repeating.
Pattern I have
Redlight begin at 0s for 2 seconds ...then turn off
Yellowlight begin at 2s for 2 seconds...then turn off
Greenlight begin at 4s for 2 seconds...then turn off
They all stay off (no repeat)
The SVG code (for the pattern I have):
<svg>
<line x1="100" y1="100" x2="400" y2="100" style="stroke: green; stroke-width:50" />
<line x1="400" y1="0" x2="400" y2="600" style="stroke: green; stroke-width:50" />
<rect x="300" y="600" height="100" width="200" fill="green"></rect>
<rect id="stoplight" x="30" y="0" height="308" width="100"></rect>
<rect id="redlight" x="55" y="25" height="60" width="50"></rect>
<animate xlink:href="#redlight" id="redlight" attributeName="opacity" from=".3" to="1" dur="2s" begin="0s"/>
<rect id="yellowlight" x="55" y="125" height="60" width="50"></rect>
<animate xlink:href="#yellowlight" id="yellowlight" attributeName="opacity" from=".3" to="1" dur="2s" begin="2s"/>
<rect id="greenlight" x="55" y="225" height="60" width="50"></rect>
<animate xlink:href="#greenlight" id="greenlight" attributeName="opacity" from=".3" to="1" dur="2s" begin= "4s" />
</svg>
We just started learning SVG so I'm just a beginner.
JSFiddle
Update Edited the code with repeating lights working. Issues with the pattern, the yellow light transitions back to red light.
Updated: JSFiddle
You've multiple elements with the same id which is invalid. After fixing that you can target the animation end correctly e.g.
<rect id="stoplight" x="30" y="0" height="308" width="100"></rect>
<rect id="redlight" x="55" y="25" height="60" width="50"></rect>
<animate xlink:href="#redlight" id="redlight2" attributeName="opacity" from=".3" to="1" dur="2s" begin="0s;greenlight2.end"/>
<rect id="yellowlight" x="55" y="125" height="60" width="50"></rect>
<animate xlink:href="#yellowlight" id="yellowlight2" attributeName="opacity" from=".3" to="1" dur="2s" begin="2s"/>
<rect id="greenlight" x="55" y="225" height="60" width="50"></rect>
<animate xlink:href="#greenlight" id="greenlight2" attributeName="opacity" from=".3" to="1" dur="2s" begin="4s" />

How to morph a SVG diamond into a circle

I've recently been dipping my toe into SVGs and I'm currently trying to morph a diamond into a circle when the user hovers over it.
I found this tutorial over at CSS Tricks
I've noticed that they're using points to do the animation however my SVG shapes are:
<circle cx="49.873" cy="50.155" r="49.845"/>
and
<rect x="15.211" y="14.798" transform="matrix(0.7071 -0.7071 0.7071 0.7071 -20.8426 50.3112)" width="70.198" height="71.034"/>
Is there a way to do this? How would I get the points of these shapes so I could follow the CSS Tricks tutorial?
For those interested:
<svg viewBox="0 0 300 300" width="500" height="500" style="border:1px solid red;"preserveAspectRatio="xMinYMax meet">
<rect id="shape2" rx="0" y="0" x="100" width="50" height="50" transform="rotate(45)">
<animate begin="shape2.mouseover" attributeName="rx" dur="700ms" to="50%" fill="freeze"/>
<animate begin="shape2.mouseout" attributeName="rx" dur="700ms" to="0" fill="freeze"/>
</rect>
</svg>
http://jsfiddle.net/4e71gra6/
Extending the first answer by user1788364:
With saving square value of shape:
https://jsfiddle.net/HoretskiyDima/xfat6oc2/13/
<svg viewBox="0 0 300 300" width="500" height="500" style="border:1px solid red;"preserveAspectRatio="xMinYMax meet">
<rect id="shape2" rx="0" y="0" x="100" width="50" height="50" transform="rotate(45)">
<!-- Making cirle from rectangle -->
<animate begin="shape2.mouseover" attributeName="rx" dur="2000ms" to="50%" fill="freeze"/>
<animate begin="shape2.mouseout" attributeName="rx" dur="325ms" to="0" fill="freeze"/>
<!-- In order to save square value, we need bigger radius then rectangle -->
<!-- S = width * height -->
<!-- S = PI * r^2 -->
<!-- d = r * 2 = sqrt(S/PI) * 2 = 56 -->
<animate begin="shape2.mouseover" attributeName="width" dur="375ms" to="56" fill="freeze"/>
<animate begin="shape2.mouseout;370ms" attributeName="width" dur="675ms" to="50" fill="freeze"/>
<animate begin="shape2.mouseover" attributeName="height" dur="375ms" to="56" fill="freeze"/>
<animate begin="shape2.mouseout;370ms" attributeName="height" dur="675ms" to="50" fill="freeze"/>
<!-- In order to pin shape center position on the screenm we need to move back on half of delta radius -->
<!-- (56 - 50) / 2 = 3 -->
<animate begin="shape2.mouseover" attributeName="x" dur="375ms" to="97" fill="freeze"/>
<animate begin="shape2.mouseout" attributeName="x" dur="675ms" to="100" fill="freeze"/>
<animate begin="shape2.mouseover" attributeName="y" dur="375ms" to="-3" fill="freeze"/>
<animate begin="shape2.mouseout" attributeName="y" dur="675ms" to="0" fill="freeze"/>
<!-- TODO: "rx" attribute animation timing working strange. -->
</rect>
</svg>