Створюємо Сонячну систему на чистому CSS3. Частина друга. Кейфрейми і тіні


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

У цій статті ми продовжимо розбиратися в принципах створення анімованої Сонячної системи на CSS3. Ми розглянемо використання keyframe-анімації для руху планет по орбітах навколо Сонця і реалізуємо динамічні тіні на планетах.

Ось на чому ми зупинилися у першій частині: ми створили HTML-файл з єдиним елементом і написали CSS- код для додавання зоряного фону і симуляції сонячного світла:

  

 

Додаємо Сонце

До того як ми додамо в наш Всесвіт будь-які елементи, ми повинні ввести відповідну систему координат.

Наш Всесвіт був прикріплений до елемента через абсолютне позиціонування, але ми хочемо, щоб усередині Всесвіту позиціонування було відносним. Для цього додамо новий

з відносним позиціонуванням:

 

Ось необхідний CSS-код:

#galaxy { position: relative; width: 100%; height: 100%;}

Усі позиції в елементі galaxy тепер розраховуватимуться відносно нього. Хоча всі поточні елементи і одного розміру, але якби ми додали хедери або футери поза елементом galaxy, верстання б збилося.

Давайте додамо елемент

для Сонця в центр галактики. Сонце має бути круглим, тому ми перетворимо прямокутний

на круглий. Це можна зробити, встановивши border-radius у 50 %, що перетворить будь-який квадрат на коло. Задамо розмір 30×30 пікселів, і використовуємо відступи для розміщення суворого по центру екрана. Ми також розфарбуємо Сонце і додамо приємну жовту тінь блоку для сяйва.

#sun { position: absolute; top: 50%; left: 50%; width: 30px; height: 30px; margin -top: - 15px; margin -left: - 15px; border-radius: 50%; background-color: #FB7209;
box-shadow: 0 0 60px rgba (255, 160, 60, 0.4); z-index: 1;}

Якесь маленьке сонце, давайте збільшимо довжину і ширину. Але працювати в пікселях – погана ідея, адже розміри екранів відрізняються. Замість цього задаватимемо розміри в em ‘ах: вони співвідносяться зі стандартним розміром тексту у браузері, і з масштабуванням проблем не виникне. Ще важливіше – всі абсолютні величини (розміри, відступи, межі і т. ін.) можна задавати в em ‘ах, і тому все їх можна масштабувати одночасно, використовуючи font-size. Якщо у нас є це:

#sun { width: 1em; height: 1em; margin-top: -.5em; margin-left: -.5em; ...}

і ми додамо це:

#sun { font-size: 24em;}

то всі розміри #sun, виражені в em ‘ах, множитимуться на 24. Крім того, збільшаться і відступи, тобто Сонце залишиться в центрі екрана!

Одноколірне сонце виглядає не дуже, тому ми додамо прозоре PNG-зображення з текстурою:

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

#sun { ... background-repeat: no - repeat; background-size: cover; background-image: url (data:image/png;base64,iVBORw0KG...AAASUVORK5CYII=);}

Ось результат:

Додаємо планету на орбіті, використовуючи кейфрейми

Зараз ми розглянемо ще одну фічу CSS3-keyframe-анімацію, чи кейфрейми. Вони використовуються для плавної зміни CSS-властивостей з часом. Наприклад, якщо Ви хочете, щоб елемент класу myelement поступово зникав, то Вам варто написати такий код:

.myelement { animation: 'fader' 2s linear;}@keyframes fader { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; }}

Спершу твердження @keyframes використовується для створення анімації з унікальним ім’ям fader. Усередині блоку keyframes ми створюємо три кейфрейми: повна непрозорість (на 0 %, на початку анімації), повна прозорість (на 50%, в середині анімації) і повна непрозорість наприкінці. Непрозорість – одна з властивостей, які можна анімувати; далі ми анімуватимемо місце розташування і обертання.

Для використання анімації достатньо додати до визначення класу правило animation. Ви задаєте ім’я анімації, її тривалість і тимчасову функцію. Ми використали linear, але можна використати ease, ease- in чи ease-out для прискорення анімації на різних етапах. Детальніше про це можна почитати тут.

Також нічого не заважає розділити всі властивості анімації. Оскільки планет буде багато, має сенс написати наступне:

.myelement { animation-name: orbit; animiation-duration: 2s; animation-timing-function: linear; animation-iteration-count: infinite;}

Ми використовуємо animation-iteration-count для створення нескінченного анімаційного циклу. Ключове слово infinite можна додати і до скороченого виду запису.

Пам’ятайте, що в загальному випадку треба додавати і варіанти з префіксами: -webkit-animation, -moz- animation і -o-animation , але оскільки ми використовуємо PrefixTree, то це нам не потрібно.

Оскільки всі планети нашої системи обертаються навколо Сонця однаково (міняється лише діаметр орбіти), ми можемо створити загальний клас для планети. Якісь властивості збігаються із Сонцем, тому спростимо:

#sun, .planet { position: absolute; top: 50%; left: 50%; width: 1em; height: 1em; margin -top: - 0.5em; margin -left: - 0.5em; border-radius: 50%;}#sun { background-color: #FB7209; background-repeat: no - repeat;
background-size: cover; box-shadow: 0 0 60px rgba (255, 160, 60, 0.4);}.planet { background-color: #202020; background-repeat: no - repeat; background-size: cover;}

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

 

Ця працює, але планета зараз розташована поверх Сонця, в центрі. До того як запустити її рух, нам треба задати орбіту, тому змінимо HTML так:

 

Тепер у нас є зв’язка орбіта-планета, однакова для всіх планет. Дамо нашій планеті ідентифікатор #mercury, щоб ми могли додати її унікальні властивості. Спершу намалюємо орбіту: дамо їй тонку, напівпрозору межу і зробимо її круглою. Для орбіти Меркурія задамо розмір 12em.

.orbit { position: absolute; top: 50%; left: 50%; border: 1px solid rgba (255, 255, 255, 0.2); border-radius: 50%;}#mercury.orbit { width: 12em; height: 12em; margin -top: - 6em; margin -left: - 6em;}

Орбіта намальована, але Меркурій все ще сидить поверх Сонця. Виправимо це, задавши планеті відступ відносно орбіти:

#mercury .planet { left: 0%; top: 50%;}

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

Настав час запустити обертання планети! Провернемо такий трюк: обертатимемо не планету, а орбіту. Оскільки планета знаходиться в системі координат орбіти, вона обертатиметься разом з орбітою. Створимо кейфрейми для орбіт з використанням перетворень. Це нова функція CSS3: Ви можете не лише анімувати значення властивостей, але й перетворювати елементи, відбиваючи, масштабуючи або обертаючи їх. Ми задамо обертання відносно осі Z від 0 до 360°.

@keyframes orbit { 0% { transform: rotateZ (0deg); } 100% { transform: rotateZ (- 360deg); }}

Задавши анімацію, ми можемо застосувати її до класу орбіт:

.orbit { ... animation-name: orbit; animation-iteration-count: infinite; animation-timing-function: linear;}

Визначимо тривалість анімації для Меркурія:

#mercury.orbit { animation-duration: 3s;}

От і все. Меркурій плавно обертається навколо Сонця, і ми все ще не скористалися JavaScript. Чистий CSS:

Додаємо тінь, що рухається, на планеті, використовуючи анімації та тіні блоку

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

Наша планета обертається навколо сонця завдяки анімації, застосованої до орбіти, тому ми можемо додати анімацію і до самої планети:

.planet { ... animation-iteration-count: infinite; animation-timing-function: linear;}#mercury .planet { animation-name: shadow - mercury;
animation-duration: 3s;}

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

@keyframes shadow - mercury { 0% { box-shadow: inset 0 0 20px rgba (0, 0, 0, 0.5); /* top */ } 25% { box-shadow: inset 16px 0 8px rgba (0, 0, 0, 0.5); /* left */ } 50% { box-shadow: inset 40px -20px 16px rgba (0, 0, 0, 0.5); /* bottom */ } 50.01% { box-shadow: inset - 40px -20px 16px rgba (0, 0, 0, 0.5); /* bottom */ } 75% { box-shadow: inset - 16px 0 8px rgba (0, 0, 0, 0.5); /* right */ } 100% { box-shadow: inset 0 0 20px rgba (0, 0, 0, 0.5); /* top */ }}

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

Тут ми навмисно зробили тінь помітнішою, ніж в оригінальній демо-версії:

Використовуючи наявний код, можна легко додати планети, яких бракує. Проте, нам треба повернути всю систему для отримання тривимірного виду. Тіні стануть набагато реалістичнішими.

Переклад статті “Making of the CSS 3 solar system animation”

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *