How move/animate multiple circles along motion path by SVG Animation - svg

How can move multiple circles along a <mpath> (motion path) using SVG SMIL Animation <<animateMotion>.
Problem: About the first 3 4 circles everything was fine.
Some circles went "out of orbit" – so they are not correctly aligned with the motion path.
.planePath {
stroke: red;
stroke-width: .1%;
stroke-width: .5%;
stroke-dasharray: 1% 2%;
stroke-linecap: round;
fill: none;
z-index: 99;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="index.css">
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<title>Document</title>
</head>
<body>
<div class="container-fluid center" style="z-index: 99">
<svg viewBox="-300 -150 3387 1270" align="center" class="svg-animation">
<path id="planePath" class="planePath"
d="M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z"/>
/>
<path style="position:absolute" id="circle2" class="planePath "
d="M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z"/>
/>
<defs>
<filter id="filter0_d_0_1" x="0" y="17" width="897" height="847" filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha" />
<feOffset dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" />
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_0_1" />
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_0_1" result="shape" />
</filter>
<filter id="filter1_d_0_1" x="926" y="33" width="897" height="847" filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha" />
<feOffset dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" />
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_0_1" />
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_0_1" result="shape" />
</filter>
<filter id="filter2_d_0_1" x="1884" y="33" width="897" height="847" filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
result="hardAlpha" />
<feOffset dy="4" />
<feGaussianBlur stdDeviation="2" />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" />
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_0_1" />
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_0_1" result="shape" />
</filter>
</defs>
<g id="plane">
<circle cx="80" cy="0" r="20" fill="black" />
</g>
<g id="point">
<circle cx="-50" cy="0" r="20" fill="black"/>
</g>
<g id="point-2">
<circle cx="20" cy="0" r="20" fill="black" />
</g>
<g id="point-3">
<circle cx="-120" cy="0" r="20" fill="black" />
</g>
<g id="point-4">
<circle cx="140" cy="0" r="20" fill="black" />
</g>
<g id="point-5">
<circle cx="180" cy="20" r="20" fill="orange" />
</g>
<g id="point-6">
<circle cx="-180" cy="0" r="20" fill="black" />
</g>
<g id="point-7">
<circle cx="-200" cy="0" r="20" fill="black" />
</g>
<g id="point-8">
<circle cx="-220" cy="0" r="20" fill="black" />
</g>
<g id="point-9">
<circle cx="-240" cy="0" r="20" fill="black" />
</g>
<g id="point-10">
<circle cx="-260" cy="0" r="20" fill="black" />
</g>
<g id="point-11">
<circle cx="-280" cy="0" r="20" fill="black" />
</g>
<g id="point-12">
<circle cx="-300" cy="0" r="20" fill="black"/>
</g>
<g id="point-13">
<circle cx="320" cy="0" r="20" fill="black" />
</g>
<g id="point-14">
<circle cx="-340" cy="0" r="20" fill="black" />
</g>
<g id="point-15">
<circle cx="-360" cy="0" r="20" fill="black" />
</g>
<g id="point-16">
<circle cx="-380" cy="0" r="20" fill="black" />
</g>
<g id="point-17">
<circle cx="-400" cy="0" r="20" fill="black" />
</g>
<g id="point-18">
<circle cx="-420" cy="0" r="20" fill="black" />
</g>
<g id="point-19">
<circle cx="-430" cy="0" r="20" fill="black" />
</g>
<g id="point-20">
<circle cx="-440" cy="0" r="20" fill="black" />
</g>
<g id="point-21">
<circle cx="-460" cy="0" r="20" fill="black" />
</g>
<g id="point-22">
<circle cx="-480" cy="0" r="20" fill="black" />
</g>
<!-- Define the motion path animation -->
<animateMotion xlink:href="#plane" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-2" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-3" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-4" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-5" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<!-- <animateMotion xlink:href="#point-6" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-7" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-8" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-9" dur="20s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion> -->
</svg>
</div>
<!-- <div class="box">
<div class="circle">
</div>
<div class="circle">
</div>
<div class="circle">
</div>
</div> -->
<script src="index.js"></script>
</body>
</html>
<!-- begin snippet: js hide: false console: true babel: false -->

Your animated circles (moving along the motion path)
should be placed at cx/cy =0.
Explained here by #Paul LeBeau: Offset when following svg motion path
Otherwise their initial position will be added to the current motion path position.
That's why your circle are moving as in straight line around the path.
Path offset via animation delay
Actually all circles have the same center position of cx="0" cy="0" - so they would be overlapping without animation.
By adding an incremental begin value we mimic a path offset like so:
<animateMotion xlink:href="#plane" dur="10s" begin="0s"repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-1" dur="10s" begin="0.1s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
The higher the begin="0.1s" value, the larger the distance between the circles.
Simplified example
<svg viewBox="-300 -150 3387 1270" align="center" class="svg-animation">
<path id="planePath" fill="none" stroke="red" stroke-width="0.5%" stroke-dasharray="1% 2%"
stroke-linecap="round" class="planePath"
d="M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z" />
/>
<g id="circles">
<circle id="plane" class="plane" fill="green" cx="0" cy="0" r="20" fill="black" />
<circle id="point-1" class="point-1" fill="magenta" cx="0" cy="0" r="20" fill="black" />
<circle id="point-2" class="point-2" fill="purple" cx="0" cy="0" r="20" fill="black" />
<circle id="point-3" class="point-3" fill="orange" cx="0" cy="0" r="20" fill="black" />
</g>
<animateMotion xlink:href="#plane" dur="10s" begin="0s"repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-1" dur="10s" begin="0.1s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-2" dur="10s" begin="0.2s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-3" dur="10s" begin="0.3s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
</svg>
Drawback: at the beginning you see circles at the position x/y=0 since they are not yet aligned to the motion path, due to the delay.
As a workaround we can hide all circles until all of them are animated/aligned:
.planePath {
stroke: red;
stroke-width: .1%;
stroke-width: .5%;
stroke-dasharray: 1% 2%;
stroke-linecap: round;
fill: none;
}
<svg viewBox="-300 -150 3387 1270" align="center" class="svg-animation">
<path id="planePath" class="planePath"
d="M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z" />
/>
<g id="circles" opacity="0">
<circle id="plane" class="plane" fill="green" cx="0" cy="0" r="20" fill="black" />
<circle id="point-1" class="point-1" fill="magenta" cx="0" cy="0" r="20" fill="black" />
<circle id="point-2" class="point-2" fill="purple" cx="0" cy="0" r="20" fill="black" />
<circle id="point-3" class="point-3" fill="orange" cx="0" cy="0" r="20" fill="black" />
</g>
<animateMotion xlink:href="#plane" dur="10s" begin="0s"repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-1" dur="10s" begin="0.1s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-2" dur="10s" begin="0.2s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<animateMotion xlink:href="#point-3" dur="10s" begin="0.3s" repeatCount="indefinite" rotate="auto">
<mpath xlink:href="#planePath" />
</animateMotion>
<!-- hide circles on start: otherwise circles show up at x/y=0 due to animation delay-->
<animate attributeName="opacity"
xlink:href="#circles"
values="0; 1;" dur="0.1s" begin="0.4"
data-id="circles"
repeatCount="1"
fill="freeze"
/>
</svg>
Fade in animation
<animate attributeName="opacity"
xlink:href="#circles"
values="0; 1;" dur="0.1s" begin="0.4"
data-id="circles"
repeatCount="1"
fill="freeze"
/>
The begin value is calculated like so:
delay-increment: 0.1 * total number of circles
Initial motion path offset – css offset-path to the rescue
Disclaimer: browser support might still be spotty.
See also MDN Docs.
The main benefit of the offset-path property is its ability to actually define a start offset – pretty neat for static element renderings as well.
(Quite similar to svg's textPath related startOffset property)
const svg = document.querySelector('svg');
let dotsCount = 15;
let steps = 100 / dotsCount;
let duration = 10;
let circleRadius = 20;
let startOffset = 50;
//create css rules for animations
let circleMarkup = '';
let css =
`.css-animate circle {
offset-path: path('M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z');
offset-rotate: auto;
}`;
for (let i = 0; i < dotsCount; i++) {
circleMarkup +=
`<circle id="point${i}" class="point point${i}" fill="green" cx="0" cy="0" r="${circleRadius}" />`;
css +=
`.point${i} {
offset-distance: ${steps*i+startOffset}%;
animation: followpath${i} ${duration}s linear infinite;
}
#keyframes followpath${i} {
to {
offset-distance: ${100+steps*i+startOffset}%;
}
}`;
}
svg.insertAdjacentHTML('afterbegin', '<style>'+css+'</style>');
svg.insertAdjacentHTML('beforeend', circleMarkup);
<svg viewBox="-300 -150 3387 1270" class="css-animate">
<path id="planePath" stroke="#ccc" stroke-width="1%" stroke-dasharray="1% 2%"
stroke-linecap="round" fill="none" class="planePath"
d="M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z" />
</svg>
In the above example the initial motion path offset is set by:
.point-1 {
offset-distance: 25%;
animation: followpath1 10s linear infinite;
}
Also referring to a #keyframe animation rule:
#keyframes followpath1 {
to {
offset-distance: 125%;
}
}
Of course, you will need to adjust the values according to the desired offsets/timings.
Alternative: animated stroke-dashoffset
Probably the easiest approach – slightly jittery.
I use pathLength to change the computed length for the dash-array to 100.
stroke-dasharray: 0 6.666;
stroke-linecap: round;
Setting the first dash-array value to 0 will result in a dotted line (so every dot is perfectly circular) when combined with stroke-linecap: round.
The second value defines the the gap or the total number of dots:
100 (pathlength) / 15 (3 circles à 5 dots) = 0.666.
.planePath {
stroke: red;
stroke-width: 5%;
stroke-dasharray: 0 6.666;
stroke-linecap: round;
fill: none;
animation: animStroke 10s linear infinite;
stroke-dashoffset: 0;
}
.planePath2 {
stroke: red;
stroke-width: 5%;
stroke-dasharray: 0 3.333;
stroke-linecap: round;
fill: none;
animation: animStroke 10s linear infinite;
}
#keyframes animStroke {
to {
stroke-dashoffset: -100;
}
}
<div class="container-fluid center" style="z-index: 99">
<svg viewBox="-300 -150 3387 1270" align="center" class="svg-animation">
<path id="planePath" pathLength="100" class="planePath"
d="M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z" />
/>
</svg>
</div>
<div class="container-fluid center" style="z-index: 99">
<svg viewBox="-300 -150 3387 1270" align="center" class="svg-animation">
<path id="planePath2" pathLength="100" class="planePath planePath2"
d="M1.50024 430C58.2002 -111.6 853.699 -156.741 889.5 430C925.5 1020 1754 1007.5 1785 430C1816 -147.5 2665.5 -132 2665.5 430C2665.5 1010.27 1847 948 1785 453C1841.5 -83.5 930.282 -187.244 889.5 389C851 933 35 1017.5 1.50024 430Z" />
/>
</svg>
</div>

Related

scale a svg element which is inside an other svg

I would like to scale up on hover 3 svgs nested in an other svg. These 3 svgs are planets visible on the first graph at this address : http://68.183.74.150:3000/planet.
So, to sum up, the code looks like this :
<svg id="a">
<g>
...
</g>
<g>
<svg id="b"></svg>
</g>
</svg>
I tried the code below but it doesn't work as b is nested inside a. It works if I apply this code to the "a" svg.
svg#b:hover {
transform: scale(3);
}
svg#b {
transition: all 1s;
transform-origin: 50% 50%;
}
How would you solve this ?
Apparently chromium seems to have issues with scaling nested svg elements.
/* example layout */
.wrap {
display: inline-block;
width: 20em;
}
.svgParent {
width: 10em;
border: 2px solid #ccc;
}
.svgParent:hover {
border: 2px solid green;
}
/* set transformorigin */
.svgChild,
.childNodes {
transition: 0.3s;
transform-origin: center;
}
/* ensure scaled element don't get cropped when scaled */
.svgChild {
overflow: visible;
}
.hoverElement:hover {
transform: scale(1.3);
opacity: 0.5;
}
<div class="wrap">
<p>Scale nested svg on hover –<br />not working in chrome</p>
<svg class="svgParent" viewBox="0 0 100 100">
<svg class="svgChild hoverElement" x="20" y="20" width="48" height="48" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="12" fill="#ccc" />
</svg>
</svg>
</div>
<div class="wrap">
<p>Scale group in nested svg on hover</p>
<svg class="svgParent" viewBox="0 0 100 100">
<svg class="svgChild" x="20" y="20" width="48" height="48" viewBox="0 0 24 24">
<g class="childNodes hoverElement">
<circle cx="12" cy="12" r="12" fill="#ccc" />
</g>
</svg>
</svg>
</div>
For a consistent display in both firefox and chromium you could wrap your planets' child elements an additional group like so:
<svg x="129.2" y="62.1" width="26" height="26" viewBox="0 0 36 36">
<g class="planetwrap">
<circle fill="#88C9F9" cx="18" cy="18" r="18" />
<path fill="#5C913B" d="M25.716 1.756c-1.022.568-1.872 1.528-3.028 1.181-1.875-.562-4.375-1.812-6-.25s-2 3 0 2.938 3.375-2.438 4.375-1.438.749 1.813-1.625 2.125S14.5 7 13.125 7s-1.688.812-.75 1.688-.563.937-2.125 1.812.375 1.25 1.688 2 2.312-.188 2.875-1.438 2.981-2.75 3.99-2.562c1.01.188 1.01.688.822 1.562s.75.625.812-.375 1.188-1.75 2.062-1.812 1.625 1.188.625 1.812-2 1.125-.75 1.438 2.125 1.938.688 2.625-3.937 1.125-5.062.562-3.688-1.375-4.375-.938-1.062.89-1.875 1.195c-.812.305-4.125 1.805-4.188 3.743S7.438 22.438 8.75 22.5s4.5-.812 5.5-1.625 2.375-.625 2.812.312.125 1.5-.312 3 .286 2.25.987 3.562c.701 1.312 1.263 2.062 1.263 3s1 1.875 2.5.312 2.875-4.625 3.5-5.75 1.125-3.625 1.875-4.125 1.938-1.688 1.062-1.5-2.625-.062-3.062-1.312-2.312-3.625-1.438-3.875 1.875 1.39 2.25 2.164c.375.774.875 1.711 1.625 1.961s2.375-1.673 2.875-1.961c.5-.289.125-1.476-.875-1.351s-2.312 0-2.312-.624 1.25-1.438 2.25-1.25 1.75.5 2.375 1.25 1.875 2.125 2.375 3 .875 1 1.125-.562c.166-1.038.387-1.609.59-2.222-1.013-5.829-4.82-10.683-9.999-13.148z" />
</g>
</svg>
Example grouped
If you can't optimize and save your tweaked planet assets statically you could use some js to do the wrapping job.
let planets = document.querySelectorAll('.recharts-reference-dot svg');
// wrap planet svg elements
planets.forEach(function(planet, i){
planet.innerHTML = '<g class="planetwrap">'+ planet.innerHTML +'</g>';
})
.recharts-reference-dot svg{
overflow:visible;
}
.planetwrap{
transform-origin:center;
transition: 0.3s transform
}
.planetwrap:hover{
transform:scale(1.5)
}
<div class="recharts-wrapper" style="position: relative; cursor: default; width: 899px; height: 199.778px;"><svg id="masse_distance" class="recharts-surface" width="899" height="199.77777777777777" viewBox="0 0 899 199.77777777777777" version="1.1">
<defs>
<clipPath id="masse_distance-clip">
<rect x="70" y="20" height="139.77777777777777" width="809"></rect>
</clipPath>
</defs>
<g class="recharts-layer recharts-cartesian-axis recharts-xAxis xAxis">
<line name="masse" type="number" orientation="bottom" width="809" height="30" x="70" y="159.77777777777777" class="recharts-cartesian-axis-line" stroke="#666" fill="none" x1="70" y1="159.77777777777777" x2="879" y2="159.77777777777777"></line>
<g class="recharts-cartesian-axis-ticks">
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="masse" type="number" orientation="bottom" width="809" height="30" x="70" y="159.77777777777777" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="231.8" y1="165.77777777777777" x2="231.8" y2="159.77777777777777"></line><text name="masse" type="number" orientation="bottom" width="809" height="30" x="231.8" y="167.77777777777777" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="middle">
<tspan x="231.8" dy="0.71em">0.01 Mjup</tspan>
</text>
</g>
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="masse" type="number" orientation="bottom" width="809" height="30" x="70" y="159.77777777777777" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="308.99821901364135" y1="165.77777777777777" x2="308.99821901364135" y2="159.77777777777777"></line><text name="masse" type="number" orientation="bottom" width="809" height="30" x="308.99821901364135" y="167.77777777777777" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="middle">
<tspan x="308.99821901364135" dy="0.71em">0.03 Mjup</tspan>
</text>
</g>
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="masse" type="number" orientation="bottom" width="809" height="30" x="70" y="159.77777777777777" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="393.6" y1="165.77777777777777" x2="393.6" y2="159.77777777777777"></line><text name="masse" type="number" orientation="bottom" width="809" height="30" x="393.6" y="167.77777777777777" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="middle">
<tspan x="393.6" dy="0.71em">0.1 Mjup</tspan>
</text>
</g>
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="masse" type="number" orientation="bottom" width="809" height="30" x="70" y="159.77777777777777" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="555.4" y1="165.77777777777777" x2="555.4" y2="159.77777777777777"></line><text name="masse" type="number" orientation="bottom" width="809" height="30" x="555.4" y="167.77777777777777" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="middle">
<tspan x="555.4" dy="0.71em">1 Mjup</tspan>
</text>
</g>
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="masse" type="number" orientation="bottom" width="809" height="30" x="70" y="159.77777777777777" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="717.2" y1="165.77777777777777" x2="717.2" y2="159.77777777777777"></line><text name="masse" type="number" orientation="bottom" width="809" height="30" x="717.2" y="167.77777777777777" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="middle">
<tspan x="717.2" dy="0.71em">10 Mjup</tspan>
</text>
</g>
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="masse" type="number" orientation="bottom" width="809" height="30" x="70" y="159.77777777777777" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="879" y1="165.77777777777777" x2="879" y2="159.77777777777777"></line><text name="masse" type="number" orientation="bottom" width="809" height="30" x="873.265625" y="167.77777777777777" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="middle">
<tspan x="873.265625" dy="0.71em">100 Mjup</tspan>
</text>
</g>
</g>
</g>
<g class="recharts-layer recharts-cartesian-axis recharts-yAxis yAxis">
<line name="periode orbitale" type="number" orientation="left" width="60" height="139.77777777777777" x="10" y="20" class="recharts-cartesian-axis-line" stroke="#666" fill="none" x1="70" y1="20" x2="70" y2="159.77777777777777"></line>
<g class="recharts-cartesian-axis-ticks">
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="periode orbitale" type="number" orientation="left" width="60" height="139.77777777777777" x="10" y="20" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="64" y1="124.83333333333333" x2="70" y2="124.83333333333333"></line><text name="periode orbitale" type="number" orientation="left" width="60" height="139.77777777777777" x="62" y="124.83333333333333" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="end">
<tspan x="62" dy="0.355em">1 jour</tspan>
</text>
</g>
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="periode orbitale" type="number" orientation="left" width="60" height="139.77777777777777" x="10" y="20" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="64" y1="89.88888888888887" x2="70" y2="89.88888888888887"></line><text name="periode orbitale" type="number" orientation="left" width="60" height="139.77777777777777" x="62" y="89.88888888888887" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="end">
<tspan x="62" dy="0.355em">100 jour</tspan>
</text>
</g>
<g class="recharts-layer recharts-cartesian-axis-tick">
<line name="periode orbitale" type="number" orientation="left" width="60" height="139.77777777777777" x="10" y="20" class="recharts-cartesian-axis-tick-line" stroke="#666" fill="none" x1="64" y1="61.208688458136685" x2="70" y2="61.208688458136685"></line><text name="periode orbitale" type="number" orientation="left" width="60" height="139.77777777777777" x="62" y="61.208688458136685" stroke="none" fill="#666" class="recharts-text recharts-cartesian-axis-tick-value" text-anchor="end">
<tspan x="62" dy="0.355em">4380 jour</tspan>
</text>
</g>
</g>
</g>
<g class="recharts-layer recharts-reference-dot">
<g>
<svg x="129.19821901364134" y="62.06438300713549" width="26" height="26" viewBox="0 0 36 36">
<circle fill="#88C9F9" cx="18" cy="18" r="18"></circle>
<path fill="#5C913B" d="M25.716 1.756c-1.022.568-1.872 1.528-3.028 1.181-1.875-.562-4.375-1.812-6-.25s-2 3 0 2.938 3.375-2.438 4.375-1.438.749 1.813-1.625 2.125S14.5 7 13.125 7s-1.688.812-.75 1.688-.563.937-2.125 1.812.375 1.25 1.688 2 2.312-.188 2.875-1.438 2.981-2.75 3.99-2.562c1.01.188 1.01.688.822 1.562s.75.625.812-.375 1.188-1.75 2.062-1.812 1.625 1.188.625 1.812-2 1.125-.75 1.438 2.125 1.938.688 2.625-3.937 1.125-5.062.562-3.688-1.375-4.375-.938-1.062.89-1.875 1.195c-.812.305-4.125 1.805-4.188 3.743S7.438 22.438 8.75 22.5s4.5-.812 5.5-1.625 2.375-.625 2.812.312.125 1.5-.312 3 .286 2.25.987 3.562c.701 1.312 1.263 2.062 1.263 3s1 1.875 2.5.312 2.875-4.625 3.5-5.75 1.125-3.625 1.875-4.125 1.938-1.688 1.062-1.5-2.625-.062-3.062-1.312-2.312-3.625-1.438-3.875 1.875 1.39 2.25 2.164c.375.774.875 1.711 1.625 1.961s2.375-1.673 2.875-1.961c.5-.289.125-1.476-.875-1.351s-2.312 0-2.312-.624 1.25-1.438 2.25-1.25 1.75.5 2.375 1.25 1.875 2.125 2.375 3 .875 1 1.125-.562c.166-1.038.387-1.609.59-2.222-1.013-5.829-4.82-10.683-9.999-13.148z"></path>
</svg>
</g><text x="167.19821901364134" y="70.06438300713549">Terre</text>
</g>
</svg></div>

Is it possible to use CSS variables to change the the TITLE (description on hover) contents of SVG objects?

Is it possible to use CSS variables (analogue to e.g. opacity in style="opacity:var(--QQQ_SOMETHING_AAA, 1)" and .ZZZ_RECTANGLES{--QQQ_SOMETHING_AAA: 0.7;} to tweak the SVGS's TITLE (description on hover <title></title>) contents?
I'm looking for something that will use only SVG1.1 features and SMIL/CSS, so no other plug-ins that might worsen cross-browser compatibility.
Here's a MWE code snippet:
.HIDDEN_LAYER{
visibility:hidden;
opacity:0;
}
.CLICKME_TICKBOX{
fill:white;
stroke:black;
}
.CLICKED_TICKBOX{
fill:white;
stroke:black;
}
.CLICKME_TEXTS{
font-family:sans-serif;
font-size:16px;
}
.CLICKED_TEXTS{
font-family:sans-serif;
font-size:16px;
stroke:black;
stroke-width:0.5;
}
.BOTTOM-LAYER_RECTANGLES{
fill:white;
stroke:black;
}
.ZZZ_RECTANGLES{
visibility:hidden;
cursor:help;
fill:yellow;
stroke:black;
--QQQ_SOMETHING_AAA: 0.7;
--QQQ_SOMETHING_BBB: 0.2;
}
.FFF_RECTANGLES{
visibility:hidden;
cursor:help;
fill:red;
stroke:black;
--PPP_SOMETHING_AAA: 0.2;
--PPP_SOMETHING_BBB: 0.7;
}
.LEGENDBOX_ZZZ{
fill:yellow;
stroke:black;
}
.LEGENDBOX_FFF{
fill:red;
stroke:black;
}
.LEGENDS{
cursor:pointer;
}
<svg id="SVG"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1320"
height="1125"
viewBox="-15 -45 1350 1155">
<symbol id="SOMETHING_AAA">
<use
xlink:href="#RECTANGLE"
transform="translate(637.5, 25)"
style="
opacity:var(--QQQ_SOMETHING_AAA, 1);
fill-opacity:var(--PPP_SOMETHING_AAA, 1)
">
</use>
</symbol>
<symbol id="SOMETHING_BBB">
<use
xlink:href="#RECTANGLE"
transform="translate(15, 215)"
style="
opacity:var(--QQQ_SOMETHING_BBB, 1);
fill-opacity:var(--PPP_SOMETHING_BBB, 1)
">
</use>
</symbol>
<g class="BOTTOM-LAYER_RECTANGLES">
<use xlink:href="#SOMETHING_AAA" />
<use xlink:href="#SOMETHING_BBB" />
</g>
<g class="ZZZ_RECTANGLES">
<use xlink:href="#SOMETHING_AAA">
<title>Something here 111.</title>
</use>
<use xlink:href="#SOMETHING_BBB">
<title>Something here 222.</title>
</use>
<set
to="visible"
attributeType="CSS"
attributeName="visibility"
end="CLICKED_ZZZ.click;bg.click"
begin="CLICKME_ZZZ.click" />
<set
to="1"
attributeType="CSS"
attributeName="opacity"
end="CLICKED_ZZZ.click;bg.click"
begin="CLICKME_ZZZ.click" />
</g>
<g class="FFF_RECTANGLES">
<use xlink:href="#SOMETHING_AAA">
<title>Something here 333.</title>
</use>
<use xlink:href="#SOMETHING_BBB">
<title>Something here 444.</title>
</use>
<set
to="visible"
attributeType="CSS"
attributeName="visibility"
end="CLICKED_DDD.click;bg.click"
begin="CLICKME_DDD.click" />
<set
to="1"
attributeType="CSS"
attributeName="opacity"
end="CLICKED_DDD.click;bg.click"
begin="CLICKME_DDD.click" />
</g>
<g id="LEGENDS"
class="LEGENDS"
transform="translate(15, -15)">
<g id="ZZZ">
<g id="CLICKME_ZZZ">
<rect id="CLICKME_TICKBOX_ZZZ"
class="CLICKME_TICKBOX"
x="0"
y="0"
width="15"
height="15">
</rect>
<use id="CLICKME_LEGENDBOX_ZZZ"
class="LEGENDBOX_ZZZ"
x="30"
y="-5"
xlink:href="#LEGENDBOX">
</use>
<text id="CLICKME_TEXT_ZZZ"
class="CLICKME_TEXTS"
x="65"
y="12.5">
Click me
</text>
</g>
<g id="CLICKED_ZZZ"
class="HIDDEN_LAYER">
<use id="CLICKED_TICKBOX_ZZZ"
x="0"
y="0"
xlink:href="#CLICKED_TICKBOX">
</use>
<use id="CLICKED_LEGENDBOX_ZZZ"
class="LEGENDBOX_ZZZ"
x="30"
y="-5"
xlink:href="#LEGENDBOX">
</use>
<text id="CLICKED_TEXT_ZZZ"
class="CLICKED_TEXTS"
x="65"
y="12.5">
Click me
</text>
<set
to="visible"
attributeType="CSS"
attributeName="visibility"
end="CLICKED_ZZZ.click;bg.click"
begin="CLICKME_ZZZ.click" />
<set
to="1"
attributeType="CSS"
attributeName="opacity"
end="CLICKED_ZZZ.click;bg.click"
begin="CLICKME_ZZZ.click" />
</g>
<animate id="ZZZ_ANIMATE"
fill="freeze"
dur="3s"
keyTimes="0;1"
values="0;1"
attributeType="CSS"
attributeName="opacity" />
</g>
<g id="DDD"
transform="translate(0,40)">
<g id="CLICKME_DDD">
<rect id="CLICKME_TICKBOX_FFF"
class="CLICKME_TICKBOX"
x="0"
y="0"
width="15"
height="15">
</rect>
<use id="CLICKME_LEGENDBOX_FFF"
class="LEGENDBOX_FFF"
x="30"
y="-5"
xlink:href="#LEGENDBOX">
</use>
<text id="CLICKME_TEXT_FFF"
class="CLICKME_TEXTS"
x="65"
y="12.5">
Click me
</text>
</g>
<g id="CLICKED_DDD"
class="HIDDEN_LAYER">
<use id="CLICKED_TICKBOX_FFF"
x="0"
y="0"
xlink:href="#CLICKED_TICKBOX">
</use>
<use id="CLICKED_LEGENDBOX_FFF"
class="LEGENDBOX_FFF"
x="30"
y="-5"
xlink:href="#LEGENDBOX">
</use>
<text id="CLICKED_TEXT_FFF"
class="CLICKED_TEXTS"
x="65"
y="12.5">
Click me
</text>
<set
to="visible"
attributeType="CSS"
attributeName="visibility"
end="CLICKED_DDD.click;bg.click"
begin="CLICKME_DDD.click" />
<set
to="1"
attributeType="CSS"
attributeName="opacity"
end="CLICKED_DDD.click;bg.click"
begin="CLICKME_DDD.click" />
</g>
<animate id="DDD_ANIMATE"
fill="freeze"
dur="3s"
keyTimes="0;1"
values="0;1"
attributeType="CSS"
attributeName="opacity" />
</g>
</g>
<defs id="DEFINITIONS">
<rect id="RECTANGLE"
width="85"
height="95">
</rect>
<rect id="RECTANGLE_YELLOW"
width="42.5"
height="95">
</rect>
<rect id="LEGENDBOX"
x="0"
y="0"
width="25"
height="25">
</rect>
<path id="CLICKED_TICKBOX"
class="CLICKED_TICKBOX"
d="M 0,0 15,15 M 0,15 15,0 M 0,0 15,0 15,15 0,15 Z"/>
</defs>
It would be nice if the
<use
xlink:href="#RECTANGLE"
transform="translate(15, 215)"
style="
opacity:var(--QQQ_SOMETHING_BBB, 1);
fill-opacity:var(--PPP_SOMETHING_BBB, 1)
">
</use>
Could also contain both of the titles:
<title>Something here 222.</title>
and
<title>Something here 444.</title>
depending on whether it is in <g class="FFF_RECTANGLES"> or <g class="ZZZ_RECTANGLES">.
So, it would be nice if the code could be altered, for example as:
<use
xlink:href="#RECTANGLE"
transform="translate(15, 215)"
style="
opacity:var(--QQQ_SOMETHING_BBB, 1);
fill-opacity:var(--PPP_SOMETHING_BBB, 1)"
title=:var(--SSS_SOMETHING, Or else it will be this.);
var(--TTT_SOMETHING, Or else it will be that.)"
">
</use>
The title could then be stated in:
.ZZZ_RECTANGLES{
--QQQ_SOMETHING_AAA: 0.7;
--QQQ_SOMETHING_BBB: 0.2;
--SSS_SOMETHING: Something here 222.;
}
and
.FFF_RECTANGLES{
--PPP_SOMETHING_AAA: 0.2;
--PPP_SOMETHING_BBB: 0.7;
--TTT_SOMETHING: Something here 444.;
}
Titles in SVG are elements, not attributes. So I don't believe there is any feaible way to achieve what you want using only CSS.
Since JS is universally supported, I assume you wouldn't have objection to using that to achieve this?
// Take the text typed into the input box, and use it for the tootip for the red rectangle
document.getElementById("title-input").addEventListener("input", function(evt) {
setTitleText("rect-title", this.value);
});
function setTitleText(elementId, newText) {
document.getElementById(elementId).textContent = newText;
}
<svg>
<rect y="50" width="200" height="50" fill="red">
<title id="rect-title">Default title</title>
</rect>
</svg>
<p>Enter some text to use as a title tooltip for the rect</p>
<input type="text" id="title-input"/>

Changeing an SVG from 238 to 266 and now I'm stuck

This was originally 238, I want to change it to 266, and now I'm stuck.
I've done this before, but I forgot how to do it.
I know 7 goes into 266 38 times. See, I forgot how to do all this math, how you're supposed to calculate it.
I'm confused now.
It should all fit evenly I think, or does it not?
<svg width="266" height="266" viewBox="0 0 266 266">
<rect x="0" y="0" width="266" height="266" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>
Assuming the original looked like this:
<svg width="238" height="238" viewBox="0 0 238 238">
<rect x="0" y="0" width="238" height="238" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>
Then all you have to do to scale it up to 266x266 is to update the width and height attributes.
<svg width="266" height="266" viewBox="0 0 238 238">
Because the SVG has a viewBox, the browser will scale the contents automatically for you.
<svg width="266" height="266" viewBox="0 0 238 238">
<rect x="0" y="0" width="238" height="238" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>

SVG: text over a shape disables animation on background shape

As I have demonstrated in this fiddle, I want SVG Cirlce to enlarge when hovered over it. But at the same time, I want to write some text over the circle (Eg. in the fiddle, "Hello" and "World").
I want that for user, text and circle should look as if they are the same entity. And all the time he/she has cursor over the circle, the circle should remain enlarged.
Please Run Quick Demo:
div,
svg {
background-color: grey;
height: 100px;
width: 600px;
}
<h1> test </h1>
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle id="C10" cx="50" cy="50" r="35" fill="red">Red</circle>
<animate xlink:href="#C10" attributeName="r" dur="0.2s" values="35;45;42" keyTimes="0;0.75;1" begin="mouseover" calcMode="linear" fill="freeze" />
<animate xlink:href="#C10" attributeName="r" dur="0.1s" values="42;35" keyTimes="0;1" begin="mouseout" calcMode="linear" fill="freeze" />
<circle id="C11" cx="150" cy="50" r="35" fill="green">Green</circle>
<animate xlink:href="#C11" attributeName="r" dur="0.2s" values="35;45;42" keyTimes="0;0.75;1" begin="mouseover" calcMode="linear" fill="freeze" />
<animate xlink:href="#C11" attributeName="r" dur="0.1s" values="42;35" keyTimes="0;1" begin="mouseout" calcMode="linear" fill="freeze" />
<text x="150" y="53" text-anchor="middle" font-family="Verdana" font-size="18" fill="white">Hello</text>
<circle id="C12" cx="250" cy="50" r="35" fill="orange"></circle>
<animate xlink:href="#C12" attributeName="r" dur="0.2s" values="35;45;42" keyTimes="0;0.75;1" begin="mouseover" calcMode="linear" fill="freeze" />
<animate xlink:href="#C12" attributeName="r" dur="0.1s" values="42;35" keyTimes="0;1" begin="mouseout" calcMode="linear" fill="freeze" />
<text id="T12" x="250" y="53" text-anchor="middle" font-family="Verdana" font-size="18" fill="white">World</text>
<set xlink:href="#C12" attributeName="r" to="42" begin="T12.mouseover" />
</svg>
</div>
But issue I am facing is, as we hover the text, the 'circle.mouseout' animation is triggered, and the animation written for hover over the circle ends. And when we hover from text part to circle part (visually still within the circle), The animation for 'circle.mouseover' get restarted.
I have tried a solution in third (orange circle) - hover over text resizes the circle, but that is not giving desired result.
Please help. Solution using CSS / JS also will do. Please fork the fiddle with your solution so I can understand it better :) :)
Use pointer-events: none to make text elements "transparent" to your hovering.
div,
svg {
background-color: grey;
height: 100px;
width: 600px;
}
text {
pointer-events: none;
}
<h1> test </h1>
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle id="C10" cx="50" cy="50" r="35" fill="red">Red</circle>
<animate xlink:href="#C10" attributeName="r" dur="0.2s" values="35;45;42" keyTimes="0;0.75;1" begin="mouseover" calcMode="linear" fill="freeze" />
<animate xlink:href="#C10" attributeName="r" dur="0.1s" values="42;35" keyTimes="0;1" begin="mouseout" calcMode="linear" fill="freeze" />
<circle id="C11" cx="150" cy="50" r="35" fill="green">Green</circle>
<animate xlink:href="#C11" attributeName="r" dur="0.2s" values="35;45;42" keyTimes="0;0.75;1" begin="mouseover" calcMode="linear" fill="freeze" />
<animate xlink:href="#C11" attributeName="r" dur="0.1s" values="42;35" keyTimes="0;1" begin="mouseout" calcMode="linear" fill="freeze" />
<text x="150" y="53" text-anchor="middle" font-family="Verdana" font-size="18" fill="white">Hello</text>
<circle id="C12" cx="250" cy="50" r="35" fill="orange"></circle>
<animate xlink:href="#C12" attributeName="r" dur="0.2s" values="35;45;42" keyTimes="0;0.75;1" begin="mouseover" calcMode="linear" fill="freeze" />
<animate xlink:href="#C12" attributeName="r" dur="0.1s" values="42;35" keyTimes="0;1" begin="mouseout" calcMode="linear" fill="freeze" />
<text id="T12" x="250" y="53" text-anchor="middle" font-family="Verdana" font-size="18" fill="white">World</text>
<set xlink:href="#C12" attributeName="r" to="42" begin="T12.mouseover" />
</svg>
</div>

Rotate SVG group indefinitely 360 degrees without CSS or Java

This is my first time diving into SVG. Is it possible to rotate this group 360 indefinitely without css or javascript/jquery? So far I have it rotating in the top left corner but I cannot seem to figure out how to center it.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="576" height="576" viewBox="0 0 288 288" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g id="seed" transform="translate(144,144)" stroke-width="2" stroke="black" fill="none" >
<circle cx="0" r="64" />
<circle cx="64" r="64" />
<circle cx="64" r="64" transform="rotate(60)" />
<circle cx="64" r="64" transform="rotate(120)" />
<circle cx="64" r="64" transform="rotate(180)" />
<circle cx="64" r="64" transform="rotate(240)" />
<circle cx="64" r="64" transform="rotate(300)" />
<circle cx="0" r="128" />
<animateTransform attributeType="xml" attributeName="transform" type="rotate" values="0 0 0; 360 0 0" dur="5s" repeatCount="indefinite" />
</g>
</svg>
Your animateTransform overwrites the transform on the <g> element. Looks like you want to provide an additional transform which you would with the attribute additive="sum"
<svg width="576" height="576" viewBox="0 0 288 288" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g id="seed" transform="translate(144,144)" stroke-width="2" stroke="black" fill="none" >
<circle cx="0" r="64" />
<circle cx="64" r="64" />
<circle cx="64" r="64" transform="rotate(60)" />
<circle cx="64" r="64" transform="rotate(120)" />
<circle cx="64" r="64" transform="rotate(180)" />
<circle cx="64" r="64" transform="rotate(240)" />
<circle cx="64" r="64" transform="rotate(300)" />
<circle cx="0" r="128" />
<animateTransform attributeType="xml" attributeName="transform" type="rotate" values="0 0 0; 360 0 0" dur="5s" additive="sum" repeatCount="indefinite" />
</g>
</svg>
PaEDIT: My bad you probally mean JavaScript.
Okay you can calculate the center with JavaScript and a nice SVG-method called getBBox();
A method to return center of SVG-elements so your should also be possible. Okay piece of code
var svg = {
getCenterPosition: function(elem) {
// use the native SVG interface to get it's boundingBox
var bbox = elem.getBBox();
// return the center of the bounding box
return {
px: (bbox.x + bbox.width / 2).toFixed(2),
py: (bbox.y + bbox.height / 2).toFixed(2)
};
}
}
svg.getCenterPosition(yourGElementAsParameter); will return the center-coordinates. (web developer console or Firebug or something) Then you can set these coordinates in your attributes but don't alter the viewbox or anything it will now rotate around it's center.

Resources