SVG element rotate on circle - css

So I have a SVG element - big circle - and group of elements inside .
I would like to rotate this elements around this big circle. The code is very simply, but I'm already freaking out how to set this circle (graph__skils) on correct path (big circle). As you can see on link below this small circle isn't rotating correct on the big circle. Please help
Circle rotate jsfiddle
HTML file
<section class="graph">
<svg xmlns="http://www.w3.org/2000/svg"
width="670"
height="696"
viewBox="0 0 670 696">
<g>
<g class="graph__middle">
<path fill="#3f9" d="M345 264c34.794 0 63 28.206 63 63s-28.206 63-63 63-63-28.206-63-63 28.206-63 63-63z"/>
</g>
<g class="graph__design" >
<g class="graph_mainCircle">
<path fill="none" stroke="#cf9" stroke- linecap="round" stroke-linejoin="round" stroke-miterlimit="50" d="M345 197c71.797 0 130 58.203 130 130s-58.203 130-130 130-130-58.203-130-130 58.203-130 130-130z"/>
</g>
<g class="graph__skills">
<g class="graph__middle">
<path fill="#cf9" d="M445.053 387c11.052 0 20.012 8.954 20.012 20s-8.96 20-20.012 20-20.012-8.954-20.012-20 8.96-20 20.012-20z"/>
</g>
</g>
</g>
</g>
</svg>
SCSS file
.graph {
position: relative;
width:500px;
height:500px;
svg {
position: relative;
border: 2px solid blue;
width: 99%;
height: 99%;
}
&__design {
position: relative;
}
&__skills {
transform-origin: center;
position: absolute;
animation: mercury-group 18s linear infinite;
}
&__middle {
position: relative;
}
}
#keyframes mercury-group {
0% {
transform: rotateZ(0deg);
}
100% {
transform: rotateZ(-360deg);
}
}

The center of the svg element is not the center of your planets. You will need to change the transform-origin to 345px 328px. In order to calculate the new center I've used the getBBox() method for the graph__middle
.graph {
position: relative;
width: 500px;
height: 500px;
}
.graph svg {
position: relative;
border: 2px solid blue;
width: 99%;
height: 99%;
}
.graph__design {
position: relative;
}
.graph__skills {
transform-origin: 345px 328px;
position: absolute;
animation: mercury-group 18s linear infinite;
}
.graph__middle {
position: relative;
}
#keyframes mercury-group {
0% {
transform: rotateZ(0deg);
}
100% {
transform: rotateZ(-360deg);
}
}
<section class="graph">
<svg xmlns="http://www.w3.org/2000/svg"
width="670"
height="696"
viewBox="0 0 670 696">
<g>
<g class="graph__middle" id="KK">
<path fill="red" d="M345 264c34.794 0 63 28.206 63 63s-28.206 63-63 63-63-28.206-63-63 28.206-63 63-63z"/>
</g>
<g class="graph__design" >
<g class="graph_mainCircle">
<path fill="none" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="50" d="M345 197c71.797 0 130 58.203 130 130s-58.203 130-130 130-130-58.203-130-130 58.203-130 130-130z"/>
</g>
<g class="graph__skills">
<g class="graph__middle">
<path d="M445.053 387c11.052 0 20.012 8.954 20.012 20s-8.96 20-20.012 20-20.012-8.954-20.012-20 8.96-20 20.012-20z"/>
</g>
</g>
</g>
</g>
<circle cx="345" cy="328" r="3" />
</svg>
</section>

You can rotate the big circle instead like below:
.graph {
position: relative;
width: 500px;
height: 500px;
}
svg {
position: relative;
border: 2px solid blue;
width: 99%;
height: 99%;
}
.graph__design {
position: relative;
transform-box:fill-box;
transform-origin: center;
animation: mercury-group 18s linear infinite;
}
.graph__skills {
transform-origin: center;
position: absolute;
}
.graph__middle {
position: relative;
}
#keyframes mercury-group {
0% {
transform: rotateZ(0deg);
}
100% {
transform: rotateZ(-360deg);
}
}
<section class="graph">
<svg xmlns="http://www.w3.org/2000/svg" width="670" height="696" viewBox="0 0 670 696">
<g>
<g class="graph__middle">
<path fill="#3f9" d="M345 264c34.794 0 63 28.206 63 63s-28.206 63-63 63-63-28.206-63-63 28.206-63 63-63z"/>
</g>
<g class="graph__design" >
<g class="graph_mainCircle">
<path fill="none" stroke="#cf9" stroke- linecap="round" stroke-linejoin="round" stroke-miterlimit="50" d="M345 197c71.797 0 130 58.203 130 130s-58.203 130-130 130-130-58.203-130-130 58.203-130 130-130z"/>
</g>
<g class="graph__skills">
<g class="graph__middle">
<path fill="#cf9" d="M445.053 387c11.052 0 20.012 8.954 20.012 20s-8.96 20-20.012 20-20.012-8.954-20.012-20 8.96-20 20.012-20z"/>
</g>
</g>
</g>
</g>
</svg>
</section>

SVG example
My example doesn't answer exactly your question but I hope you take some ideas from my answer.
Judging by the names of the animation mercury-group you want to create a model of the solar system.
I propose a variant of the animation of the rotation of the planet around the sun.
I located the center of rotation of the planets of the solar system in the center of the sun which has coordinates x =" 250 " y =" 175 " center of the sun
Therefore, the animation team of the rotation of the planet around the sun has the following form:
<animateTransform
attributeName="transform"
type="rotate"
values="0 250 175;360 250 175"
dur="12s"
repeatCount="indefinite"
/>
Filters and gradients are used to design the appearance of the planet and the sun.
Animation of the ripple of the sun and changing its color
<radialGradient id="gradSun">
<stop offset="80%" stop-color="yellow">
<animate attributeName="offset" values="80%;20%;80%" dur="6s" repeatCount="indefinite" />
</stop>
<stop offset="100%" stop-color="gold" >
<animate attributeName="stop-color" values="gold;red;gold" dur="6s" repeatCount="indefinite" />
</stop>
</radialGradient>
Below is the full animation code for the rotation of the planet around the sun:
.solar-system{
background-color:#002;
width:100%;
height:100%;
}
.sun{
fill:url(#gradSun);
filter:url(#dropShadow2);
}
.Earth-orbit{
stroke:rgba(255,255,255,.4);
stroke-width:1;
fill:none;
}
.Earth{
filter:url(#dropShadow1);
fill:url(#gradEarth);
}
<div class="solar-system">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 500 400" >
<defs>
<filter id="dropShadow1"
x="-20%" y="-20%"
width="150%" height="150%">
<feGaussianBlur stdDeviation="1" />
</filter>
<filter id="dropShadow2"
x="-20%" y="-20%"
width="150%" height="150%">
<feGaussianBlur stdDeviation="4" />
</filter>
<radialGradient id="gradSun">
<stop offset="80%" stop-color="yellow">
<animate attributeName="offset" values="80%;20%;80%" dur="6s" repeatCount="indefinite" />
</stop>
<stop offset="100%" stop-color="gold" >
<animate attributeName="stop-color" values="gold;red;gold" dur="6s" repeatCount="indefinite" />
</stop>
</radialGradient>
<linearGradient id="gradEarth">
<stop offset="40%" stop-color="dodgerblue"></stop>
<stop offset="100%" stop-color="yellowgreen" ></stop>
</linearGradient>
</defs>
<!-- planet rotation animation -->
<g>
<animateTransform
attributeName="transform"
type="rotate"
values="360 250 175;0 250 175"
dur="12s"
repeatCount="indefinite"
/>
<circle class="Earth-orbit" cx="250" cy="175" r="90" />
<circle class="Earth" cx="160" cy="175" r="10" transform="rotate(45 250 175)" />
</g>
<circle class="sun" cx="250" cy="175" r="20" />
</svg>

First, You must set key frames then use css animation
#-webkit-keyframes rotated {
0% {
-webkit-transform: rotate(0);
transform: rotate(0);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}}
#keyframes rotated {
0% {
-webkit-transform: rotate(0);
transform: rotate(0);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}}
Then use animation in css
.bg-shape{
animation: rotated 35s linear infinite;}
Then in html use svg image to rotate
<div class="col-lg-4">
<div class="inner-wrapper text-center">
<div class="mb-3">
<img src="../img/svg/shape-37.svg" alt="" class="bg-shape">
</div>
</div>
</div>

Related

Why is blue circle not spinning in the center of itself [duplicate]

This question already has an answer here:
CSS transform origin issue on svg sub-element
(1 answer)
Closed 3 years ago.
Why is the blue circle not rotating in the center of its own axis?
Below you can find my previous code.
Here you can see my CSS with the proportionate SVG:
circle {
animation: grow 2s infinite;
transform-origin: center;
}
#keyframes grow {
0% {
transform: scale(1);
}
50% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
<svg xmlns="http://www.w3.org/2000/svg"
width="80"
height="110"
version="1.1">
<rect width="70"
height="100"
x="5"
y="5"
fill="white"
stroke="red"
stroke-width="10"
rx="5"/>
<circle cx="40" cy="105" r="3" fill="blue"/>
</svg>
You need transform-box: fill-box;
circle {
animation: grow 2s infinite;
transform-origin: center;
transform-box: fill-box;
}
#keyframes grow {
0% {
transform: scale(1);
}
50% {
transform: scale(0.5);
}
100% {
transform: scale(1);
}
}
<svg
xmlns="http://www.w3.org/2000/svg"
width="80"
height="110"
version="1.1"
>
<rect
width="70"
height="100"
x="5"
y="5"
fill="white"
stroke="red"
stroke-width="10"
rx="5"
/>
<circle cx="40" cy="105" r="3" fill="blue" />
</svg>
Because scale in SVG is different, it makes scale in X & Y axis. Additionally it scales "cx" and "cy" properties.
The best way is to make "cx" & "cy" at 0 and use the "translate" to coordinates you need
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="110" version="1.1">
<rect
width="70"
height="100"
x="5"
y="5"
fill="white"
stroke="red"
stroke-width="10"
rx="5" />
<circle cx="0" cy="0" r="3" fill="blue" transform="translate(40 105)">
<animateTransform
attributeName="transform"
type="scale"
additive="sum"
from="1 1"
to="1 1"
values="1 1; 0.5 0.5; 1 1"
begin="0s"
dur="2s"
repeatCount="indefinite">
</animateTransform>
</circle>
</svg>
Enjoy!

SVG rounded triangle with gradient overlay and background image

I have the below code that is creating a simple rounded triangle shape with a purple gradient. I'm trying to insert a background image that will fill the shape underneath the gradient to create a similar effect to the screenshot below:
What I'm looking to achieve:
My code so far (doesn't show the image):
<svg width="100%" viewBox="0 0 1440 742" version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events">
<defs>
<linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="linearGradient-1">
<stop stop-color="#6300FF" stop-opacity="0.7" offset="0%"></stop>
<stop stop-color="#251D4B" offset="100%"></stop>
</linearGradient>
<pattern id="img1" patternUnits="userSpaceOnUse" width="1400" height="742">
<image xlink:href="https://upload.wikimedia.org/wikipedia/commons/1/11/Varkala_Beach_High_Res.jpg" x="0" y="0" width="1400" height="742" />
</pattern>
<path d="M526.611472,1330.75724 C526.681681,1330.68703 525.998884,-525.688822 526.611472,-525.076039 L1243.10385,191.419563 C1359.86286,308.179101 1359.86286,497.502097 1243.10385,614.261635 L526.611472,1330.75724 Z" id="path-2"></path>
</defs>
<g id="Desktop" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Knowledge-base-article">
<g id="businessman-in-workplace-PYDTUKV" transform="translate(-209.000000, -63.000000)">
<mask id="mask-3" fill="white">
<use xlink:href="#path-2"></use>
<use xlink:href="#img1"></use>
</mask>
<use id="Mask" fill="url(#linearGradient-1)" transform="translate(928.513633, 402.840523) scale(-1, 1) rotate(90.000000) translate(-928.513633, -402.840523) " xlink:href="#path-2"></use>
</g>
</g>
</g>
</svg>
I would go with a pure CSS solution using some transformation like below
.container {
width:300px;
height:300px;
margin:auto;
position:relative;
overflow:hidden;
}
.container > div {
position:absolute;
width:100%;
height:100%;
border-radius:80px;
transform-origin:top left;
transform:translateX(-20%) rotate(-45deg);
overflow:hidden;
}
.container > div:before {
content:"";
position:absolute;
width:calc(100% * 1.4);
height:calc(100% * 1.4);
transform:rotate(45deg);
transform-origin:top left;
background:
linear-gradient(to top,rgba(99, 0, 255, 0.7),#251D4B),
url(https://picsum.photos/300/300?image=1069) top/cover;
}
<div class="container">
<div></div>
</div>
With the container as full width:
.container {
margin:auto;
position:relative;
overflow:hidden;
}
.container > div {
width:100%;
padding-top:100%;
border-radius:15%;
transform-origin:top left;
transform:translateY(-15%) translateX(-21%) rotate(-45deg);
overflow:hidden;
}
.container > div:before {
content:"";
position:absolute;
top:0;
left:0;
width:calc(100% * 1.4);
height:calc(100% * 1.4);
transform:rotate(45deg);
transform-origin:top left;
background:
linear-gradient(to top,rgba(99, 0, 255, 0.7),#251D4B),
url(https://picsum.photos/300/300?image=1069) top/cover;
}
<div class="container">
<div></div>
</div>
Use the <path> as a <mask>. Then use that <mask> on a your <image>, then use that same <mask> on a <rect> that sits on top. Finally fill the <rect> with your <gradient>.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
<defs>
<linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="gradient">
<stop stop-color="#6300FF" stop-opacity="0.7" offset="0%"></stop>
<stop stop-color="#251D4B" offset="100%"></stop>
</linearGradient>
<mask id="mask">
<path d="M812.532 489.667L1306.8 -4.60034H-106L388.268 489.667C505.425 606.825 695.374 606.825 812.532 489.667Z" fill="#C4C4C4"/>
</mask>
</defs>
<image xlink:href="https://upload.wikimedia.org/wikipedia/commons/1/11/Varkala_Beach_High_Res.jpg" x="0" y="0" width="1200" height="800" mask="url(#mask)" />
<rect width="1400" height="742" mask="url(#mask)" fill="url(#gradient)"></rect>
</svg>

Why doesn't a circular SVG look like a circle with animation?

.refresh-wrap {
width: 200px;
height: 200px;
border: 3px dotted red;
}
.refresh-wrap .svg-icon {
animation: rotatefresh 1s infinite linear;
transform-origin: 50% 50%;
}
#keyframes rotatefresh {
100% {
transform: rotate(360deg) translateZ(0);
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
style="position: absolute; width: 0; height: 0" id="__SVG_SPRITE_NODE__">
<symbol viewBox="0 0 24 24" id="icon-refresh">
<!-- Generator: Sketch 49 (51002) - http://www.bohemiancoding.com/sketch -->
<title>刷新</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="icon-refresh_Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="icon-refresh_拍品详情-出价" transform="translate(-339.000000, -867.000000)" fill="#FF9A00"
fill-rule="nonzero">
<g id="icon-refresh_提交" transform="translate(0.000000, 701.000000)">
<g id="icon-refresh_刷新" transform="translate(339.000000, 166.000000)">
<path d="M12.2016807,24 C11.700628,24 11.2941176,23.5855666 11.2941176,23.0740726 C11.2941176,22.5625785 11.700628,22.1481451 12.2016807,22.1481451 C17.706141,22.1481451 22.184847,17.5790883 22.184847,11.9629708 C22.184847,8.33764134 20.2716461,4.95675165 17.1914975,3.13925865 C16.7578056,2.88337408 16.6094934,2.31702211 16.8600332,1.87425184 C17.1111393,1.43178418 17.6671484,1.28016825 18.1002471,1.53638297 C21.739344,3.68332633 24,7.67876817 24,11.9629983 C23.999973,18.6002881 18.7070599,24 12.2016807,24 Z"
id="icon-refresh_Shape"></path>
<path d="M6.81501566,22.5882353 C6.67498165,22.5882353 6.53257464,22.5554577 6.39963265,22.486312 C2.45209185,20.4339192 0,16.3780143 0,11.9013052 C0,5.33882725 5.29295139,0 11.7983174,0 C12.2993711,0 12.7058824,0.409760463 12.7058824,0.915487094 C12.7058824,1.42121373 12.2993711,1.83097419 11.7983174,1.83097419 C6.29384538,1.83097419 1.81512991,6.34851245 1.81512991,11.9013051 C1.81512991,15.6896036 3.89023824,19.1217826 7.23155824,20.8585859 C7.67706218,21.0904498 7.85196313,21.6423643 7.62210564,22.0917571 C7.4614157,22.4070474 7.14354146,22.5882353 6.81501566,22.5882353 Z"
id="icon-refresh_Shape"></path>
<path d="M17.1246966,7.05882353 C16.6329542,7.05882353 16.2352941,6.66118273 16.2352941,6.17041419 L16.2352941,2.32065794 C16.2352941,1.82988938 16.640232,1.41176471 17.1319744,1.41176471 L20.9916537,1.41176471 C21.4833961,1.41176471 21.8823529,1.82922947 21.8823529,2.31999801 C21.8823529,2.81076655 21.4833961,3.22823132 20.9916537,3.22823132 L18.0140991,3.22823132 L18.0140991,6.17044058 C18.0140991,6.66118275 17.6164391,7.05882353 17.1246966,7.05882353 Z"
id="icon-refresh_Shape"></path>
<path d="M6.86796299,22.5882353 L3.00832963,22.5882353 C2.51659643,22.5882353 2.11764706,22.1898582 2.11764706,21.6965763 C2.11764706,21.2032944 2.51659643,20.8049173 3.00832963,20.8049173 L5.98593424,20.8049173 L5.98593424,17.8341355 C5.98593424,17.3408537 6.38358686,16.9411765 6.87532006,16.9411765 C7.36705326,16.9411765 7.76470588,17.3408537 7.76470588,17.8341355 L7.76470588,21.7036072 C7.76473236,22.1968891 7.35969619,22.5882353 6.86796299,22.5882353 Z"
id="icon-refresh_Shape"></path>
</g>
</g>
</g>
</g>
</symbol>
</svg>
<div class="refresh-wrap">
<svg class="svg-icon" width="200" height="200">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-refresh"></use>
</svg>
</div>
I use SVG to loading. But I found that if you use animation, SVG will shake.
Environment:
Both PC and Mobile

SVG animateTransform not working same as css3 transform

SVG animateTransform not working same as the css3 transform.
svg.truck {
overflow: visible;
}
.smoke{
transform-origin: 50% 50%;
animation: smoke 1.5s infinite ease-out;
}
#keyframes smoke {
from {transform: translate(0, 5px) scale(1, 1);}
to { transform: translate(40px, 10px) scale(4, 4);}
}
<svg class='truck' height='53' viewBox='0 0 93 53' width='93' xmlns='http://www.w3.org/2000/svg'>
<g>
<circle cx='90' cy='35' fill='#000' r='2.5'>
<animateTransform attributeName='transform' attributeType='XML' dur='1.5s' from='1' repeatCount='indefinite' to='4' type='scale'></animateTransform>
<animateTransform additive='sum' attributeName='transform' attributeType='XML' dur='1.5s' from='0, 5' repeatCount='indefinite' to='40,10' type='translate'></animateTransform>
</circle>
</g>
</svg>
<hr>
<svg class='truck' height='53' viewBox='0 0 93 53' width='93' xmlns='http://www.w3.org/2000/svg'>
<g class='smoke-group'>
<circle class='smoke' cx='90' cy='35' fill='#000' r='2.5' />
</g>
</svg>
The problem is that SVG animations don't have the ability to set transform-origin like you can with CSS. So the scale transform is affecting the position as well as the size.
The simplest solution is put the circle at the origin and resposition it with the parent group element.
Also, to match the CSS, you need to switch the order of your <animateTransform> elements.
svg.truck {
overflow: visible;
}
.smoke{
transform-origin: 50% 50%;
animation: smoke 1.5s infinite ease-out;
}
#keyframes smoke {
from {transform: translate(0, 5px) scale(1, 1);}
to { transform: translate(40px, 10px) scale(4, 4);}
}
<svg class='truck' height='53' viewBox='0 0 93 53' width='93' xmlns='http://www.w3.org/2000/svg'>
<g transform="translate(90,35)">
<circle cx='0' cy='0' fill='#000' r='2.5'>
<animateTransform attributeName='transform' attributeType='XML' dur='1.5s' from='0, 5' repeatCount='indefinite' to='40,10' type='translate'></animateTransform>
<animateTransform additive='sum' attributeName='transform' attributeType='XML' dur='1.5s' from='1' repeatCount='indefinite' to='4' type='scale'></animateTransform>
</circle>
</g>
</svg>
<hr>
<svg class='truck' height='53' viewBox='0 0 93 53' width='93' xmlns='http://www.w3.org/2000/svg'>
<g class='smoke-group'>
<circle class='smoke' cx='90' cy='35' fill='#000' r='2.5' />
</g>
</svg>

SVG image CSS3 animation

I need to make the first dot of my bubble chat visible and invisible in an infinit CSS3 animation.
Why doesn't my code work ?
#keyframes onoff {
0% { display: none; }
25% { display: block; }
50% { display: none; }
100% { display: block; }
}
#circle1 {
animation: onoff 5s infinite;
}
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 24 24">
<g stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" fill="none">
<path d="M.5 16.5c0 .553.447 1 1 1h2v4l4-4h15c.552 0 1-.447 1-1v-13c0-.553-.448-1-1-1h-21c-.553 0-1 .447-1 1v13z" />
<!--Annimation on this cicle-->
<circle id="circle1" cx="8.5" cy="10" r=".5" />
<!-- -->
<circle id="circle2" cx="16.5" cy="10" r=".5" />
<circle id="circle3 " cx="12.5" cy="10" r=".5" />
</g>
</svg>
The display property isn't animatable (see MDN). You can animate the opacity though.
Example :
#keyframes onoff {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
#circle1 {
animation: onoff 2s infinite;
}
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240" viewBox="0 0 24 24">
<g stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" fill="none">
<path d="M.5 16.5c0 .553.447 1 1 1h2v4l4-4h15c.552 0 1-.447 1-1v-13c0-.553-.448-1-1-1h-21c-.553 0-1 .447-1 1v13z" />
<circle id="circle1" cx="8.5" cy="10" r=".5" />
<circle id="circle2" cx="16.5" cy="10" r=".5" />
<circle id="circle3 " cx="12.5" cy="10" r=".5" />
</g>
</svg>

Resources