Анимация тени блока / текста по круговой траектории?
Я пытаюсь использовать CSS-анимацию для создания эффекта источника света, указывающего на объект вниз, отбрасывающего тень. И кругового движения вокруг него. Я создал фрагмент ниже, чтобы показать, что у меня получилось.
Решение вроде бы близко, но на данный момент (потому что у меня всего 4 ключевых кадра) получается, что источник света движется по квадратной траектории. Я бы хотел, чтобы он выглядел так, как будто он движется по круговой траектории.
Единственное решение, которое я могу придумать, чтобы приблизиться к круговой траектории, - это добавить еще несколько ключевых кадров и создать (для простоты) путь в форме двенадцатиугольника, но есть ли более простое решение?
Есть ли какая-то функция времени, которую я мог бы использовать, чтобы упростить ее?
Или я могу использовать какую-то функцию Sass для автоматического вычисления промежуточных ключевых кадров?
Я должен был заметить, что как только я получу эту работу с тенями блока, я также хотел бы применить тот же метод к теням текста.
.container {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
}
.circle {
width: 200px;
height: 200px;
border-radius: 100%;
background-color: teal;
box-shadow: 50px 50px 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
@keyframes orbit-shadow {
0% {
box-shadow: 50px 50px 5px darkgrey;
}
25% {
box-shadow: -50px 50px 5px darkgrey;
}
50% {
box-shadow: -50px -50px 5px darkgrey;
}
75% {
box-shadow: 50px -50px 5px darkgrey;
}
1000% {
box-shadow: 50px 50px 5px darkgrey;
}
}
<div class="container">
<div class="circle"></div>
</div>
Свободный перевод вопроса Animating a box-shadow/text-shadow on a circular path? от участника @itsViney.
Ответы (1 шт):
Для этого нужно учитывать ротацию. Используйте псевдоэлемент, чтобы не вращать основной элемент:
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
position:relative;
z-index:0;
}
.circle {
width: 200px;
height: 200px;
margin:50px;
border-radius: 100%;
background-color: teal;
position:relative;
}
.circle::before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
border-radius:inherit;
box-shadow: 50px 50px 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
@keyframes orbit-shadow {
100% {
transform:rotate(360deg);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle"></div>
</div>
Или вы просто поворачиваете элемент, если у вас не будет содержимого:
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.circle {
width: 200px;
height: 200px;
border-radius: 100%;
background-color: teal;
box-shadow: 50px 50px 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
@keyframes orbit-shadow {
100% {
transform:rotate(360deg);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle"></div>
</div>
Другая идея
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
position:relative;
z-index:0;
}
.circle {
width: 200px;
height: 200px;
margin:50px;
border-radius: 100%;
background-color: teal;
position:relative;
}
.circle::before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
border-radius:inherit;
background:darkgrey;
filter:blur(5px);
animation: orbit-shadow 5s linear infinite;
}
@keyframes orbit-shadow {
0% {
transform:rotate(0deg) translate(50px);
}
100% {
transform:rotate(360deg) translate(50px);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle"></div>
</div>
Вы также можете сделать то же самое для text-shadow с немного другой анимацией, чтобы текст не поворачивался:
.container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.circle {
position:relative;
font-size:40px;
font-weight:bold;
}
.circle::before,
.circle::after{
content:attr(data-text);
position:relative;
z-index:1;
}
.circle::before {
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
color:transparent;
text-shadow:0 0 5px darkgrey;
animation: orbit-shadow 5s linear infinite;
}
/* the 50px is your offset */
@keyframes orbit-shadow {
0% {
transform:rotate(0deg) translate(50px) rotate(0deg);
}
100% {
transform:rotate(360deg) translate(50px) rotate(-360deg);
}
}
body{
margin:0;
}
<div class="container">
<div class="circle" data-text="some text"></div>
</div>
Свободный перевод ответа от участника @Temani Afif.