I am using
in svg
to roate som circles and texts around a point at the same time, however, I want to k
<g id = "common"`>
....
</g>
<animateTransform xlink:href="#common"
attributeName="transform"
type="rotate"
begin="svg1.click"
restart="whenNotActive"
repeatCount="indefinite"
dur="10s"
values="
0, 75.74, 74.91;
-360, 75.74, 74.91"
additive="sum" />
<animateTransform attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive"
repeatCount="indefinite" dur="10s"
values="
0, 56.13, 106.87;
360, 56.13, 106.87"
additive="sum" />
<script>
//Find the center of rotation of the letter A
let bb = a1.getBBox();
console.log(bb.x+bb.width/2);
console.log(bb.y+bb.height/2);
</script>
The animation will start after clicking
text {
font-family:sans-serif;
font-size:14px;
font-weight:bold;
fill:#6E6E6E;
}
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="190px" height="190px" viewBox="0 0 150 150" version="1.1">
<defs>
</defs>
<g id="common">
<g transform="translate(-27.970238,-63.089294)">
<circle cx="102.9" cy="138.0" r="75" fill="#faa"/>
<path d="m163.7 175.2-121.5 0 60.8-105.2z" fill="#fea"/>
<!-- Spiral -->
<path d="m101.3 136.5c1.1 2-2.1 2.5-3.3 1.9-3.2-1.7-2.6-6.2-0.5-8.4 3.7-4.1 10.2-2.9 13.6 0.9 5 5.6 3.3 14.3-2.3 18.8-7.4 6-18.4 3.7-23.9-3.6-7-9.2-4.1-22.5 5-29.1 11-8 26.6-4.4 34.3 6.4 9 12.8 4.8 30.7-7.8 39.4-14.6 10-34.8 5.2-44.6-9.2-11.1-16.4-5.6-39 10.6-49.7 18.2-12.1 43.1-6 54.9 11.9 13.1 19.9 6.4 47.2-13.3 60.1" style="fill:none;stroke-width:1;stroke:#6E6E6E">
</path>
<g id="La">
<circle cx="55.9" cy="108.0" r="12.9" fill="#efa"/>
<text id="a1" x="51" y="112">
A
</text>
<!-- Animation of the rotation of the letter `A` -->
<animateTransform attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 56.13, 106.87;360, 56.13, 106.87" additive="sum" />
</g>
<g>
<circle cx="153.7" cy="110.3" r="12.9" fill="#efa"/>
<text id="b1" xml:space="preserve" x="114" y="116" >
B
</text>
<!-- Animation of the rotation of the letter `B` -->
<animateTransform attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 153.7, 110.3;360, 153.7, 110.3" additive="sum" />
</g>
<g>
<circle cx="105.2" cy="192.5" r="12.9" fill="#efa" />
<text id="c1" x="100" y="198" >
C
</text>
<!-- Animation of the rotation of the letter `C` -->
<animateTransform attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 104.93, 193.46;360, 104.93, 193.46" additive="sum" />
</g>
</g>
</g>
<!-- Animating the rotation of the entire shape -->
<animateTransform xlink:href="#common" attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 75.74, 74.91;-360, 75.74, 74.91" additive="sum" />
</svg>
<script>
//Find the center of rotation of the letter A
let bb = a1.getBBox();
console.log(bb.x+bb.width/2);
console.log(bb.y+bb.height/2);
</script>
Example with adding animation of the ball movement in a spiral
text {
font-family:sans-serif;
font-size:14px;
font-weight:bold;
fill:#6E6E6E;
}
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="190px" height="190px" viewBox="0 0 150 150" version="1.1">
<defs>
</defs>
<g id="common">
<g transform="translate(-27.970238,-63.089294)">
<circle cx="102.9" cy="138.0" r="75" fill="#faa"/>
<path d="m163.7 175.2-121.5 0 60.8-105.2z" fill="#fea"/>
<path d="m163.7 175.2-121.5 0 60.8-105.2z" fill="#fea"/>
<!-- Spiral track (pink) -->
<path id="track" d="m101.3 136.5c1.1 2-2.1 2.5-3.3 1.9-3.2-1.7-2.6-6.2-0.5-8.4 3.7-4.1 10.2-2.9 13.6 0.9 5 5.6 3.3 14.3-2.3 18.8-7.4 6-18.4 3.7-23.9-3.6-7-9.2-4.1-22.5 5-29.1 11-8 26.6-4.4 34.3 6.4 9 12.8 4.8 30.7-7.8 39.4-14.6 10-34.8 5.2-44.6-9.2-11.1-16.4-5.6-39 10.6-49.7 18.2-12.1 43.1-6 54.9 11.9 13.1 19.9 6.4 47.2-13.3 60.1" style="fill:none;stroke-width:3;stroke:#FFAAAA"/>
<!-- Spiral -->
<path stroke-dasharray="0,432" d="m101.3 136.5c1.1 2-2.1 2.5-3.3 1.9-3.2-1.7-2.6-6.2-0.5-8.4 3.7-4.1 10.2-2.9 13.6 0.9 5 5.6 3.3 14.3-2.3 18.8-7.4 6-18.4 3.7-23.9-3.6-7-9.2-4.1-22.5 5-29.1 11-8 26.6-4.4 34.3 6.4 9 12.8 4.8 30.7-7.8 39.4-14.6 10-34.8 5.2-44.6-9.2-11.1-16.4-5.6-39 10.6-49.7 18.2-12.1 43.1-6 54.9 11.9 13.1 19.9 6.4 47.2-13.3 60.1" style="fill:none;stroke-width:2;stroke:#6E6E6E">
<!-- Spiral animation -->
<animate attributeName="stroke-dasharray" begin="svg1.click" repeatCount="indefinite" restart="whenNotActive" dur="10s" values="0,432;432,0;0,432" fill="freeze" />
</path>
<circle cx="0" cy="0" r="6" fill="#6E6E6E">
<!-- Ball movement in a spiral clockwise -->
<animateMotion id="forwards"
begin="svg1.click;back.end"
dur="5s" >
<mpath xlink:href="#track" />
</animateMotion>
<!-- Ball movement in a spiral counterclockwise -->
<animateMotion
id="back"
dur="5s"
begin="forwards.end"
repeatCount="1"
keyPoints="1;0"
keyTimes="0;1"
calcMode="linear"
rotate="auto"
fill="freeze" >
<mpath xlink:href="#track" />
</animateMotion>
</circle>
<g id="La">
<circle cx="55.9" cy="108.0" r="12.9" fill="#efa"/>
<text x="51" y="112"> A </text>
<animateTransform attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 55.9, 108;360, 55.9, 108" additive="sum" />
</g>
<g>
<circle cx="153.7" cy="110.3" r="12.9" fill="#efa"/>
<text xml:space="preserve" x="114" y="116" >
B
</text>
<animateTransform attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 153.7, 110.3;360, 153.7, 110.3" additive="sum" />
</g>
<g>
<circle cx="105.2" cy="192.5" r="12.9" fill="#efa" />
<text x="100" y="198" > C
</text>
<!-- Animation of the rotation of the letter `C` -->
<animateTransform attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 105.2, 192.5;360, 105.2, 192.5" additive="sum" />
</g>
</g>
</g>
<!-- Animating the rotation of the entire shape -->
<animateTransform xlink:href="#common" attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"
values="0, 75.38, 75;-360, 75.38, 75" additive="sum" />
</svg>
Instead of rotation of <g>roup
and reverse rotation of the text within it, try this alternate grouping. Center the <g>
around origin(0,0)
with negative x=
and y=
values & use rotate(degree, 0, 0)
on circle_group
, then translate(x,y)
on the main_group
.
Edit: Here's an animated example, modified from this source. The trick is to move it around the origin with sin() and cos() trigonometric functions.
<!DOCTYPE html>
<html>
<head>
<title>JavaScript SVG Animation</title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/> <!-- Remove this line in production. -->
</head>
<body>
<svg width="800px" height="800px" viewBox="0 0 800 800">
<g transform="translate(400, 400)"> <!-- Create a Cartesian coordinate system (with the y-axis flipped) for the animated square. That is, place the origin at the center of the 800 x 800 SVG viewport: -->
<!-- A 200 x 200 square with the upper left-hand corner at (-100, -100). This places the center of the square
at the origin (0, 0): -->
<rect id="mySquare" x="-100" y="-100" width="200" height="200" rx="5" ry="5"
style=" fill: yellow; stroke: yellow; stroke-width: 1; stroke-dasharray: 10, 5;" />
<!-- Represents the x-axis: -->
<line x1="-400" y1="0" x2="400" y2="0" style="stroke: blue;" />
<!-- Represents the y-axis (although up is negative and down is positive): -->
<line x1="0" y1="-400" x2="0" y2="400" style="stroke: blue;" />
<circle cx="0" cy="0" r="141" fill="none" stroke="yellow"/>
<g id="circle_a">
<circle cx="0" cy="0" r="10" fill="none" stroke="blue"/>
<text x="-5" y="5" width="20" height="20">A</text>
</g>
<g id="circle_b">
<circle cx="0" cy="0" r="10" fill="none" stroke="red"/>
<text x="-5" y="5" width="20" height="20">B</text>
</g>
</g>
</svg>
<script>
"use strict";
/* CONSTANTS */
var initialTheta = 0; // The initial rotation angle, in degrees.
var thetaDelta = 0.3; // The amount to rotate the square about every 16.7 milliseconds, in degrees.
var angularLimit = 180; // The maximum number of degrees to rotate the square.
var theSquare = document.getElementById("mySquare");
var circleA = document.getElementById("circle_a");
var circleB = document.getElementById("circle_b");
theSquare.currentTheta = initialTheta; // The initial rotation angle to use when the animation starts, stored in a custom property.
var requestAnimationFrameID = requestAnimationFrame(doAnim); // Start the loop.
function doAnim() {
if (theSquare.currentTheta > angularLimit) {
cancelAnimationFrame(requestAnimationFrameID); // The square has rotated enough, instruct the browser to stop calling the doAnim() function.
return; // No point in continuing, bail now.
}
theSquare.setAttribute("transform", "rotate(" + theSquare.currentTheta + ")"); // Rotate the square by a small amount.
circleA.setAttribute("transform", "translate(" +Math.cos((theSquare.currentTheta-45)*Math.PI/180)*141 + "," + Math.sin((theSquare.currentTheta-45)*Math.PI/180)*141+")"); // Move the circle A
circleB.setAttribute("transform", "translate(" +Math.cos((theSquare.currentTheta+45)*Math.PI/180)*141 + "," + Math.sin((theSquare.currentTheta+45)*Math.PI/180)*141+")"); // move the circle B
theSquare.currentTheta += thetaDelta; // Increase the angle that the square will be rotated to, by a small amount.
requestAnimationFrameID = requestAnimationFrame(doAnim); // Call the doAnim() function about 60 times per second (60 FPS), or about once every 16.7 milliseconds until cancelAnimationFrame() is called.
}
</script>