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


У цій статті ми продовжимо розбиратися в принципах створення анімованої Сонячної системи на 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”

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

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