Создаём Солнечную систему на чистом CSS3. Часть вторая. Кейфреймы и тени

solarmini3

В этой статье мы продолжим разбираться в принципах создания анимированной Солнечной системы на CSS3. Мы рассмотрим использование keyframe-анимации для движения планет по орбитам вокруг Солнца и реализуем динамические тени на планетах. 

Вот на чем мы остановились в первой части: мы создали HTML-файл с единственным элементом и написали CSS-код для добавления звёздного фона и симуляции солнечного света:

See the Pen CSS 3 Solar System, Step 2 by Independent Software (@independent-software) on CodePen.

Добавляем Солнце

Прежде чем мы добавим в нашу вселенную какие-либо элементы, мы должны ввести подходящую систему координат. <div> нашей вселенной был прикреплён к элементу <body> через абсолютное позиционирование, но мы хотим, чтобы внутри вселенной позиционирование было относительным. Для этого добавим новый <div> с относительным позиционированием:

Вот необходимый CSS-код:

Все позиции в элементе galaxy теперь будут рассчитываться относительно него. Хотя все текущие элементы и одного размера, но если бы мы добавили хэдеры или футеры вне элемента galaxy, вёрстка бы сбилась.

Давайте добавим элемент <div> для Солнца в центр галактики. Солнце должно быть круглым, поэтому мы превратим прямоугольный <div> в круглый. Это можно сделать, установив border-radius в 50%, что превратит любой квадрат в круг. Зададим размер 30×30 пикселей, и используем отступы для размещения строго по центру экрана. Мы также раскрасим Солнце и добавим приятную жёлтую тень блока для сияния.

Какое-то маленькое солнце, давайте увеличим длину и ширину. Но работать в пикселях — плохая идея, ведь размеры экранов отличаются. Вместо этого будем задавать размеры в em’ах: они соотносятся со стандартным размером текста в браузере, и с масштабированием проблем не возникнет. Что ещё более важно, все абсолютные величины (размеры, отступы, границы и т.п.) можно задавать в em’ах, и поэтому все их можно масштабировать одновременно, используя font-size. Если у нас есть это:

… и мы добавим это:

… то все размеры #sun, выраженные в em’ах, умножатся на 24. Кроме того, увеличатся и отступы, то есть Солнце останется в центре экрана!

Одноцветное солнце выглядит не очень, поэтому мы добавим прозрачное PNG-изображение с текстурой:

sun

Для помещения изображения поверх солнца снова воспользуемся правилом background-size:

Вот результат:

See the Pen CSS 3 Solar System, Step 3 by Independent Software (@independent-software) on CodePen.

Добавляем планету на орбите, используя кейфреймы

Сейчас мы рассмотрим ещё одну фичу CSS3 — keyframe-анимацию, или кейфреймы. Они используются для плавного изменения CSS-свойств с течением времени. Например, если вы хотите, чтобы элемент класса myelement постепенно исчезал, вам стоит написать такой код:

Сперва утверждение @keyframes используется для создания анимации с уникальным именем fader. Внутри блока keyframes мы создаём три кейфрейма: полная непрозрачность (на 0%, в начале анимации), полная прозрачность (на 50%, в середине анимации) и полная непрозрачность в конце. Непрозрачность — лишь одно из свойств, которые можно анимировать; в дальнейшем мы будем анимировать местоположение и вращение.

Для использования анимации достаточно добавить к определению класса правило animation. Вы задаёте имя анимации, её длительность и временную функцию. мы использовали linear, но можно использовать ease, ease-in или ease-out для ускорения анимации на различных этапах. Подробнее об этом можно почитать здесь.

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

Мы используем animation-iteration-count для создания бесконечного анимационного цикла. Ключевое слово infinite можно добавить и к сокращённому виду записи.

Помните, что в общем случае нужно добавлять и варианты с префиксами: -webkit-animation, -moz-animation и -o-animation — но поскольку мы используем PrefixTree, это нам не нужно.

Поскольку все планеты нашей системы вращаются вокруг Солнца одинаково (меняется лишь диаметр орбиты), мы можем создать общий класс для планеты. Какие-то свойства совпадают и с Солнцем, поэтому упростим:

Добавим планету в наш HTML:

Эта работает, но планета сейчас расположена поверх Солнца, в центре. Прежде чем запустить её движение, нам нужно задать орбиту, поэтому изменим HTML так:

Теперь у нас есть связка орбита-планета, одинаковая для всех планет. Дадим нашей планете идентификатор #mercury, чтобы мы могли добавить её уникальные свойства. Сперва нарисуем орбиту: дадим ей тонкую, полупрозрачную границу и сделаем её круглой. Для орбиты Меркурия зададим размер 12em.

Орбита нарисована, но Меркурий всё ещё сидит поверх Солнца. Исправим это, задав планете отступ относительно орбиты:

Это поместит Меркурий слева от Солнца, на линию орбиты.

See the Pen CSS 3 Solar System, Step 4 by Independent Software (@independent-software) on CodePen.

Настало время запустить вращение планеты! Провернём такой трюк: будем вращать не планету, а орбиту. Поскольку планета находится в системе координат орбиты, она будет вращаться вместе с орбитой. Создадим кейфреймы для орбит с использованием преобразований. Это новая функция CSS3: вы можете не только анимировать значения свойств, но и преобразовывать элементы, отражая, масштабируя или вращая их. В нашем случае мы зададим вращение относительно оси Z от 0 до 360 градусов.

Задав анимацию, мы можем применить её к классу орбит:

Определим длительность анимации для Меркурия:

Вот и всё. Меркурий плавно вращается вокруг Солнца, и мы всё ещё не воспользовались JavaScript. Чистый CSS:

See the Pen CSS 3 Solar System, Step 5 by Independent Software (@independent-software) on CodePen.

Добавляем движущуюся тень на планете, используя анимации и тени блока

Наша Солнечная система будет куда реалистичней, если мы затемним ту часть планеты, которая в текущий момент времени не освещается Солнцем. Это можно реализовать с использованием кейфреймов.

Наша планета вращается вокруг солнца благодаря анимации, применённой к орбите, поэтому мы можем добавим анимацию и к самой планете:

Мы указали, что анимация планет будет зациклена, а у Меркурия она будет называться shadow-mercury. Определим её:

Внутренние тени используются для отбрасывания теней на планету. Поскольку планеты круглые, тени должны быть такими же. В начале анимации планета находится за Солнцем и полностью освещена. На 50% она полностью в тени. Когда планета проходит перед Солнцем, мы должны переключить анимацию, что мы и делаем на 50.01%. Также заметьте, что на 100% тень должна быть в точности такой же, как и на 0%, для корректного вычисления затенения.

Здесь мы намеренно сделали тень более заметной, чем в оригинальной демке:

See the Pen CSS 3 Solar System, Step 6 by Independent Software (@independent-software) on CodePen.

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

Перевод статьи «Making of the CSS 3 solar system animation»Иван Бирюков, страж правописания