В CSS есть очень интересный модуль --CSS Motion Path Module Level 1, что соответствует траектории движения. В этой статье мы подробно рассмотрим траекторию движения. Из этой статьи вы узнаете:
- Что такое траектория движения CSS
- Простая анимация пути с помощью пути движения CSS
- Анимация сложных путей с помощью пути движения CSS
Что такое путь движения CSS?
Что такое путь движения CSS? Используя свойства, указанные в этой спецификации, мы можем управлять анимацией преобразования положения элемента по определенному пути. Кроме того, этот путь может быть очень сложным.
Прежде чем углубиться в CSS Motion Path, давайте взглянем на возможности традиционного CSS и на то, как мы можем добиться анимации пути.
Традиционный способ CSS для достижения анимации линейного пути
Раньше мы хотели переместить объект из точки А в точку Б по прямой линии, обычно используяtransform: translate()
,top | left | bottom | right
илиmargin
Атрибуты, которые могут изменить положение объекта.
Простая демонстрация:
<div>
div {
width: 60px;
height: 60px;
background: #000;
animation: move infinite 1s alternate linear;
}
@keyframes move {
100% {
transform: translate(100px, 100px);
}
}
Эффект простого линейного движения из точки А в точку В выглядит следующим образом:
Традиционный способ CSS для достижения анимации кривого пути
Конечно, CSS также может реализовать несколько простых анимаций кривых траекторий. Что, если мы хотим двигаться из точки А в точку Б не по прямой линии, а по кривой?
Для некоторых простых дуговых путей вы все равно можете использовать некоторые умные методы, взгляните на следующий пример.
На этот раз мы использовали два элемента, дочерний элемент — это шар, который мы хотим переместить по кривой, но фактически мы устанавливаем родительский элемент, устанавливаяtransform-origin
, пусть родительский элемент выполняетtransform: rotate()
Движение приводит в движение мяч дочернего элемента:
<div class="g-container">
<div class="g-ball"></div>
</div>
.g-container {
position: relative;
width: 10vmin;
height: 70vmin;
transform-origin: center 0;
animation: rotate 1.5s infinite alternate;
}
.g-ball {
position: absolute;
width: 10vmin;
height: 10vmin;
border-radius: 50%;
background: radial-gradient(circle, #fff, #000);
bottom: 0;
left: 0;
}
@keyframes rotate {
100% {
transform: rotate(90deg);
}
}
Для облегчения понимания, во время движения я позволил появиться контуру родительского элемента:
Таким образом, мы едва можем получить нелинейную анимацию движения по траектории, а ее реальная траектория движения представляет собой кривую.
Однако это в основном предел того, что CSS мог сделать раньше.Используя чистый CSS, невозможно добиться более сложных анимаций пути, таких как следующая анимация пути:
До сих пор у нас была более мощная спецификация для этого, которая является главным героем этой статьи —CSS Motion Path.
CSS Motion Path реализует анимацию линейного пути.
Спецификация CSS Motion Path в основном включает следующие свойства:
-
offset-path
: получение пути SVG (аналогично пути SVG, clip-path в CSS), определяющего геометрический путь движения. -
offset-distance
: Управляет текущим элементом на основеoffset-path
расстояние движения -
offset-position
: уточнитьoffset-path
исходное положение -
offset-anchor
: определить вдольoffset-path
Точка привязки позиционируемого элемента. Это также легко понять.Движущийся элемент может не быть точкой, поэтому вам нужно указать, какая точка в элементе привязана к пути для перемещения. -
offset-rotate
: определить вдольoffset-path
Направление элемента при позиционировании, говоря - угол наклона элемента в процессе движения
Ниже мы используем Motion Path для реализации простой линейной анимации смещения.
<div>
div {
width: 60px;
height: 60px;
background: linear-gradient(#fc0, #f0c);
offset-path: path("M 0 0 L 100 100");
offset-rotate: 0deg;
animation: move 2000ms infinite alternate ease-in-out;
}
@keyframes move {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
offset-path
Получите путь пути SVG, где содержимое нашего пути является настраиваемым путем.path("M 0 0 L 100 100")
, в переводе с0 0
перейти к100px 100px
точка.
offset-path
Принимает путь SVG, определяющий геометрический путь движения. Подобно пути SVG и clip-path в CSS, если вы мало что знаете об этом пути SVG, вы можете щелкнуть здесь, чтобы узнать о содержимом пути SVG:SVG-путь
Получаем следующий результат:
через элемент управленияoffset-distance
от0%
изменить на100%
Анимируйте путь элемента.
Конечно, приведенная выше анимация является самой простой, я могу в полной мере использовать характеристики пути, добавить несколько промежуточных ключевых кадров и немного изменить приведенный выше код:
div {
// 只改变运动路径,其他保持一致
offset-path: path("M 0 0 L 100 0 L 200 0 L 300 100 L 400 0 L 500 100 L 600 0 L 700 100 L 800 0");
animation: move 2000ms infinite alternate linear;
}
@keyframes move {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
Здесь главное использовать путь вL
команда, и получается прямая линия, как показано на следующем рисунке:
Окончательный эффект заключается в следующем, с использованиемtransform: translate()
Добавление нескольких ключевых кадров аналогично:
Вы можете нажать здесь для полной демонстрации:CodePen Demo -- CSS Motion Path Demo
CSS Motion Path реализует анимацию кривого пути.
Вышеуказанные траектории движения состоят из прямых линий. Давайте посмотрим, как использовать CSS Motion Path для создания криволинейной анимации пути.
На самом деле принцип тот же, только нужноoffset-path: path()
Вы можете добавить к нему путь, связанный с кривой.
В пути SVG мы берем один из методов рисования кривых - кривые Безье, например следующий путь, где путьd="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80"
:
<svg width="400" height="160" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80" stroke="black" fill="transparent"/>
</svg>
Соответствует такой непрерывной кривой Безье:
Примените соответствующий путь кoffset-path: path
середина:
<div>
div:nth-child(2) {
width: 40px;
height: 40px;
background: linear-gradient(#fc0, #f0c);
offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
}
@keyframes move {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
Можно получить следующие эффекты движения:
Видно, что элемент движется по пути кривой Безье, и, поскольку на этот раз нет пределаoffset-rotate
, ориентация элемента также меняется с ориентацией пути. (Можно представить, что при движении передняя часть автомобиля всегда будет следовать за дорогой и будет меняться, изменяя угол наклона всего кузова)
Вы можете нажать здесь для полной демонстрации:CodePen Demo -- CSS Motion Path Demo
Общие сведения об якорях движения со смещением
Хорошо, тогда дальше, давайте посмотримoffset-anchor
Как понять.
В приведенном выше DEMO мы заменяем маленький квадрат треугольником и рисуем кривую движения на странице, например так:
где треугольникclip-path
Реализовано:
width: 40px;
height: 40px;
clip-path: polygon(0 0, 100% 50%, 0 100%);
background: linear-gradient(#fc0, #f0c);
Вообще говоря, по кривой движется центральная точка объекта (аналог.transform-origin
), здесь мы можем пройтиoffset-anchor
Изменяем точку привязки движения, например, мы хотим, чтобы нижняя часть треугольника двигалась по кривой:
.ball {
width: 40px;
height: 40px;
clip-path: polygon(0 0, 100% 50%, 0 100%);
offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
offset-anchor: 0 100%;
background: linear-gradient(#fc0, #f0c);
animation: move 3000ms infinite alternate linear;
}
@keyframes move {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
После тестирования Могу ли я использовать говорит
offset-anchor
Совместимость атрибута — Chrome 79+, Firefox 72+, но на самом деле его поддерживает только Firefox, и на данный момент он не может действовать в Chrome~
Вы можете нажать здесь для полной демонстрации:CodePen Demo -- CSS Motion Path offset-anthor Demo
Анимация с траекторией движения
Хорошо, мы в основном дали принцип выше, давайте посмотрим, как использовать Motion Path на практике.
Создавайте эффекты кнопок с помощью Motion Path
Используя траектории движения, мы можем создать несколько простых эффектов нажатия кнопки. Раньше я видел такой эффект нажатия кнопки на CodePen:
Принцип заключается в использованииbackground-radial
генерировать каждую маленькую точку, контролируяbackground-position
Чтобы управлять смещением маленьких точек, вы можете щелкнуть здесь для получения подробного демонстрационного кода:
CodePen Demo -- Bubbly button (Design by Gal Shir)
Однако пути движения маленьких точек в основном прямые линии.Используя путь движения в этой статье, мы также можем добиться некоторых подобных эффектов.Основной код выглядит следующим образом, и здесь мы используем HTML.Pug
Шаблон, CSS используетSASS
:
.btn
-for(var i=0; i<60; i++)
span.dot
.btn {
position: relative;
padding: 1.5rem 4.5rem;
}
.btn .dot {
position: absolute;
width: 4px;
height: 4px;
@for $i from 1 through $count {
&:nth-child(#{$i}) {
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0) rotate(#{360 / $count * $i}deg);
}
}
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 4px;
height: 4px;
border-radius: 50%;
offset-path: path("M0 1c7.1 0 10.7 2 14.3 4s7.1 4 14.3 4 10.7-2 14.3-4 7.2-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4 10.7-2 14.3-4 7.1-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4 10.7-2 14.3-4 7.1-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4");
offset-distance: 0;
}
}
.btn.is-animating:active .dot:nth-child(4n+1)::before {
animation: dot var(--animation-time) var(--animation-timging-function);
}
.btn.is-animating:active .dot:nth-child(4n+2)::before {
border: 1px solid var(--color-primary);
background: transparent;
animation: dot var(--animation-time) var(--animation-timging-function) 0.1s;
}
.btn.is-animating:active .dot:nth-child(4n+3)::before {
animation: dot var(--animation-time) var(--animation-timging-function) 0.2s;
}
.btn.is-animating:active .dot:nth-child(4n)::before {
border: 1px solid var(--color-primary);
background: transparent;
animation: dot var(--animation-time) var(--animation-timging-function) 0.3s;
}
@keyframes dot {
0% {
offset-distance: 0%;
opacity: 1;
}
90% {
offset-distance: 60%;
opacity: .5;
}
100% {
offset-distance: 100%;
opacity: 0;
}
}
Не смотри код чуть сложнее, но понять не сложно, суть в том, чтобы поставить одну и ту же маленькую точку для каждого подэлемента offset-path: path()
, установите разные углы поворота для подэлементов в разных группах и используйте задержку анимацииanimation-delay
Установите 4 набора анимаций, которые запускаются одновременно.
Здесь наш путь траектории не является прямой линией, эффект следующий:
Вы можете нажать здесь для получения полного кода:
CodePen Demo -- Button Animation with CSS Offset Paths
Используйте Motion-Path, чтобы нарисовать анимацию поиска пути на карте.
Это также очень практично, и теперь мы можем полностью использовать CSS Motion-Path для достижения анимации поиска пути на карте:
Демо исходит от Ахмада Эмрана, вы можете щелкнуть здесь, чтобы увидеть полный код:
CodePen Demo -- CodePen Home Animation with offset-path | Only Using CSS & HTML
Анимация путей с помощью Motion-Path
Или мы можем использовать способность Path рисовать любой путь, чтобы реализовать различные пути, которые мы хотим, такие как парабола, добавленная в корзину, или различные траектории движения.Вот еще одна демонстрация:
CodePen Demo -- CSS Motion Path offset-path animation
Can i Use - Motion-Path
Давайте посмотрим, насколько в настоящее время совместим Motion-Path? По состоянию на 27 апреля 2021 г.
В настоящее время, за исключением браузера IE, пришло время подождать, пока Safari станет совместимым, и использование его зависит от использования браузера целевой группой.
наконец
Что ж, это конец этой статьи, представляющий анимацию траектории движения Motion Path и использующий ее для достижения некоторых эффектов анимации траектории, которые не могли быть легко достигнуты в прошлом, я надеюсь, что это поможет вам :)
Если вы хотите получить самую интересную информацию о CSS, не пропустите мой официальный аккаунт --Интересные факты о внешнем интерфейсе iCSS😄
Другие замечательные технические статьи по CSS собраны в моемGithub -- iCSS, продолжайте обновлять, добро пожаловать, нажмите звездочку, чтобы подписаться на коллекцию.
Если у вас есть какие-либо вопросы или предложения, вы можете общаться больше.Оригинальные статьи ограничены в написании и знаниях.Если в статье есть какие-либо неточности, пожалуйста, дайте мне знать.