Размещение текста по заданной траектории с помощью CSS

3981
Размещение текста по заданной траектории с помощью CSS
Размещение текста по заданной траектории с помощью CSS

На протяжении пары последних месяцев я много экспериментировала с CSS Motion Path и получила массу удовольствия от создания демок, некоторые из которых вы можете найти в этой коллекции Codepen. Но название «Motion Path» немного вводит в заблуждение, поскольку оно относится не только к движению. Несмотря на то, что спецификация по-прежнему называется «Motion Path», свойство, используемое для определения траектории, было изменено с motion-path на offset-path. Легко понять, почему: элемент может быть размещен в любом месте пути, с движением или без движения — его положение (или offset-distance) не нужно анимировать.

В следующей демке (версия @beesandbombs GIF) кажется, что масштаб и непрозрачность кругов анимированы, но на самом деле их положение неподвижно, несмотря на иллюзию движения. Тем не менее, каждый из них расположен по круговой траектории при помощи offset-path и offset-distance.

See the Pen
Offset-path animated circles with Houdini and Splitting JS
by Odinokun (@Odinokun)
on CodePen.

Есть также conic-gradient маска, анимированная с помощью CSS Houdini — но, полноценно, она работает только в Chrome.

Возможность располагать элементы вдоль заданной траектории хорошо подходит для текста. В прошлом году я создала несколько демок, в которых использовала пользовательские свойства CSS для размещения текста по кругу, применяя трансформации. В этом примере используется Splitting.js (моя любимая библиотека JS!) Для задавания пользовательских свойств (подробнее об этом позже.)

See the Pen
Text in a circle with CSS variables + Splitting.js and fluid type
by Odinokun (@Odinokun)
on CodePen.

Этот пример отлично работает с динамическим контентом — вы можете изменить текст, и положение каждого символа будет пересчитано, чтобы текст идеально подходил к окружности. Но есть и обратная сторона: текст нельзя выделить, потому что используется абсолютное позиционирование и трансформация.

Содержание

Motion Path — спасение

Если вместо этого мы используем offset-path, вычисляем значения offset-distance для каждого символа с используя пользовательские свойства, мы можем добиться того же эффекта с полностью выбираемым текстом! Класс!

See the Pen
Text in a circle with offset-path
by Odinokun (@Odinokun)
on CodePen.

К сожалению, на момент написания статьи, единственное поддерживаемое значение offset-path — это path() функция. Она не поможет нам с адаптацией, поскольку path не масштабируется. Но можно, например, использовать медиазапросы для задавания разных значений path при определенных разрешениях окна браузера. В качестве альтернативы мы могли бы использовать трансформации, чтобы уменьшить масштаб всего изображения на небольших экранах. Но ни один из этих вариантов не идеален. Если бы мы могли использовать URL пути SVG (как указано в спецификации), то это дало бы нам более точный контроль.

Немного про определение траектории

Мой любимый способ определения offset-path значения — нарисовать путь в Illustrator и сохранить его как SVG, прежде чем очистить его с помощью инструмента оптимизации и скопировать значение атрибута d у полученного пути . Если вы просто нарисуете круг, Illustrator сохранит его как circle элемент, а не как path. Один из способов избежать этого — сначала нарисовать круг, а затем с помощью инструмента-ножницы в Illustrator обрезать траекторию круга в нужном месте. После этого он будет сохранен как элемент path а не как circle.

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

Да, мы можем анимировать текст тоже

Анимация — вот где эти методы действительно выглядят блестяще. Мы можем анимировать, offset-distance чтобы переместить строку текста вдоль заданной траектории. Один из моих любимых приемов — использовать значения animation-delay, рассчитанные на основе пользовательских свойств. Splitting.js присваивает каждому символу собственное свойство, которое соответствует его индексу. Передача значений в calc() функцию сделает движение более органичным и. Вы можете увидеть разницу в двух анимациях ниже. Вторая анимация реализует animation-delay для каждого символа, рассчитывая их с использованием пользовательских свойств:

.char {
  --delay: calc(var(--char-index) * 30ms);
}

See the Pen
Comparing offset-path animation with/without delay
by Odinokun (@Odinokun)
on CodePen.

Это очень увлекательно. Следующая демка использует методы, описанные выше, чтобы создать эффект американских горок:

See the Pen
Typo-coaster
by Odinokun (@Odinokun)
on CodePen.

Мы можем сделать анимацию еще более причудливой и добавить в нее некоторые 3D-трансформации:

See the Pen
Splitting and motion path
by Odinokun (@Odinokun)
on CodePen.

источник