Использование css-анимации для перемещения элемента div в каждый угол страницы
Я новичок в сцене анимации css. Я хотел бы узнать, как использовать анимацию css, чтобы элемент div круга переходил в каждый угол страницы.
Я пытался сделать это, но безрезультатно, пожалуйста, помогите.
Довольно простой вопрос, но он поможет мне понять, как работает css анимация.
<!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">
<title>CSS 201</title>
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
<style>
.box {
width: 300px;
height: 300px;
border: 10px solid black;
background-color: black;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
animation: myAnimation 4s infinite alternate,myAnimation2 4s infinite alternate;
}
@keyframes myAnimation {
0% { top: 0; left: 0; }
30% { top: 3000px; }
68%, 72% { left: 50px; }
100% { top: 3000px; left: 90%; }
}
@keyframes myAnimation2{
0% { bottom: 0; right: 0; }
30% { top: 3000px; }
68%, 72% { left: 50px; }
100% { top: 3000px; left: 90%; }
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
Свободный перевод вопроса Using css animation to make a div element move to each corner of the page от участника @иStefan.
Ответы (5 шт):
В своем решении я использовал transform: translate() translateY(), чтобы не допустить, чтобы анимированный объект создавал переполнение.
В этом решении второй @keyframes с именем myAnimation2 был удален, так как в этом коде не было смысла.
Кроме того, я уменьшил размер анимированного элемента для лучшего визуального восприятия анимации в моем примере.
body {
margin: 0;
}
.box {
width: 100px;
height: 100px;
border: 10px solid black;
background-color: black;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
animation: myAnimation 4s infinite;
}
@keyframes myAnimation {
0% {
top: 0;
left: 0;
transform: translate(0) translateY(0);
}
25% {
top: 100%;
left: 0;
transform: translateX(0) translateY(-100%);
}
50% {
top: 100%;
left: 100%;
transform: translateX(-100%) translateY(-100%);
}
75% {
top: 0;
left: 100%;
transform: translateX(-100%) translateY(0);
}
100% {
top: 0;
left: 0;
transform: translateX(0) translateY(0);
}
}
<div class="box"></div>
Свободный перевод ответа от участника @s.kuznetsov.
Более простая идея с использованием фона без сложных ключевых кадров:
.box {
background:
radial-gradient(farthest-side,black 97%,transparent)
top left/100px 100px /* simply adjust the values here to control the size of the circle */
no-repeat;
position: fixed;
top: 0;
left: 0;
right:0;
bottom:0;
animation: move 4s infinite;
}
@keyframes move {
25% { background-position: bottom left }
50% { background-position: bottom right }
75% { background-position: top right }
}
<div class="box"></div>
Свободный перевод ответа от участника @Temani Afif.
Изменения в правилах CSS вопроса
.box {
width: 300px;
height: 300px;
border: 10px solid black;
background-color: black;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
animation: myAnimation 4s infinite;
}
@keyframes myAnimation {
5% { top: 0; left: 0; }
25% { top: 200px; left: 0px; }
50% { top: 200px; left: calc(100% - 320px); }
75% { top: 0px; left: calc(100% - 320px); }
100% { top: 0px; left: 0; }
}
<div class="box"></div>
Свободный перевод ответа от участника @Lalji Tadhani.
Рассмотрите возможность использования SMIL SVG для решения этого вопроса.
На мой взгляд SMIL это мощная и гибкая платформа для реализации анимаций, которая легка в настройке и не требует, как анимация CSS пересчета таймингов, в случае изменения логики приложения.
Гибкость smil заключается в том, что достаточно изменить логические цепочки, определяющие последовательность анимаций, и это даст возможность полностью пересобрать приложение, не затрачивая значительных усилий на пересчет таймингов.
1#. Решение примера из вопроса: один шар перемещается в углы страницы.
Для этого достаточно задать координаты углов в атрибуте values и шар будет перемещаться по углам страницы
Анимация начнется после клика
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100vw" height="95vh" viewBox="0 0 400 400" preserveAspectRatio="xMinYMin meet" >
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect x="10" y="10" width="380" height="380" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<circle cx="30" cy="30" r="3%" fill="url(#gradB)" >
<animateTransform
attributeName="transform"
type="translate"
begin="svg1.click"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,340;
0,340;
0,0;
0,0" />
</circle>
</svg>
#2. Добавлены паузы при приходе шарика в углы
Для реализации пауз анимации в углах дублируются координаты этих углов
values="
0,0;
340,0;
340,0;
340,340;
340,340;
0,340;
0,340;
0,0;
0,0" />
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100vw" height="95vh" viewBox="0 0 400 400" preserveAspectRatio="xMinYMin meet" >
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect x="10" y="10" width="380" height="380" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<circle cx="30" cy="30" r="3%" fill="url(#gradB)" >
<animateTransform
attributeName="transform"
type="translate"
begin="svg1.click"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,0;
340,340;
340,340;
0,340;
0,340;
0,0;
0,0" />
</circle>
#3. Анимация двух шаров
Запуском второй анимации (красного шара) управляет логическая цепочка
begin="anBlue.begin+3s"
Словами можно сказать, что анимация красного шарика начнется через 3s после старта анимации голубого шарика.
Вот это и есть логические цепочки, который управляют последовательностью выполнения анимаций.
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100vw" height="95vh" viewBox="0 0 400 400" preserveAspectRatio="xMinYMin meet" >
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
<radialGradient id="gradR" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="red" offset="25%"/>
<stop stop-color="rgb(192,0,0)" offset="50%"/>
<stop stop-color="rgb(127,0,0)" offset="70%"/>
<stop stop-color="rgb(64,0,0)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect x="10" y="10" width="380" height="380" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<!-- Red ball -->
<circle cx="30" cy="30" r="3%" fill="url(#gradR)" >
<!-- Red ball animation -->
<animateTransform id="anRed"
attributeName="transform"
type="translate"
begin="anBlue.begin+3s"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,0;
340,340;
340,340;
0,340;
0,340;
0,0;
0,0" />
</circle>
<!-- Blue ball -->
<circle cx="30" cy="30" r="3%" fill="url(#gradB)" >
<!-- Blue ball animation -->
<animateTransform id="anBlue"
attributeName="transform"
type="translate"
begin="svg1.click"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,0;
340,340;
340,340;
0,340;
0,340;
0,0;
0,0" />
</circle>
</svg>
[BONUS]
#4. Вариант с хаотичным отскоком шаров от бортов коробки
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" height="100vh" viewBox="0 0 400 400">
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
<radialGradient id="gradR" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="red" offset="25%"/>
<stop stop-color="rgb(192,0,0)" offset="50%"/>
<stop stop-color="rgb(127,0,0)" offset="70%"/>
<stop stop-color="rgb(64,0,0)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect width="100%" height="100%" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<circle cx="50%" cy="20%" r="3%" fill="url(#gradB)" >
<animate attributeName="cx" dur="3" values="3%;97%;3%"
repeatCount="indefinite" />
<animate attributeName="cy" dur="2.8" values="3%;97%;3%"
repeatCount="indefinite" />
</circle>
<circle cx="30%" cy="70%" r="3%" fill="url(#gradR)" >
<animate attributeName="cx" dur="2.7" values="97%;3%;97%"
repeatCount="indefinite" />
<animate attributeName="cy" dur="3.1" values="3%;97%;3%"
repeatCount="indefinite" />
</circle>
</svg>
Свободный перевод ответа от участника @Alexandr_TT.
CSS Only
.box {
position: relative; overflow: hidden; width: 180px; height: 180px;
border: 5px solid #9D8500; border-radius: 5px; background: green;
}
.blue, .red, .yellow {
position: absolute; width: 13px; height: 13px; border-radius: 15px;
}
.blue {background: blue; animation: bX 1.5s linear 0s infinite alternate, bY 2s linear 0s infinite alternate;}
.red {background: red; animation: rX 2s linear 0s infinite alternate, rY 2.5s linear 0s infinite alternate;}
.yellow {background: yellow; animation: yX 3s linear 0s infinite, yY 3s linear 0s infinite;}
@keyframes bX {from {left: 0;} to {left: 167px;}}
@keyframes bY {from {top: 0;} to {top: 167px;}}
@keyframes rX {from {right: 0;} to {right: 167px;}}
@keyframes rY {from {bottom: 0;} to {bottom: 167px;}}
@keyframes yX {from {left: 167px;} to {left: 0;}}
@keyframes yY {0% {top: 0; left: 0;} 25% {top: 0; left: 167px;} 50% {top: 167px; left: 167px;} 75% {top: 167px; left: 0;} 100% {top: 0; left: 0;}}
<div class="box"><div class="blue"></div><div class="red"></div><div class="yellow"></div></div>