Создаём Солнечную систему на чистом CSS3. Часть вторая. Кейфреймы и тени
11К открытий11К показов
В этой статье мы продолжим разбираться в принципах создания анимированной Солнечной системы на CSS3. Мы рассмотрим использование keyframe-анимации для движения планет по орбитам вокруг Солнца и реализуем динамические тени на планетах.
Вот на чем мы остановились в первой части: мы создали HTML-файл с единственным элементом и написали CSS-код для добавления звёздного фона и симуляции солнечного света:
Добавляем Солнце
Прежде чем мы добавим в нашу вселенную какие-либо элементы, мы должны ввести подходящую систему координат. <div>
нашей вселенной был прикреплён к элементу <body>
через абсолютное позиционирование, но мы хотим, чтобы внутри вселенной позиционирование было относительным. Для этого добавим новый <div>
с относительным позиционированием:
Вот необходимый CSS-код:
Все позиции в элементе galaxy теперь будут рассчитываться относительно него. Хотя все текущие элементы и одного размера, но если бы мы добавили хэдеры или футеры вне элемента galaxy, вёрстка бы сбилась.
Давайте добавим элемент <div>
для Солнца в центр галактики. Солнце должно быть круглым, поэтому мы превратим прямоугольный <div>
в круглый. Это можно сделать, установив border-radius
в 50%, что превратит любой квадрат в круг. Зададим размер 30×30 пикселей, и используем отступы для размещения строго по центру экрана. Мы также раскрасим Солнце и добавим приятную жёлтую тень блока для сияния.
Какое-то маленькое солнце, давайте увеличим длину и ширину. Но работать в пикселях — плохая идея, ведь размеры экранов отличаются. Вместо этого будем задавать размеры в em’ах: они соотносятся со стандартным размером текста в браузере, и с масштабированием проблем не возникнет. Что ещё более важно, все абсолютные величины (размеры, отступы, границы и т.п.) можно задавать в em’ах, и поэтому все их можно масштабировать одновременно, используя font-size
. Если у нас есть это:
… и мы добавим это:
… то все размеры #sun, выраженные в em’ах, умножатся на 24. Кроме того, увеличатся и отступы, то есть Солнце останется в центре экрана!
Одноцветное солнце выглядит не очень, поэтому мы добавим прозрачное PNG-изображение с текстурой:
Для помещения изображения поверх солнца снова воспользуемся правилом background-size
:
Вот результат:
Добавляем планету на орбите, используя кейфреймы
Сейчас мы рассмотрим ещё одну фичу 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.
Орбита нарисована, но Меркурий всё ещё сидит поверх Солнца. Исправим это, задав планете отступ относительно орбиты:
Это поместит Меркурий слева от Солнца, на линию орбиты.
Настало время запустить вращение планеты! Провернём такой трюк: будем вращать не планету, а орбиту. Поскольку планета находится в системе координат орбиты, она будет вращаться вместе с орбитой. Создадим кейфреймы для орбит с использованием преобразований. Это новая функция CSS3: вы можете не только анимировать значения свойств, но и преобразовывать элементы, отражая, масштабируя или вращая их. В нашем случае мы зададим вращение относительно оси Z от 0 до 360 градусов.
Задав анимацию, мы можем применить её к классу орбит:
Определим длительность анимации для Меркурия:
Вот и всё. Меркурий плавно вращается вокруг Солнца, и мы всё ещё не воспользовались JavaScript. Чистый CSS:
Добавляем движущуюся тень на планете, используя анимации и тени блока
Наша Солнечная система будет куда реалистичней, если мы затемним ту часть планеты, которая в текущий момент времени не освещается Солнцем. Это можно реализовать с использованием кейфреймов.
Наша планета вращается вокруг солнца благодаря анимации, применённой к орбите, поэтому мы можем добавим анимацию и к самой планете:
Мы указали, что анимация планет будет зациклена, а у Меркурия она будет называться shadow-mercury. Определим её:
Внутренние тени используются для отбрасывания теней на планету. Поскольку планеты круглые, тени должны быть такими же. В начале анимации планета находится за Солнцем и полностью освещена. На 50% она полностью в тени. Когда планета проходит перед Солнцем, мы должны переключить анимацию, что мы и делаем на 50.01%. Также заметьте, что на 100% тень должна быть в точности такой же, как и на 0%, для корректного вычисления затенения.
Здесь мы намеренно сделали тень более заметной, чем в оригинальной демке:
Используя имеющийся код, можно легко добавить все недостающие планеты. Однако, нам нужно повернуть всю систему для получения трёхмерного вида. Тени станут гораздо более реалистичными.
11К открытий11К показов