Перемещения с помощью CSS Motion Path

С выпуском Firefox 72 7 января 2020 года CSS Motion Path теперь присутствует в Firefox, новом Edge (с января 2020 года), Chrome и Opera (и других браузерах на основе Blink). Это означает, что каждый из этих браузеров поддерживает базовые способы применения offset-path: path(), offset-distance и offset-rotate.

Firefox также выпустил стабильную поддержку offset-anchor. Далее рассмотрим основы того, что поддерживается, обратим внимание на некоторые особенности применения path, а также выделим возможности offset-anchor.

See this code Shape Revealer 2020 on x.xhtml.ru.

Определение пути (path)

Технически при использовании каких-либо свойств, определенных в спецификации CSS Motion Path, движение не обеспечивается. Свойство offset-path позволяет установить невидимый путь, по которому может следовать элемент.

#my-element {
  offset-path: path('M0,0 C40,160 60,160 100,0');
}

Это может показаться похожим, если вы знакомы с SVG path или исследовали другие места для использования функции path(), например, параметры clip-path. Набор букв, цифр и запятых позволяет указать векторизованные линии, кривые и многое другое. В примере выше создается U-образная кривая, начинающаяся с точки 0px,0px и заканчивающаяся на 100 пикселей вправо в точке 100px, 0px. Чтобы узнать больше об этом синтаксисе, прочтите SVG Pocket Guide Joni Trythall’s или Illustrated SVG path Syntax Guide на сайте CSS-Tricks.

Некоторые основы:

  • M 0,0 означает: перейти к координатам x=0, y=0 без рисования
  • L 10,10 означает: провести линию от предыдущей точки до 10,10
  • Кривые Безье обрабатываются с помощью c и трех наборов координат.

В спецификации CSS Motion Path есть много других способов установить путь смещения, например, используя другие функции CSS Shape circle(), box элемента или новой функцию ray(), которая вводит полярные координаты в CSS. Однако в настоящее время во всех уже упомянутых браузерах поддерживается только path(). Значительный прогресс достигнут в использовании ray(), осталось дождаться поддержки браузерами.

Определение расстояния

Расстояние смещения может быть любым обозначением единиц длины, однако проценты будут наиболее наглядной единицей, поскольку 100% всегда – конец пути. Половина пути будет обозначаться также просто – 50%.

See this code Offset-distance on x.xhtml.ru.

Анимация по пути

Как было сказано ранее, спецификация CSS Motion Path “из коробки” на самом деле не обеспечивает движения. Можно взять определения свойств пути, затем использовать существующие проверенные методы анимации для изменения значения offset-distance. Итак, чтобы анимировать элемент на всём его пути от 0% (значение по умолчанию для offset-distance) до 100%, можно настроить CSS-анимацию (или использовать API веб-анимации, requestAnimationFrame и т.д.) для изменения этих значений.

#my-element {
  offset-path: path('M0,0 C40,160 60,160 100,0');
  animation: go 4000ms infinite ease-in-out;
}
@keyframes go {
  100% {
    offset-distance: 100%;
  }
}

See this code Offset-distance in motion on x.xhtml.ru.

Анимация самого пути

Также можно изменять сам путь, и если он имеет такое же количество точек, браузер может интерполировать значения и плавно перемещать путь. Если начать с простого прямого пути, определенного как path('M0,0 L100,100') (который представляет сегмент линии от 0px,0px до 100px,100px), можно его анимировать в новый отрезок, как-будто у него только две точки, например path('M100,0 L0,100'). Если попытаться перейти по path('M100,0 L0,100 L100,100'), браузер не сможет определить промежуточные значения, поскольку у путей пути разное количество точек, поэтому путь будет только переключаться туда-сюда вместо плавного перехода.

See this code Animating offset-path on x.xhtml.ru.

Определение того, где находится элемент

По умолчанию элемент обращается «лицом» по направлению пути, т.е. его правая сторона всегда будет перпендикулярна линии пути. Это происходит благодаря значению auto третьего свойства смещения offset-rotate. Если нужно, чтобы элемент смотрел в сторону от направления пути, можно использовать значение reverse.

Свойство offset-rotate может принимать значения угла, если необходимо, чтобы элемент оставался в фиксированном положении и под определенным углом а не по направлению пути. Со значением 0deg элемент останется в своей исходной ориентации без паттернов, при этом правая сторона всегда будет смотреть вправо, независимо от направления пути.

Последний вариант – объединить ключевые слова auto или reverse со второй опцией – значением угла. Если установить, например, offset-rotate: auto 90deg элемент будет вращаться с учетом направления пути, но с добавленным смещением в 90 градусов. Итак, после поворота элемента на четверть оборота, его верхняя сторона обращается по направлению пути и остается перпендикулярной ему.

See this code offset-rotate vs. transform/rotate on x.xhtml.ru.

Аналогично анимации offset-path и offset-distance, с использованием углов (даже в сочетании с auto/reverse) можно анимировать свойство offset-rotate.

Определение точки привязки на пути

Элементы центрируются относительно линии пути, но это можно легко изменить, установив свойство offset-anchor. Указание значений аналогично тому, что используется для background-position или в двумерном transform-origin, где указывается положение по горизонтали (ось x) и по вертикали (ось y). Таким образом, значение по умолчанию – offset-anchor: 50% 50% можно указать и как center center. А также можно выбрать top left (или 0% 0%), а также любое другое значение длины/процента, чтобы изменить точку на элементе, которой он привязан к пути. Можно использовать даже значения координат за пределами элемента с отрицательными числами или более 100%.

See this code Offset Path Anchor on x.xhtml.ru.

Если значениями являются единицы длины или проценты, свойство привязки можно анимировать. Следовательно, каждое из четырех свойств offset может быть анимировано, даже если единственное, что перемещается по траектории в традиционном смысле – offset-distance.

See this code animating offset distance, rotate, and anchor on x.xhtml.ru.

Почему происходит смещение элемента, если применяется только путь?

Можно подумать, что на самом деле ничего не происходит, если указывать только путь, так как расстояние, поворот и привязка влияют на то, как элемент отображается в пути.

У самого пути координаты 0,0, помещенные в исходное положение элемента в потоке документа. При указании только offset-path элемент помещается в начало невидимого пути (offset-distance: 0%). Однако весьма вероятно, что элемент будет визуально выглядеть иначе, поскольку это центральная точка элемента, которая находится в начале пути (offset-anchor: 50% 50%), а его исходная правая сторона будет обращена по направлению пути (offset-rotate: auto).

See this code Offset-path: none v path on x.xhtml.ru.

Если начало пути находится в верхнем левом углу, то как минимум элемент будет смещен вверх и влево так, чтобы точка привязки (по умолчанию center center) находилась в верхнем левом углу исходного положения элемента. Если нужно, чтобы элемент в исходном положении оставался в начале, придется переделать настройки пути, чтобы он начинался с начальной точки привязки, или поработать с позиционированием или отдельными свойствами преобразования.

Заключение

Это некоторые ключевые основы, но, безусловно, есть много возможностей для изучения. Пути движения часто связаны с непрерывными кривыми, но ничто не говорит о том, что нельзя использовать прямые линии или несвязанные отрезки. Траектории движения обычно связаны с движением, но offset можно использовать для простого статического позиционирования элементов. Посмотрите, какие из обсуждаемых выше свойств поддерживаются в вашем браузере:

offset-path
offset-distance
offset-position
offset-rotate
offset-anchor