Откройте для себя магию анимации траектории движения Motion Path

внешний интерфейс CSS
Откройте для себя магию анимации траектории движения Motion Path

В 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команда, и получается прямая линия, как показано на следующем рисунке:

image

Окончательный эффект заключается в следующем, с использованием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 г.

Can i Use - Motion-Path:

В настоящее время, за исключением браузера IE, пришло время подождать, пока Safari станет совместимым, и использование его зависит от использования браузера целевой группой.

наконец

Что ж, это конец этой статьи, представляющий анимацию траектории движения Motion Path и использующий ее для достижения некоторых эффектов анимации траектории, которые не могли быть легко достигнуты в прошлом, я надеюсь, что это поможет вам :)

Если вы хотите получить самую интересную информацию о CSS, не пропустите мой официальный аккаунт --Интересные факты о внешнем интерфейсе iCSS😄

Другие замечательные технические статьи по CSS собраны в моемGithub -- iCSS, продолжайте обновлять, добро пожаловать, нажмите звездочку, чтобы подписаться на коллекцию.

Если у вас есть какие-либо вопросы или предложения, вы можете общаться больше.Оригинальные статьи ограничены в написании и знаниях.Если в статье есть какие-либо неточности, пожалуйста, дайте мне знать.