Как анимировать движение круга по окружности другого большого круга с помощью SVG
Я хочу перемещать маленький круг по окружности большого круга, используя CSS или SVG
@keyframes moveAround {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#small {
animation: moveAround 2s infinite linear;
}
<svg width="120" height="100" viewBox="0 0 120 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="circles">
<circle id="big" cx="60" cy="50" r="30" fill="white" stroke="#2493AB" stroke-width="20" />
<circle id="small" cx="60" cy="20" r="10" fill="#EF6868" />
</g>
</svg>
Свободный перевод вопроса https://stackoverflow.com/q/66838390/7394871 от участника @Subato Patnaik.
Ответы (4 шт):
Вы должны указать, вокруг какой координаты круг должен вращаться. По умолчанию это координата 0,0, но вы хотите, чтобы она вращалась вокруг центра большого круга.
В CSS вы делаете это с помощью transform-origin:
#small {
transform-origin: 60px 50px;
animation: moveAround 2s infinite linear;
}
@keyframes moveAround {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
<svg width="120" height="100" viewBox="0 0 120 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="circles">
<circle id="big" cx="60" cy="50" r="30" fill="white" stroke="#2493AB" stroke-width="20" />
<circle id="small" cx="60" cy="20" r="10" fill="#EF6868" />
</g>
</svg>
SMIL SVG решение
Для вращения шарика используйте animateTransform
<svg width="120" height="100" viewBox="0 0 120 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="circles">
<circle id="big" cx="60" cy="50" r="30" fill="white" stroke="#2493AB" stroke-width="20" />
<circle id="small" cx="60" cy="20" r="10" fill="#EF6868" >
<animateTransform
attributeName="transform"
type="rotate"
begin="0s"
dur="3s"
values="
0 60 50;
360 60 50"
repeatCount="indefinite" />
</circle>
</g>
</svg>
Вращение шарика с паузами в конечной точке
<svg width="120" height="100" viewBox="0 0 120 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="circles">
<circle id="big" cx="60" cy="50" r="30" fill="white" stroke="#2493AB" stroke-width="20" />
<circle id="small" cx="60" cy="20" r="10" fill="#EF6868" >
<animateTransform id="an"
attributeName="transform"
type="rotate"
begin="0s;an.end+1s"
dur="2s"
values="
0 60 50;
360 60 50"
/>
</circle>
</g>
</svg>
Вращение вперед-назад
<svg width="120" height="100" viewBox="0 0 120 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="circles">
<circle id="big" cx="60" cy="50" r="30" fill="white" stroke="#2493AB" stroke-width="20" />
<circle id="small" cx="60" cy="20" r="10" fill="#EF6868" >
<animateTransform
attributeName="transform"
type="rotate"
begin="0s"
dur="4s"
values="
0 60 50;
360 60 50;
360 60 50;
0 60 50;
0 60 50"
repeatCount="indefinite" />
</circle>
</g>
</svg>
Свободный перевод ответа от участника @Alexandr_TT.
Решение только для CSS без SVG
.box {
width: 60px;
height: 60px;
border: 20px solid #2493AB;
border-radius: 50%;
position: relative;
}
.box::before {
content: "";
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background: #EF6868;
animation: moveAround 3s linear infinite;
}
@keyframes moveAround {
from {
transform: rotate(0deg) translate(40px);
}
to {
transform: rotate(360deg) translate(40px);
}
}
<div class="box"></div>
Свободный перевод ответа от участника @Temani Afif.
Элементы изображаем с помощью градиентов radial-gradient. Анимацию вращения имитируем с помощью трансформации transform: rotate.
.box {
width: 100px; height: 100px; animation: circle 3s linear infinite;
background:
radial-gradient(yellow, yellow 9px, transparent 10px),
radial-gradient(circle at center, transparent, transparent 30px, red 31px, red 49px, transparent 50px, transparent 100%);
background-position: 0 -40px, 0 0;
}
@keyframes circle {0% {transform: rotate(0deg);} 100% {transform: rotate(360deg);}}
<div class="box"></div>
Такую анимацию конечно можно выполнить и с помощью позиционирования фона background-position, но тогда получится добрая простыня стилей, потому что позиционирование будет смещаться на пиксель-в-пиксель, так как анимация вращения должна быть по кругу. Поэтому приведу самый простой пример анимации с помощью позиционирования фона. При том, что анимация передвижения элемента не по кругу, правило @keyframes уже включает в себя пять кадров.
.box {
width: 100px; height: 100px; animation: circle 5s linear infinite;
background:
radial-gradient(yellow, yellow 9px, transparent 10px),
linear-gradient( 45deg, transparent, transparent 50px, red 51px, red 69px, transparent 70px, transparent 100%),
linear-gradient( 0deg, transparent, red 0px, red 19px, transparent 19px, transparent 100%);
background-position: -40px -41px, 0 -16px, 0 0;
}
@keyframes circle {
0% {background-position: -40px -41px, 0 -16px, 0 0;}
25% {background-position: 41px 41px, 0 -16px, 0 0;}
50% {background-position: -40px 41px, 0 -16px, 0 0;}
75% {background-position: 40px 41px, 0 -16px, 0 0;}
100% {background-position: -40px -41px, 0 -16px, 0 0;}
}
<div class="box"></div>