Cannot apply animation on SVG g element - javascript

I have the following SVG file.
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="htntp://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="1000"
height="650"
id="svgContainer">
<g
id="truck">
<animate attributeName="fill" from="black" to="red" dur="5s"/>
<path
d="m 655.589,484.36218 -6.18561,-128.61524 -110.99241,-15.79583 -34.55321,-87.58893 -94.74579,0 3.03024,178.75619 -322.238663,2.0203 0.145305,51.22351 z"
id="body"
fill="#000000"
stroke="#000000"
stroke-width="1px"
stroke-linecap="butt"
stroke-linejoin="miter"
stroke-opacity="1" />
<animate attributeType="XML" attributeName="x" to="1000" begin="indefinite" dur="1s" />
<animate attributeType="XML" attributeName="y" to="1000" begin="indefinite" dur="1s" />
</g>
</svg>
</g>
</svg>
I just want to move it to some other place with animation, but it does not work. Is there something that I am missing here? (I want to animate the g element with everything inside. I removed the rest of the elements for the sake of simplicity.)

OK, I changed to animation here with following.
<animateTransform
attributeType="XML"
attributeName="transform"
type="translate"
from="0,0" to="1000,1000"
begin="0s" dur="1"
repeatCount="indefinite"/>
And it started to work.
UPDATE
I found a better solution. In the first one, after animation my group element is returning to its original position. With the follwing it stays where it is.
<animateMotion
from="0,0" to="500,0"
dur="4s" fill="freeze"/>

Related

Why has my animation SVG animation stopped changing color?

I have some SVG animation on my website. A rectangle gets bigger and smaller, rapidly changing to a random color, while the words "Buy our crap" jump out of it.
For some reason, it stopped changing color. I can't remember changing or deleting anything. Why did it stop? What can I do to fix it?
function rand(max){
return Math.floor(Math.random() * (max+1));
}
function init() {
let refreshRate = Math.random() *1000 + 50; // 10 times per second
setInterval(function(){document.getElementById("RectElement").setAttribute("fill","rgb("+rand(255)+", "+rand(255)+", "+rand(255)+")");},refreshRate);
}
window.document.onload = init;
<?xml version="1.0" standalone="no"?>
<svg width="8cm" height="3cm" viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg">
<desc>Example anim01 - demonstrate animation elements</desc>
<rect x="1" y="1" width="900" height="400"
fill="none" stroke="none" stroke-width="2" />
<!-- The following illustrates the use of the 'animate' element
to animate a rectangles x, y, and width attributes so that
the rectangle grows to ultimately fill the viewport. -->
<rect id="RectElement" x="300" y="100" width="300" height="100"
fill="rgb(0,255,0)" >
<animate attributeName="fill" begin="0" dur="1.3"
repeatCount="indefinite"/>
<animate attributeName="x" begin="0s" dur="1.3s"
fill="freeze" from="300" to="0" repeatCount="indefinite"/>
<animate attributeName="y" begin="0s" dur="1.3s"
fill="freeze" from="100" to="0" repeatCount="indefinite"/>
<animate attributeName="width" begin="0s" dur="1.3s"
fill="freeze" from="300" to="800" repeatCount="indefinite"/>
<animate attributeName="height" begin="0s" dur="1.3s"
fill="freeze" from="100" to="300" repeatCount="indefinite"/>
</rect>
<!-- Set up a new user coordinate system so that
the text string's origin is at (0,0), allowing
rotation and scale relative to the new origin -->
<g transform="translate(100,100)" >
<!-- The following illustrates the use of the 'set', 'animateMotion',
'animate' and 'animateTransform' elements. The 'text' element
below starts off hidden (i.e., invisible). At 3 seconds, it:
* becomes visible
* continuously moves diagonally across the viewport
* changes color from blue to dark red
* rotates from -30 to zero degrees
* scales by a factor of three. -->
<text id="TextElement" x="0" y="0"
font-family="Verdana" font-size="35.27" visibility="hidden" >
Buy our crap!
<set attributeName="visibility" to="visible"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
<animateMotion path="M 0 0 L 100 100"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
<animateTransform attributeName="transform"
type="rotate" from="-30" to="0"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
<animateTransform attributeName="transform"
type="scale" from="0.5" to="2" additive="sum"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
</text>
</g>
</svg>
The rectangle is not changing color. I'm pretty new to this, so please be patient and suggest anything that you think could improve this question in the comments.
There is no window.document.onload.
Change window.document.onload = init; to window.onload = init;.
GlobalEventHandlers.onload
Window: load event

How can I put random number values into "rgb()" for the svg "fill" attribute?

I have an svg element on my website, and I want to animate it so that it changes from a random color value to another random color value. What I have right now looks like this:
<?xml version="1.0" standalone="no"?>
<svg width="8cm" height="3cm" viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg">
<desc>Example anim01 - demonstrate animation elements</desc>
<rect x="1" y="1" width="900" height="400"
fill="none" stroke="none" stroke-width="2" />
<!-- The following illustrates the use of the 'animate' element
to animate a rectangles x, y, and width attributes so that
the rectangle grows to ultimately fill the viewport. -->
<rect id="RectElement" x="300" y="100" width="300" height="100"
fill="rgb(0,255,0)" >
<animate attributeName="fill" begin="0" dur="1.3"
fill="remove" from="rgb(0,255,0)" to="rgb(255,0,0)" repeatCount="indefinite"/>
<animate attributeName="x" begin="0s" dur="1.3s"
fill="freeze" from="300" to="0" repeatCount="indefinite"/>
<animate attributeName="y" begin="0s" dur="1.3s"
fill="freeze" from="100" to="0" repeatCount="indefinite"/>
<animate attributeName="width" begin="0s" dur="1.3s"
fill="freeze" from="300" to="800" repeatCount="indefinite"/>
<animate attributeName="height" begin="0s" dur="1.3s"
fill="freeze" from="100" to="300" repeatCount="indefinite"/>
</rect>
<!-- Set up a new user coordinate system so that
the text string's origin is at (0,0), allowing
rotation and scale relative to the new origin -->
<g transform="translate(100,100)" >
<!-- The following illustrates the use of the 'set', 'animateMotion',
'animate' and 'animateTransform' elements. The 'text' element
below starts off hidden (i.e., invisible). At 3 seconds, it:
* becomes visible
* continuously moves diagonally across the viewport
* changes color from blue to dark red
* rotates from -30 to zero degrees
* scales by a factor of three. -->
<text id="TextElement" x="0" y="0"
font-family="Verdana" font-size="35.27" visibility="hidden" >
Buy our crap!
<set attributeName="visibility" to="visible"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
<animateMotion path="M 0 0 L 100 100"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
<animateTransform attributeName="transform"
type="rotate" from="-30" to="0"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
<animateTransform attributeName="transform"
type="scale" from="0.5" to="2" additive="sum"
begin="0s" dur="1.3s" fill="freeze" repeatCount="indefinite"/>
</text>
</g>
</svg>
But what I want is instead for the rectangle to be assigned a random color value (something like "rgb(random #,random #,random #)").
How would I go about doing that to make sure that every single color is a possible outcome?
let refreshRate = 1300;
function rand(max){
return Math.floor(Math.random() * (max+1));
};
setInterval(function(){
document.getElementById("RectElement").setAttribute("fill","rgb("+rand(255)+", "+rand(255)+", "+rand(255)+")");
},refreshRate);

Two or more SVGs in a page. How can I animate them on button click?

Same SVG is repeated in carousel multiple times. Carousel is constructed in PHP using a while loop. How can I trigger animation at the click of a next/prev button in carousel?
My jQuery code is as below. It animates only the first <animate> tag. I think I must have explained my whole point.
jQuery(document).ready(function($){
$('.first').click(function(){
$('animate')[0].beginElement();
$('animateTransform')[0].beginElement();
});
});
My SVG code:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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 425 386" style="enable-background:new 0 0 425 386;" xml:space="preserve">
<polygon class="st0" points="356.4,330 399.3,370.8 399.3,82.5 357.3,106.5 "/>
<polygon class="st1" points="63.8,105 63.8,329.3 357.3,329.3 357.3,106.5 "/>
<polygon class="st2" points="21.8,369 62.5,329.3 357.3,329.3 399.3,370.8 20.9,370.8 "/>
<polygon class="st0" points="63.8,329.2 20.9,370.8 20.9,82.5 63.8,105 "/>
<g>
<line class="st3" id="line1" x1="65.2" y1="76.3" x2="180.9" y2="76.3"/>
<animate xlink:href="#line1" attributeName="x2" from="65" to="180.9" dur="2s" class="ani" />
<line class="st3" id="line2" x1="237.6" y1="76.3" x2="338.6" y2="76.3"/>
<animate xlink:href="#line2" attributeName="x2" from="250" to="338.6" dur="2s" class="ani" />
<text x="200" y="80" class="wt1">10'</text>
</g>
<g>
<g>
<text x="368" y="70" class="wt1">5'</text>
</g>
<line class="st3" id="line3" x1="352.1" y1="76.9" x2="362.6" y2="70.8"/>
<animate xlink:href="#line3" attributeName="x2" from="351" to="362.6" dur="3s" class="ani" />
<animate xlink:href="#line3" attributeName="y2" from="77" to="70.8" dur="3s" class="ani" />
<line class="st3" id="line4" x1="387.7" y1="58" x2="396.6" y2="51.9"/>
<animate xlink:href="#line4" attributeName="x2" from="388" to="396.6" dur="3s" class="ani" />
<animate xlink:href="#line4" attributeName="y2" from="58" to="51.9" dur="3s" class="ani" />
</g>
<g>
<ellipse class="st4" id="elli1" cx="210.1" cy="344.8" rx="37.2" ry="4.5"/>
<animate xlink:href="#elli1" attributeName="rx" from="7.2" to="37.2" dur="3s" class="ani" />
<animate xlink:href="#elli1" attributeName="ry" from="0.2" to="4.5" dur="3s" class="ani" />
<g id="box1" transform="translate(0, 0)">
<polygon class="st5" points="230.8,307.5 213,307.5 213,307.9 213,314.1 207,314.1 207,307.5 189.2,307.5 188.9,345.4 231.2,345.4
"/>
<path class="st6" d="M207,307.3v-6.9c0-0.2,6-0.1,6-0.1v7.1h17.8l-8-7.1h-26.7l-7,7.1H207V307.3z"/>
<polygon class="st7" points="207,314.1 213,314.1 213,307.9 213,307.5 207,307.5 "/>
<path class="st8" d="M207,300.4v6.9v0.1h6v-7.1C213,300.4,207,300.2,207,300.4z"/>
<animateTransform xlink:href="#box1" attributeName="transform" type="translate" from="0 -70" to="0 0" dur="3s" class="ani" />
</g>
</g>
</svg>
You forgot to add a question style sheet. I restored the color values of the svg parts according to the figure.
Since all animations should start simultaneously at the click of a mouse, you can do without Javascript
To do this, add a launch command to each animation begin="Layer_1.click"
.container {
width:75%;
height:75%;
}
.st0 {fill:#C8C8C8;}
.st1 {fill:#E7E7E7;}
.st2 {fill:#6A6A6A;}
.st3 {stroke:#F6C44A;}
.st4 {fill:#323232;}
.st5 {fill:#CB9751;}
.st6 {fill:#E0B268;}
.st7 {fill:#C8A066;}
.st8 {fill:#E3C084;}
<div class="container">
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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 425 386" style="enable-background:new 0 0 425 386;" xml:space="preserve">
<polygon class="st0" points="356.4,330 399.3,370.8 399.3,82.5 357.3,106.5 "/>
<polygon class="st1" points="63.8,105 63.8,329.3 357.3,329.3 357.3,106.5 "/>
<polygon class="st2" points="21.8,369 62.5,329.3 357.3,329.3 399.3,370.8 20.9,370.8 "/>
<polygon class="st0" points="63.8,329.2 20.9,370.8 20.9,82.5 63.8,105 "/>
<g>
<line class="st3" id="line1" x1="65.2" y1="76.3" x2="180.9" y2="76.3"/>
<animate xlink:href="#line1" attributeName="x2" from="65" to="180.9" begin="Layer_1.click" dur="2s" class="ani" />
<line class="st3" id="line2" x1="237.6" y1="76.3" x2="338.6" y2="76.3"/>
<animate xlink:href="#line2" attributeName="x2" from="250" to="338.6" begin="Layer_1.click" dur="2s" class="ani" />
<text x="200" y="80" class="wt1">10'</text>
</g>
<g>
<g>
<text x="368" y="70" class="wt1">5'</text>
</g>
<line class="st3" id="line3" x1="352.1" y1="76.9" x2="362.6" y2="70.8"/>
<animate xlink:href="#line3" attributeName="x2" from="351" to="362.6" begin="Layer_1.click" dur="3s" class="ani" />
<animate xlink:href="#line3" attributeName="y2" from="77" to="70.8" begin="Layer_1.click" dur="3s" class="ani" />
<line class="st3" id="line4" x1="387.7" y1="58" x2="396.6" y2="51.9"/>
<animate xlink:href="#line4" attributeName="x2" from="388" to="396.6" begin="Layer_1.click" dur="3s" class="ani" />
<animate xlink:href="#line4" attributeName="y2" from="58" to="51.9" begin="Layer_1.click" dur="3s" class="ani" />
</g>
<g>
<ellipse class="st4" id="elli1" cx="210.1" cy="344.8" rx="37.2" ry="4.5"/>
<animate xlink:href="#elli1" attributeName="rx" from="7.2" to="37.2" begin="Layer_1.click" dur="3s" class="ani" />
<animate xlink:href="#elli1" attributeName="ry" from="0.2" to="4.5" begin="Layer_1.click" dur="3s" class="ani" />
<g id="box1" transform="translate(0, 0)">
<polygon class="st5" points="230.8,307.5 213,307.5 213,307.9 213,314.1 207,314.1 207,307.5 189.2,307.5 188.9,345.4 231.2,345.4
"/>
<path class="st6" d="M207,307.3v-6.9c0-0.2,6-0.1,6-0.1v7.1h17.8l-8-7.1h-26.7l-7,7.1H207V307.3z"/>
<polygon class="st7" points="207,314.1 213,314.1 213,307.9 213,307.5 207,307.5 "/>
<path class="st8" d="M207,300.4v6.9v0.1h6v-7.1C213,300.4,207,300.2,207,300.4z"/>
<animateTransform xlink:href="#box1" attributeName="transform" type="translate" from="0 -70" to="0 0" begin="Layer_1.click" dur="3s" class="ani" />
</g>
</g>
</svg>
</div>

encircle the object depending on the set percentages

I have such task: a circle without borders and we get some percentages (from user or just enter by ourself - doesn't mater), after it the border of circle should be filled depending on this number.
I'm trying to use SVG. But it's not clear for me. It doesn't work with persentages and I don't know how to get right number for all length
<svg width="270" height="270">
<circle
r="115" cx="135" cy="135"
fill="none";
stroke="blue"
stroke-width="15"
stroke-dasharray="1000"
stroke-dashoffset="0%">
<animate
attributeName="stroke-dashoffset"
attributeType="CSS"
from="1000" to="00"
begin="0s" dur="2s"/>
</svg>
Image to see how it shoul be
One observation : the value of stroke-dasharray if you want it to be full should be the circumference of the circle in pixels. So 2*Pi*r.
The stroke-dashoffset is the amount of pixels that are offset from the stroke, so for example :
A circle of 115px radius will have a circumference of 2*Pi*115=722.56 723px.
If we want to fill it at 75%, we must offset the stroke by 723*(1-0.75)=180.75 181px.
Examples below :
<svg id="svg" width="270" height="270">
<circle id="circle"
r="115" cx="135" cy="135"
fill="none";
stroke="blue"
stroke-dasharray="723"
stroke-dashoffset="361"
stroke-width="15">
<animate id="animation"
attributeName="stroke-dashoffset"
attributeType="CSS"
begin="0s"
to="361"
from="723"
dur="2s"/>
</circle>
<text x="50%" y="50%" text-anchor="middle" stroke="#000" stroke-width="2px" dy=".3em">50%</text>
</svg>
<svg id="svg" width="270" height="270">
<circle id="circle"
r="115" cx="135" cy="135"
fill="none";
stroke="blue"
stroke-dasharray="723"
stroke-dashoffset="181"
stroke-width="15">
<animate id="animation"
attributeName="stroke-dashoffset"
attributeType="CSS"
begin="0s"
to="181"
from="723"
dur="2s"/>
</circle>
<text x="50%" y="50%" text-anchor="middle" stroke="#000" stroke-width="2px" dy=".3em">75%</text>
</svg>

SVG mouseover does not work on nested elements

I would like to make it so that when you hover over a nested group #sec7kpi-c and then further into the text inside the animation effect when you mouseover continues.
<g transform="matrix(1 0 0 1 150 150)" id="sec7kpi">
<g transform="matrix(1 0 0 1 0 0)" id="sec7kpi-c">
<ellipse fill="#372356" stroke="#27AE60" stroke-width="16" stroke-miterlimit="10" cx="0" cy="0" rx="71" ry="71" />
<text id="sec7text" x="-33" y="15" fill="#27AE60" font-family="LatoRegular" font-size="38.8363">KPI</text>
</g>
</g>
<animateTransform attributeType="XML"
xlink:href="#sec7kpi-c"
attributeName="transform"
type="scale"
dur="1s"
from="1"
to="2"
restart="whenNotActive"
begin="mouseover"
calcMode="spline"
values="1;1.5;1"
keyTimes="0;0.5;1"
keySplines=".16,.59,.46,.98;.88,.27,.37,1.52"
fill="freeze"
id="c-hover">
</animateTransform>
You can set the text pointer-events property to none to avoid this.
Note that your keySplines values are invalid (they must all be <= 1) so your animation should not work as written (if it does you should raise a bug on that UA). I've corrected that in my version.
Also I've removed the from and to attributes as they are ignored if you provide a values attribute.
body, html {
width: 100%;
height: 100%;
}
<svg width="100%" height="100%">
<g transform="matrix(1 0 0 1 150 150)" id="sec7kpi">
<g transform="matrix(1 0 0 1 0 0)" id="sec7kpi-c">
<ellipse fill="#372356" stroke="#27AE60" stroke-width="16" stroke-miterlimit="10" cx="0" cy="0" rx="71" ry="71" />
<text id="sec7text" x="-33" y="15" fill="#27AE60" font-family="LatoRegular" font-size="38.8363" pointer-events="none">KPI</text>
</g>
</g>
<animateTransform attributeType="XML"
xlink:href="#sec7kpi-c"
attributeName="transform"
type="scale"
dur="1s"
restart="whenNotActive"
begin="mouseover"
calcMode="spline"
values="1;1.5;1"
keyTimes="0;0.5;1"
keySplines=".16,.59,.46,.98;.88,.27,.37,1"
fill="freeze"
id="c-hover">
</animateTransform>
</svg>

Categories

Resources