Animating SVG Inline - animation
I have this setup working beautifully with SVG but I was curious if anyone knew how to smooth the transition and/or add animation between the hover animations I have. Right now the scale is being increased on hover and if I could get that animated somehow that would be awesome. I imagine inline JS somewhere would be best / most flexible, but i'm not sure exactly how to animate SVG properlly...
http://jsfiddle.net/468gm/
I imagine somewhere inline here would be best, but again im not sure if its possible to smooth the existing scale effect with inline SVG or if a different method would be needed to achieve a animated version of this hover effect
importedPaths.setAttribute("transform","translate("+transX+" "+transY+")scale("+scale+" "+scale+")")
After some playing around with your code I decided a non-js solution would be the best since you don't have a dynamic number of arrows. Check out the rough demo
I was able to add a CSS hover event to the elements by first putting them each in their own group (<g>) and applying the transform you gave them to that group. Then on hover I used transform: scaleY(1.3); and transition:all 0.5s to make the arrows grow. You also have to have a default scale(1) for the paths which I didn't expect, but that's just another couple lines
/* CSS */
use:hover {
-webkit-transform:scaleY(1.3);
transform:scaleY(1.3);
}
use {
-webkit-transform:scaleY(1);
transform:scaleY(1);
-webkit-transform-origin: bottom center;
transform-origin: bottom center;
transition:all 0.5s;
}
/* SVG */
<svg id="mySVG" x="0" y="0" width="900" height="800" overflow="visible">
<defs id="myDefs">
<g id="myBlackArrow" fill="#0a8c9e" transform="translate(-421.37805790890565 -409.89077969361676)scale(0.1587493937731687 0.1587493937731687)" filter="url(#f2)" >
<path d="M2553.826,1137.28l-2.772-1.719l29.799,1445.434l195.02,1.004l9.765-1448.729 c0,0-63.94,42.007-113.36,42.007S2553.826,1137.28,2553.826,1137.28z"></path>
<path d="M2451.84,1058.265c0,0,171.983,75.005,216.505,75.005s188.535-75.005,188.535-75.005l-190.691-366.037 L2451.84,1058.265z"></path>
</g>
<g id="myGrayArrow" fill="#1c9eb0" transform="translate(-421.37805790890565 -409.89077969361676)scale(0.1587493937731687 0.1587493937731687)" filter="url(#f1)">
<path d="M2553.826,1137.28l-2.772-1.719l29.799,1445.434l195.02,1.004l9.765-1448.729 c0,0-63.94,42.007-113.36,42.007S2553.826,1137.28,2553.826,1137.28z"></path>
<path d="M2451.84,1058.265c0,0,171.983,75.005,216.505,75.005s188.535-75.005,188.535-75.005l-190.691-366.037 L2451.84,1058.265z"></path>
</g>
<g id="myWhiteArrow" fill="#47c9db" transform="translate(-421.37805790890565 -409.89077969361676)scale(0.1587493937731687 0.1587493937731687)">
<path d="M2553.826,1137.28l-2.772-1.719l29.799,1445.434l195.02,1.004l9.765-1448.729 c0,0-63.94,42.007-113.36,42.007S2553.826,1137.28,2553.826,1137.28z"></path>
<path d="M2451.84,1058.265c0,0,171.983,75.005,216.505,75.005s188.535-75.005,188.535-75.005l-190.691-366.037 L2451.84,1058.265z"></path>
</g>
</defs>
<defs>
<filter id="f1" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation="5"></feGaussianBlur>
</filter>
</defs>
<defs>
<filter id="f2" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation="15"></feGaussianBlur>
</filter>
</defs>
<g transform="translate(400 400) rotate( 0)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate( 22.5)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate( 45)"><use xlink:href="#myGrayArrow"></use></g>
<!-- Found below -->
<g transform="translate(400 400) rotate( 90)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate(112.5)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate( 135)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate(157.5)"><use xlink:href="#myGrayArrow"></use></g>
<!-- Found below -->
<g transform="translate(400 400) rotate(202.5)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate( 225)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate(247.5)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate( 270)"><use xlink:href="#myGrayArrow"></use></g>
<!-- Found below -->
<g transform="translate(400 400) rotate( 315)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate(337.5)"><use xlink:href="#myGrayArrow"></use></g>
<g transform="translate(400 400) rotate( 67.5)"><use xlink:href="#myWhiteArrow"></use></g>
<g transform="translate(400 400) rotate( 180)"><use xlink:href="#myWhiteArrow"></use></g>
<g transform="translate(400 400) rotate(292.5)"><use xlink:href="#myWhiteArrow"></use></g>
</svg>
The only things you have left to do are to decide which arrows should have #myBlackArrow as opposed to #myGrayArrow (the way you have it on your demo seems random), fix the alignment of the arrows (the groups are wider than they should be - 75px when they are actually only like 65px so the rotation is off by around 10px), and add the gradient to the background
If you're looking to target the specific types to have separate hover events for each, you can add a data- attribute and select it with CSS. I decided to use data-aColor to keep it unique and because it's the arrow color. You can then select the data attribute with CSS by using the following: [data-aColor="gray"] { ... Here's a demo of what I mean
Related
SVG animate gradient along path
I have the following svg that i would like to animate. I would like the red part moves along the path up to the end (so from the top right side to the left bottom side) : The problem is : obviously is quite impossible to have a gradient following a path. Here is my code so far : <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; } </style> <linearGradient id="light" x1="100%" y1="100%"> <stop offset="70%" stop-color="#3E3E3E"> <!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="0.5s" fill="freeze" /> --> </stop> <stop offset="100%" stop-color="#CF4B59"> <!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="0.5s" fill="freeze" /> --> </stop> </linearGradient> </defs> <g id="Calque_2" data-name="Calque 2"> <g id="Calque_1-2" data-name="Calque 1"> <g class="cls-2"> <path class="cls-3" id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" transform="translate(-52.32 -8.93)" stroke="url(#light)"/> </g> </g> </g> </svg> I tried to use "animate" to make it move along the path, but it's a vertical gradient which is applied and goes from the top to the bottom and not a gradient which follows the path. I had other ideas to overcome this : Maybe by using a second path which would be the same shape than the first one but with inverted gradient so I could make it slide along the initial path maybe Or, I could use opacity to make the final path appear but i'm not sure i will be able to make the red part move in this way... If you have some ideas to make the red part move from the top right to the bottom left it would help me a lot!
Question I would like the red part moves along the path up to the end (so from the top right side to the left bottom side) : Consider using fill-line animation with stroke-dashoffset. For clarity, I placed exactly the same curve below which will show the route of filling the line with color If this indication of the motion path is not necessary, simply remove the path id = "trace" <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; stroke:#E7E7E7; } #base { fill: none; stroke:crimson; stroke-width:3px; stroke-dashoffset:1732; stroke-dasharray:1732; animation: fillStroke 10s linear forwards; } #keyframes fillStroke { to {stroke-dashoffset:0;} } </style> </defs> <g transform="translate(-352.32 -8.93)"> <path id="trace" class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" /> <g class="cls-2"> <path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" > </path> </g> </g> </svg> Gradient animation option Instead of filling with color as the length of the curve increases, a gradient will perform this function <svg id="fil" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 783.53 362"> <defs> <style> .cls-3{ fill: none; stroke-miterlimit:10; stroke-width:3px; stroke:#E7E7E7; } #base { fill: none; stroke:url(#light); stroke-width:3px; stroke-dashoffset:1732; stroke-dasharray:1732; animation: fillStroke 10s linear forwards; } #keyframes fillStroke { to {stroke-dashoffset:0;} } </style> <linearGradient id="light" x1="100%" y1="100%"> <stop offset="50%" stop-color="#CF4B59"> <!-- <animate attributeName="stop-color" from="#CF4B59" to="#3E3E3E" dur="10s" fill="freeze" /> --> </stop> <stop offset="100%" stop-color="#3E3E3E"> <!-- <animate attributeName="stop-color" to="#CF4B59" from="#3E3E3E" dur="10s" fill="freeze" /> --> </stop> </linearGradient> </defs> <g transform="translate(-352.32 -8.93)"> <path class="cls-3" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" /> <g class="cls-2"> <path id="base" d="M656.89,8.93c0,48,7.42,124.9,64.45,125.92a115.56,115.56,0,0,0,53.83-12.28c8.35-4.2,16.35-9.59,21.84-17.15s8.15-17.62,5.25-26.51c-3.12-9.53-12.16-16.28-21.87-18.83-61.57-16.19-142.83,57.7-139.63,119.4,1.23,23.69,16.72,41.59,37.61,51.29,27,12.55,60.55,13.36,89.45,8.06,12.25-2.25,25.82-5.25,37.26-10.44,12.63-5.72,32.28-20.08,28.88-36.64a18,18,0,0,0-15.63-14.59c-10.28-1.4-19.14,3.57-26.76,10-16.18,13.66-29.34,30.65-44.7,45.2a359.34,359.34,0,0,1-49.33,39.08A356.65,356.65,0,0,1,638.08,303c-35.77,14.83-90.88,29.56-123.22-.47-11.61-10.78-17.61-26.71-18.41-42.53-1.07-21.19,4.41-54.95,30-59.28,36.67-6.2,78.65,49.05,86.38,79.36,8.2,32.14-5.44,70.78-35.75,84.26-28.8,12.81-63.93,0-85.8-22.72-23.52-24.41-18.59-55.9-36.07-82.56-16-24.39-41.3-23.5-66.77-24.62" > </path> </g> </g> </svg>
How to make an object rotate around the exact center of the screen using animateTransform?
Consider the following SVG code for moving a circle around the center of the screen, with hard-coded dimensions: <svg xmlns="http://www.w3.org/2000/svg"> <g> <ellipse id="circ" style="fill:#000000" cx="60%" cy="50%" rx="10" ry="10" /> <!--Assuming window size is 1000x1000--> <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,500,500" to="360,500,500" repeatCount="indefinite"/> </g> </svg> If I try to provide the center of rotation in percent, the animation doesn't work at all: <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,50%,50%" to="360,50%,50%" repeatCount="indefinite"/> How do I fix this?
Set a viewBox on your SVG, then whatever size you make it, the ellipse will rotate around the centre of it. viewBox="0 0 1000 1000" The value of 1000 for width and height here is chosen because it would make 500 be the centre. svg:nth-child(1) { width: 200px; } svg:nth-child(2) { width: 500px; } svg { border: solid 1px green; } <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> <g> <ellipse id="circ" style="fill:#000000" cx="60%" cy="50%" rx="10" ry="10" /> <!--Assuming window size is 1000x1000--> <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,500,500" to="360,500,500" repeatCount="indefinite"/> </g> </svg> <!-- An exact duplicate of th first one --> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"> <g> <ellipse id="circ" style="fill:#000000" cx="60%" cy="50%" rx="10" ry="10" /> <!--Assuming window size is 1000x1000--> <animateTransform attributeName="transform" type="rotate" dur="10s" from="0,500,500" to="360,500,500" repeatCount="indefinite"/> </g> </svg>
Why does the SVG animation stop when using xlink:href for external file
For some reason my spinner.svg is not animating when using xlink:href. Embedding the SVG on the page and using xlink:href seems to work fine, as the snippet below shows. The problem: static (and solid!) spinner instead of animation Why are the animation tags of the SVG suddenly not taking effect? The reference must be working since the image is actually displaying. EDIT: Could this have to do with the shadow dom and xref? According to Sara Soueidan "The target element must be part of the current SVG document fragment". I might be overloading what "document fragment" means, but to me document fragments belong in Shadow DOM land, and I suspect that SMIL animations might not work when using <use> statements due to this? Working versions .xlinked { color: green; } img { color: red; // not taking effect - of course! just a test. } .embedded { color: blue; } <h1>xlink local</h1> <svg class="xlinked"> <!-- could not get this external reference to work? <use xlink:href="http://imgh.us/spinner_1.svg" /> --> <use xlink:href="#spinner" /> </svg> <h1>embedded</h1> <div class="embedded"> <svg id="embedded" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"> <circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round"/> <circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round"> <animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502"/> <animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4"/> </circle> </svg> </div> <h1>img</h1> <img src="http://imgh.us/spinner_1.svg" /> <h1>External absolute xlink (not working)</h1> <svg> <!-- could not get this external reference to work. should be the same as a local reference? --> <use xlink:href="http://imgh.us/spinner_1.svg" /> </svg> <h1>Source SVG with symbols for xlink reference </h1> <svg xmlns="http://www.w3.org/2000/svg"><symbol id="spinner" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="50" cy="50" r="45" stroke="rgba(43,43,43,0.3)" fill="none" stroke-width="10" stroke-linecap="round"/><circle cx="50" cy="50" r="45" stroke="currentColor" fill="none" stroke-width="6" stroke-linecap="round"><animate attributeName="stroke-dashoffset" dur="2s" repeatCount="indefinite" from="0" to="502"/><animate attributeName="stroke-dasharray" dur="2s" repeatCount="indefinite" values="150.6 100.4;1 250;150.6 100.4"/></circle></symbol></svg>
In SVG1.1, Use element requires reference to SVG fragment not SVG URL. Try to add id attribute to root svg element of external SVG file and add hash string to href value of use element, like this. external svg(spinner_1.svg) <svg xmlns="http://www.w3.org/2000/svg" id="root"> <!--svg structure--> </svg> html uses external SVG file <svg> <use xlink:href="http://imgh.us/spinner_1.svg#root" /> </svg> Note:In SVG2, you can set SVG URL to href attribute of use element. See https://www.w3.org/TR/2016/CR-SVG2-20160915/struct.html#UseElement
SVG Filter causes clipping of SVG with viewbox in Firefox
I am trying to create a resizable SVG shape, with a 'glow' effect when it is selected using a gaussian filter. When I try to apply the filter as below, in Firefox (tried on v39+), the filter seems to cause the rectangle to be clipped at the bottom as soon as the height of the SVG element is > about 490. This doesn't happen in chrome though. If the filter is removed, the rectangle is not clipped. I've mucked around for hours trying various combinations for the filter effect region parameters, but can't seem to find anything that works for arbitrary sizes of the SVG element. Putting the filter on the g element seems to work, but here are going to be other children that I don't want the filter to apply to. What am I missing and how can I make this work? Thanks, Dave <html> <body> <div style = "width: 100%; height: 100%"> <svg style = "width: 100%; height: 100%"> <defs> <symbol id="rectangle"> <polygon vector-effect="non-scaling-stroke" points="3,3 103,3 103,53 3,53"></polygon> </symbol> </defs> <filter id="nodeGlow" width="100" height="100"> <feGaussianBlur stdDeviation="3" result="coloredBlur"/> <feMerge> <feMergeNode in="coloredBlur"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> <g> <svg style="fill: rgb(0, 251, 255); stroke: rgb(30, 30, 30); stroke-width : 1.5px; filter: url("#nodeGlow");" y="0" x="0" height="500" width="200" class="node" preserveAspectRatio="none" viewBox="0 0 106 56"> <use xlink:href="#rectangle"></use> </svg> </g> </svg> </div> </html> </body> Update: Robert's suggestion to add another <g> element did the trick, although I put it around the <svg> element rather than the <use> element because the blur effect looked poor when scaled up if it was around the <use>. I didn't add it to the existing <g>, cause there will be other children of that one that shouldn't have the filter.
Wrap the use in a <g> element and put the filter on that, or put the filter directly on the <use> element. html, body, div { width: 100%; height: 100%; } <div> <svg width="100%" height="100%"> <defs> <symbol id="rectangle"> <polygon vector-effect="non-scaling-stroke" points="3,3 103,3 103,53 3,53"></polygon> </symbol> </defs> <filter id="nodeGlow" width="100" height="100"> <feGaussianBlur stdDeviation="3" result="coloredBlur"/> <feMerge> <feMergeNode in="coloredBlur"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> <g> <svg style="fill: rgb(0, 251, 255); stroke: rgb(30, 30, 30); stroke-width : 1.5px;" height="500" width="200" class="node" preserveAspectRatio="none" viewBox="0 0 106 56"> <g style="filter: url(#nodeGlow);"> <use xlink:href="#rectangle"></use> </g> </svg> </g> </svg> </div> Putting the filter on something that has a viewBox is unlikely to work as the viewBox changes the co-ordinate system of its children but it doesn't change the element's co-ordinate system. Firefox is actually working properly.
Why don't the circles show up?
I built some SVG with d3.js but nothing is displayed. Why? Here is part of code: <svg width="863" height="863" id="svgId"> <g transform="translate(431.5,431.5)"> <g class="asdf" r="421.5"> <circle transform="translate(0,0)" style="fill: rgb(255, 0, 0);"></circle> </g> <g class="asdf" r="127.6354829132969"> <circle transform="translate(-118.50486492278469,167.13470131539657)" style="fill: rgb(255, 0, 0);"></circle> </g> </g>
You've set the radius (r attribute) on the <g> element where it does nothing and not on the <circle> element where it's required. What you need is this... <svg width="863" height="863" id="svgId"> <g transform="translate(431.5,431.5)"> <g class="asdf"> <circle r="421.5" transform="translate(0,0)" style="fill: rgb(255, 0, 0);"></circle> </g> <g class="asdf"> <circle r="127.6354829132969" transform="translate(-118.50486492278469,167.13470131539657)" style="fill: rgb(255, 0, 0);"></circle> </g> </g> </svg>