SVG mouseover does not work on nested elements - javascript

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>

Related

How to position an SVG circle along another circle's path

I'm building a Gauge chart in a presentational component in React.
I just need to pass it a percentage and let the component do the rest. I can't use any animations because I'm taking a screenshot of the component to place the image in a Powerpoint presentation.
Here's a screenshot of what I'm trying to do:
As you can see in my code snippet, the circle <marker> is being positioned at the end of the grey <path> instead of at the end of the green <path>. How could I position the circle so it sits at the stroke-linecap of the green <path> as in the image above?
Here's the HTML code I have so far:
<div style="width:400px">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker
id="dot"
viewBox="0 0 10 10"
refX="4"
refY="4"
markerWidth="4"
markerHeight="4"
>
<circle
cx="4"
cy="4"
r="2"
fill="#FFFFFF"
stroke="#008000"
stroke-width="2"
/>
</marker>
</defs>
<path d="M20,60a35,35 0 1,1 60,0" stroke="#D3D7DB" stroke-width="4" fill="none" stroke-linecap="round"></path>
<path d="M20,60a35,35 0 1,1 60,0" stroke="#008000" stroke-width="6" pathLength="100" fill="none" stroke-linecap="round" stroke-dasharray="75 35" marker-end="url(#dot)"></path>
</svg>
</div>
You can do it all in SVG by setting pathLength and using animationMotion to position the circle.
Some JavaScript and a W3C standard Web Component (supported in all modern Browsers) help in putting multiple gauges on screen and making them dynamic.
customElements.define("svg-gauge", class extends HTMLElement {
connectedCallback() {
let speed = 0.5; // set to 0.0001 for instant display!
let arc = "M20,60a35,35 0 1,1 60,0";
let col = this.getAttribute("color") || "green";
this.innerHTML =
`<input type="range" min="0" max="100" step="5" value="0"`+ // delete 2 lines
` oninput="this.parentNode.percent=this.value" /><br>`+ // just for demo
`<svg viewbox="0 0 100 100">
<path d="${arc}" stroke="grey" stroke-width="6" fill="none" stroke-linecap="round"></path>
<path id="P" d="${arc}" stroke="${col}" stroke-width="8" pathLength="100" fill="none" stroke-linecap="round" stroke-dasharray="75 35"/>
<circle stroke="${col}" cx="0" cy="0" fill="#fff" r="4" stroke-width="3">
<animateMotion dur="${speed}s" path="${arc}" keyPoints="0;0.75" fill="freeze" keyTimes="0;1" calcMode="linear"/>
</circle>
<text x="50%" y="40%" text-anchor="middle">XXX</text>
</svg>`;
this.style.display='inline-block';
this.percent = this.getAttribute("value") || "50";
}
set percent(val = 0) {
this.setAttribute("value", val);
let dash = val + " " + (105 - val);
this.querySelector("#P").setAttribute('stroke-dasharray', dash);
this.querySelector("animateMotion").setAttribute('keyPoints', '0;'+val/100);
this.querySelector("text").innerHTML =`${val} %`;
this.querySelector("animateMotion").beginElement();
this.querySelector("input").value = val;
}
})
<svg-gauge value="35" color="red" ></svg-gauge>
<svg-gauge value="50" color="orange"></svg-gauge>
<svg-gauge value="75" color="green" ></svg-gauge>
I went ahead and accepted Danny '365CSI' Engelman's answer above, but just in case anyone wants to do this without the animations here is how I ended up implementing it:
<div style="width:400px">
<svg viewBox="0 -10 100 100" xmlns="http://www.w3.org/2000/svg">
<path d="M20,60a35,35 0 1,1 60,0" stroke="#D3D7DB" stroke-width="4" fill="none" stroke-linecap="round"></path>
<path d="M20,60a35,35 0 1,1 60,0" stroke="#008000" stroke-width="6" pathLength="100" fill="none" stroke-linecap="round" stroke-dasharray="50 85"></path>
<circle
cx="0"
cy="0"
r="6"
stroke-width="6"
fill="#FFFFFF"
stroke="#008000"
>
<animateMotion
begin="0s"
dur="infinite"
repeatCount="infinite"
keyPoints="0.5;0.5"
fill="freeze"
keyTimes="0;1"
calcMode="linear"
path="M20,60a35,35 0 1,1 60,0"
></animateMotion>
</circle>
</svg>
</div>

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>

Change animated object

I have a svg animation like this:
<svg width="500" height="350" viewBox="0 0 500 350">
<path id="motionPath" fill="none" stroke="#000000" stroke-miterlimit="10" d="M202.4,58.3c-13.8,0.1-33.3,0.4-44.8,9.2
c-14,10.7-26.2,29.2-31.9,45.6c-7.8,22.2-13.5,48-3.5,70.2c12.8,28.2,47.1,43.6,68.8,63.6c19.6,18.1,43.4,26.1,69.5,29.4
c21.7,2.7,43.6,3.3,65.4,4.7c19.4,1.3,33.9-7.7,51.2-15.3c24.4-10.7,38.2-44,40.9-68.9c1.8-16.7,3.4-34.9-10.3-46.5
c-9.5-8-22.6-8.1-33.2-14.1c-13.7-7.7-27.4-17.2-39.7-26.8c-5.4-4.2-10.4-8.8-15.8-12.9c-4.5-3.5-8.1-8.3-13.2-11
c-6.2-3.3-14.3-5.4-20.9-8.2c-5-2.1-9.5-5.2-14.3-7.6c-6.5-3.3-12.1-7.4-19.3-8.9c-6-1.2-12.4-1.3-18.6-1.5
C222.5,59,212.5,57.8,202.4,58.3"/>
<circle id="circle" r="10" cx="0" cy="0" fill="tomato" />
<animateMotion
xlink:href="#circle"
dur="5s"
begin="0s"
fill="freeze"
repeatCount="indefinite">
<mpath xlink:href="#motionPath" />
</animateMotion>
</svg>
But instead of circle, I have some svg-image, and I need to change this image to another image in some stage of animation.
<svg width="50" height="35" viewBox="0 0 500 350">
<path id="motionPath1" fill="none" stroke="rgba(255, 255, 255, 0.3)" stroke-miterlimit="10" d="M 100 50 C 150 600 650 600 700 50 "/>
<foreignObject transform="scale(0.5), translate(-25, -25)" id="car1" width="160" height="160"
>
<svg xmlns="http://www.w3.org/2000/svg"><path class="ytp-large-play-button-bg" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f00" fill-opacity="1"></path><path d="M 45,24 27,14 27,34" fill="#fff"></path></svg>
</foreignObject>
<animateMotion xlink:href="#car1" dur="8s" begin="1.3s" fill="freeze" repeatCount="indefinite" rotate="auto-reverse">
<mpath xlink:href="#motionPath1" />
</animateMotion>
</svg>

Trigger SVG animation trough button click

I'm trying to trigger an SVG animation when the button below is clicked.
This is my third evening trying, and still no succes.
I know the animation works when I click on it when using begin="click"
But I can't get it to work using a button.
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Laag_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-20 -20 400 400" width="350px" style="enable-background:new 0 0 306 307;" xml:space="preserve">
<style type="text/css">
.st0{fill:#56595D;}
.st1{fill:#427F31;}
.st2{fill:#FFFFFF;}
.st3{font-family: 'Roboto', sans-serif;}
.st4{font-size:21px;}
</style>
<path id="RechtsBoven" class="st0" d="M243,153h63C306,68,238,0,153,0v63C203,63,243,103,243,153z"/>
<path id="LinksBoven" class="st0" d="M152,63V0C68,0,0,68,0,153h63C63,103,103,63,152,63z"/>
<path id="LinksOnder" class="st0" d="M63,154H0c0,85,68,153,153,153v-63C103,244,63,204,63,154z"/>
<path id="RechtsOnder" class="st0" d="M154,244v63c84,0,152-68,152-153h-63C243,204,203,244,154,244z"/>
<circle id="Midden" class="st1" cx="153" cy="153.5" r="89.2"/>
<text id="XMLID_33_" transform="matrix(1 0 0 1 92.7636 147.0369)"><tspan x="0" y="0" class="st2 st3 st4">BUSINESS IT</tspan><tspan x="-3.9" y="25.2" class="st2 st3 st4">CONSULTING</tspan></text>
<animateTransform
xlink:href="#RechtsBoven"
attributeName="transform"
attributeType="XML"
id="animatie1"
type="translate"
from="0 0"
to="15 -15"
dur="0.3s"
begin="indefinite"
repeatCount="1"
fill="freeze" />
<animateTransform
xlink:href="#RechtsOnder"
attributeName="transform"
attributeType="XML"
id="animatie2"
type="translate"
from="0 0"
to="15 15"
dur="0.3s"
begin="indefinite"
repeatCount="1"
fill="freeze" />
</svg>
<br><br>
<button id="trigger1">Slide 1</button>
Below is the javascript part.
$( "#trigger1" ).click(function() {
document.getElementById("animatie1").beginElement();
});
You can find it here on Codepen.io
I seem to have got the animation to work on the codepen by first adding JQuery to your HTML:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
And to get an element by ID, use # instead of $:
$( "#trigger1" ).click(function() { ... }

Cannot apply animation on SVG g element

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"/>

Categories

Resources