Звёздные войны

Доставайте попкорн! В этой главе мы немного развлечёмся, создавая SVG-анимацию. Мы сделаем название фильма Star Wars из трейлера The Force Awakens.

Источник: https://www.youtube.com/watch?v=ngElkyQ6Rhs

В этом примере CSS-анимация сочетается с некоторыми другими свойствами CSS, которые могут оказаться для вас полезными, в частности с трансформациями scale(), translate() и rotate().

transform: не свойство анимации

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

Трансформация: scale(), translateZ() и rotateY()

С помощью scale() мы можем делать элементы больше или меньше. С помощью translateZ() мы можем перемещать элементы по оси Z — она представляет собой линию, проведённую от вас сквозь монитор.

В данном случае мы будем использовать комбинацию scale() и translateZ(), чтобы создать впечатление, будто некоторые слова летят сквозь пространство.

И, наконец, мы используем rotateY(), чтобы вращать буквы подзаголовка. Вращение вокруг оси Y потребует небольшой работы с 3D в браузере.

SVG, HTML и CSS

Для подготовки этого примера я создал два SVG-файла для надписей Star и Wars. Не стесняясь берите их, если хотите как-то использовать для экспериментов.

HTML для демонстрации выглядит следующим образом:

<div class="starwars-demo">
  <img src="//cssanimation.rocks/demo/starwars/images/star.svg" alt="Star" class="star">
  <img src="//cssanimation.rocks/demo/starwars/images/wars.svg" alt="Wars" class="wars">
  <h2 class="byline" id="byline">The Force Awakens</h2>
</div>

В качестве фона используется статичное изображение звёзд. Шрифт для заголовка найти было сложно, поэтому для этого примера я взял веб-шрифт Lato.

С помощью абсолютного позиционирования мы размещаем содержимое в центре экрана:

Анимация Star и Wars

Мы хотим, чтобы крупный текст постепенно появлялся в поле видимости, при этом сперва был большим и уменьшался со временем. Это хороший пример для функции трансформации scale(). Давайте применим её к слову Star с помощью таких ключевых кадров:

@keyframes star {
  0% {
    opacity: 0;
    transform: scale(1.5) translateY(-0.75em);
  }
  20% {
    opacity: 1;
  }
  89% {
    opacity: 1;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: translateZ(-1000em);
  }
}

В ходе анимации меняются два свойства — opacity и transform. Изменение opacity делает текст прозрачным в начале и постепенно появляющимся, а в конце он исчезает, чтобы мы могли зациклить анимацию.

Трансформация начинается с установки масштаба как 1.5. Это означает, что начальный размер текста на 150% больше обычного. На 89% мы устанавливаем свойство transform на масштаб 1. Это означает, что между 0% и 89% масштаб плавно изменяется от 150% до 100%.

Финальная функция translateZ() приводит к быстрому уменьшению размера слов.

Мы можем применить эти ключевые кадры к слову Star следующим образом:

.star {
  animation: star 10s ease-out infinite;
}

Аналогичный набор ключевых кадров используется для слова Wars.

Создание 3D

Использование 3D-преобразований в CSS, будь то перемещение по оси Z или вращение по осям Y и Z, требует, чтобы мы создали сцену для 3D. В терминах HTML это означает, что мы создаём контейнер и сообщаем браузеру, что в нём будут происходить 3D-действия.

Для этого мы добавим к классу .starwars-demo следующее:

.starwars-demo {
  perspective: 800px;
  transform-style: preserve3d;
}

Эти два свойства сообщают браузеру, что дочерние элементы контейнера должны быть расположены не в плоскости, а в трёхмерном пространстве. Более подробно об этих свойствах рассказывается в CSS Tricks.

Кроме того, свойство perspective сообщает браузеру, насколько «глубокой» должна быть сцена. В нашем случае мы сделали её глубиной 800px. Меньшие значения создают более «экстремальные» эффекты перспективы, так как сцена становится короче.

С этим разобрались, теперь представим подзаголовок.

The Force Awakens

В трейлере появляется подзаголовок The Force Awakens, в котором каждая буква вращается отдельно. Мы можем создать такой эффект с помощью трансформации rotateY(). В данном случае мы поместили каждую букву в элемент <span>, чтобы можно было применить анимацию к отдельным буквам.

Я быстро обнаружил, что нет прямого способа анимировать каждую букву в строке. Мой первый подход заключался в том, чтобы вручную вставить каждую букву в тег <span>. Это сработало, но сделало HTML немного запутанным. Текущая демонстрация включает в себя JavaScript (спасибо Tady за помощь), который автоматически оборачивает каждую букву в <span>.

Мы собираемся применить анимацию к каждой букве. Сначала ключевые кадры:

@keyframes spin-letters {
  0%, 10% {
    opacity: 0;
    transform: rotateY(90deg);
  }
  30% {
    opacity: 1;
  }
  70%, 86% {
    transform: rotateY(0);
    opacity: 1;
  }
  95%, 100% {
    opacity: 0;
  }
}

Сперва буквы повёрнуты на 90 градусов, а на 70% анимации они поворачиваются лицом к зрителю.

Мы можем применить этот набор ключевых кадров к каждому элементу <span> следующим образом:

.byline span {
  animation: spin-letters 10s linear infinite;
}

В результате каждый из контейнеров <span>, содержащих букву, будет медленно проявляться и вращаться на месте, а затем исчезнет в конце анимации.

Собрав всё вместе, мы получили готовое демо.

Источник: https://codepen.io/donovanh/pen/pJzwEw?editors=110

Домашнее задание

Если у вас есть время, я бы посоветовал посмотреть раздел CSS в версии CodePen.

Вы можете заметить несколько медиа-запросов в CSS. Мы используем их для изменения размера на небольших устройств. Попробуйте поменять некоторые ключевые кадры анимации или значения transform и посмотреть, что произойдёт.

Автор: Донован Хатчинсон
Последнее изменение: 17.02.2024