CSS переходи, трансформації і анімації — Перспектива

2

Від автора: В цій статті з серії статей, присвячених CSS переходах, трансформацій і анимациям, ми розглянемо на прикладах (включаючи 3D куб) CSS3 властивість perspective.

CSS переходи, трансформації і анімації — Перспектива

CSS переходи, трансформації і анімації — Перспектива

Це друга частина з серії навчальних статей, присвячених практичному застосуванню CSS переходів, трансформацій і анімацій. В даній навчальній статті ми детально розберемо перспективу в CSS3 і випадки її застосування для поліпшення користувацького досвіду взаємодії.

Що таке перспектива?

У контексті двовимірного світу перспектива дає користувачам ілюзію глибини об’єкта, ширини, висоти і позиції щодо іншого об’єкта, якщо дивитися на об’єкт з певної точки зору. Перспектива дозволяє художникам створювати пейзажі, дивлячись на які створюється враження, що вони йдуть «всередину» полотна, або малювати на вулиці будівлі різних розмірів, які «йдуть» від нашого погляду. На двовимірній площині у об’єктів також є точка сходження, в якій «розчиняється» глибина об’єкта. Давайте проілюструємо це на простий діаграмі:

CSS переходи, трансформації і анімації — Перспектива

На даній діаграмі показані три об’єкти (прямокутники) на двовимірній площині. Коли прямокутники переміщуються по площині, то лінії перспективи (промені) можуть бути проведені до точки сходу, і тоді ми отримаємо тривимірні об’єкти. А оскільки Веб відображається на двовимірних поверхнях (тобто екранах пристроїв), то перспектива може допомогти нам створити схожу глибину. У світі Інтернету і CSS3 трансформацій, перспектива може бути визначена наступним чином (визначення з сайту MDN):

CSS властивість perspective визначає відстань між площиною z = 0 і користувачем, щоб дати 3D-позиционированному елементу деяку перспективу. Кожен 3D-елемент з z > 0, стає більше, а кожен 3D-елемент z < 0 — менше. Сила ефекту визначається значенням цієї властивості.

За замовчуванням точка сходження знаходиться по центру елемента, але ми можемо змінити це за допомогою властивості perspective-origin. Давайте подивимося на базовий приклад.

Демо-приклад № 1 – Базова перспектива

Давайте візьмемо дуже просту фігуру – квадрат – і використовуємо властивості перспективи, щоб надати їй трохи глибини. Для перших демо-прикладів я буду використовувати деякі допоміжні класи, щоб відобразити наступні діапазони:

властивість perspective не задано

властивість perspective зі значенням 100px

властивість perspective зі значенням 200px

властивість perspective-origin у значенні [0, 0]

Зверніть увагу на те, що властивості перспективи повинні бути батьківського контейнера того елемента, на який ми хочемо вплинути. Пам’ятаючи про це, розмітка для наступних трьох прикладів буде дійсно простий:


square

square

square

Давайте тепер застосуємо необхідні CSS властивості перспективи:

.perspective-container {
background-color: #eee;
}
.perspective—none {
/**/
}
.perspective—100 {
perspective: 100px;
}
.perspective—200 {
perspective: 200px;
}
.perspective-origin—00 {
perspective-origin: 0 0;
}
.surface {
display: block;
text-align: center;
width: 100%;
height: 100%;
color: #fff;
background-color: rgb(55,124,255);
font-size: 18px;
line-height: 200px;
}

Якщо ми відновимо нашу сторінку в браузері, то побачимо три однакових квадрата. Чому? Тому що жоден з наших трьох об’єктів не був насправді переміщений на площині. Щоб побачити, як властивості перспективи впливають на наші об’єкти, давайте перемістимо їх на площині по осі Z, використовуючи властивість transform. Ми додамо наступний CSS до нашого класу .surface, який управляє поданням наших об’єктів:

.surface {
transform: translateZ(-50px);
}

Тепер ми можемо побачити три різних результати:

Перший об’єкт залишився незмінним, тому що без вказівки яких-небудь правил для перспективи переміщення по осі Z (тобто і з екрану) не дасть ніяких змін в плані глибини.

Другий об’єкт трохи перемістився в середину екрана, оскільки ми вказали властивість perspective рівне 200px. Пам’ятайте, що, за визначенням, властивості перспективи встановлюють відстань між площиною z=0 і користувачем.

Третій об’єкт здається ще менше. Він перемістився у верхній лівий кут батьківського контейнера. Це сталося тому, що ми встановили властивість perspective-origin саме для батьківського контейнера.

Демо-приклад № 2 – Обертання фігур в перспективі

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

На цей раз у нас є ті ж три квадрата, але ми будемо обертати їх по осі Y, щоб вони поверталися «всередину» екрану. Ми будемо використовувати CSS ефект переходу разом з псевдо-класом :hover, щоб анімувати те, як властивості перспективи впливають на обертання. Ось розмітка:


square

square

square

На цей раз я додав допоміжний клас зі значенням 400px:

.perspective—400 {
perspective: 400px;
}

Нарешті, давайте подивимося на CSS для нашої нової фігури, який прописаний в класі surface-2:

.surface-2 {
display: block;
text-align: center;
width: 100%;
height: 100%;
color: #fff;
background-color: rgb(55,124,255);
font-size: 24px;
line-height: 200px;
transition: transform 1s;
}
.surface-2:hover {
transform: rotateY(180deg);
}

При наведенні ми отримуємо три різних результати:

Без вказівки перспективи перший об’єкт обертається на осі Z в дуже плоскою манері. Несхоже, щоб щось виходило у всередину або назовні екрану.

Коли ми встановлюємо перспективу зі значенням 400px, ми вже бачимо, що другий об’єкт обертається, «заглядаючи» і «виглядати» з екрану. А все завдяки перспективі.

А встановивши для третього об’єкта перспективу зі значенням 400px і вихідне положення зі значенням [0,0] ми досягаємо схожого ефекту (як і з другим об’єктом), але тільки вже відштовхуючись від вихідного положення.

Демо-приклад № 3 – 3D куб в різних вихідних положеннях

А тепер ми будемо створювати щось кльове. Ми збираємося створити куб (з шістьма сторонами), використовуючи CSS3 трансформації, і задамо для даного куба глибину за допомогою перспективи. Ми також налаштуємо систему управління, щоб ми могли «на льоту» змінювати властивості перспективи, щоб по-справжньому відчути, наскільки сильний вплив робить використання перспективи на кінцевий результат.

Ми будемо будувати наш куб, використовуючи 6 елементів span всередині батьківського елемента div з класом cube. Кожен елемент span буде представляти окрему сторону куба. А сам куб буде знаходитися всередині блоку-обгортки, для якого ми будемо задавати властивості перспективи. Ось така розмітка у нас вийшло:

front
back
top
bottom
left
right

Ми задамо деякі початкові налаштування для блоку-обгортки. Контейнер для куба буде мати відносне позиціонування, щоб кожна зі сторін куба могла бути абсолютно позиційована всередині контейнера і відповідним чином змінена. Якщо нам потрібно отримати куб, у якого довжина кожної сторони буде 200px, наш CSS буде наступним:

.wrap {
perspective: 500px;
perspective-origin: 50% 50%;
}
.cube {
position: relative;
margin: 100px auto;
width: 200px;
height: 200px;
transform-style: preserve-3d;
}

Зверніть увагу на те, що я спочатку поставив властивості perspective значення 500px, а для властивості perspective-origin — 50% 50%. Це спочатку створить нам деяку глибину для роботи, щоб ми могли побачити переміщення трансформованих елементів на площині. Запам’ятайте, що без перспективи трансформовані об’єкти не отримають тієї тривимірної глибини, до якої ми прагнемо. Властивість perspective-origin є необов’язковим, т. к. я вже вказав значення за замовчуванням (це центр контейнера), але я включив його тут просто для повторення.

Давайте тепер вивчимо сторони куба. Насамперед кожна сторона повинна бути абсолютно позиційована, і мати ширину і висоту в 200px. З метою візуалізації я також додам трохи внутрішніх тіней для кожної сторони. Ось як виглядає базовий CSS для сторін куба:

.face {
display: block;
position: absolute;
top: 0; left: 0;
width: 200px;
height: 200px;
color: #666;
font-size: 18px;
text-align: center;
line-height: 200px;
box-shadow: inset 0 0 4px rgba(0,0,0,0.5);
}

А тепер давайте подивимося на кожну сторону окремо. Ми встановили наступні розміри для нашого куба: 200 x 200 x 200. Але в цілому нам потрібно додати трохи глибини. Тому давайте пододвинем до нас лицьову сторону куба на 100px, а зворотний бік, навпаки, відсунемо. І тепер ми отримаємо ідеальний квадрат розміром 200px у центрі площини. Зворотна сторона куба також повинна бути повернута на 180 градусів, щоб вона була відображена назовні. Ось наш CSS:

.front {
transform: translateZ(100px);
}
.back {
transform: translateZ(-100px) rotateY(-180deg);
}

Тепер давайте подивимося на ліву і праву сторони. Ліву сторону потрібно перемістити вліво на 100px, потім повернути на -90 градусів по осі Y. З правою стороною потрібно виконати зворотні дії. Наступні правила розставлять їх по місцях:

.left {
transform: translateX(-100px) rotateY(-90deg);
}
.right {
transform: translateX(100px) rotateY(90deg);
}

І тепер давайте подивимося на верхню і нижню сторони. Верхню сторону потрібно підняти на 100px і повернути по осі X на 90 градусів, а з нижньою стороною все навпаки. Наступні правила допоможуть розташувати їх потрібним чином:

.top {
transform: translateY(-100px) rotateX(90deg);
}
.bottom {
transform: translateY(100px) rotateX(-90deg);
}

І ось ми отримали наш CSS куб, використовуючи трансформації і перспективу! А зараз давайте додамо деякі елементи управління, які дозволять нам змінювати «на льоту» властивості перспективи. Я буду використовувати елемент range і розміщу три таких елемента, щоб управляти налаштуваннями. Ось наша розмітка:

Perspective

0 1000px

Perspective Origin X

-1000px 1000px

Perspective Origin Y

-1000px 1000px

А ось і трохи JavaScript, який дозволить нам створити невеликий цікавий демо-приклад:

(function() {
«use strict»;
var wrap = document.getElementById(«wrap»);
var p = document.getElementById(«p»);
var pX = document.getElementById(«pX»);
var pY = document.getElementById(«pY»);
var pVal;
var xVal;
var yVal;
p.addEventListener. ( «input», function() {
pVal = p.value + «px»;
wrap.style.perspective = pVal;
});
pX.addEventListener. ( «input», function() {
xVal = pX.value + «px»;
yVal = pY.value + «px»;
wrap.style.perspectiveOrigin = xVal + «» + yVal;
});
pY.addEventListener. ( «input», function() {
xVal = pX.value + «px»;
yVal = pY.value + «px»;
wrap.style.perspectiveOrigin = xVal + «» + yVal;
});
})();

Ось тепер у нас є інтерактивний демо-приклад з 3D кубом, який створено завдяки CSS3 трансформацій та в перспективі.

Демо-приклад № 4 – Обертові куби

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

.rotate-x {
animation: spinX 4s infinite linear;
}
.rotate-y {
animation: spinY 4s infinite linear;
}
@keyframes spinX {
from { transform: rotateX(0); }
to { transform: rotateX(360deg); }
}
@keyframes spinY {
from { transform: rotateY(0); }
to { transform: rotateY(360deg); }
}

І ми можемо додати наступні класи для наших кубів:

Також зверніть увагу на важливість використання для куба властивості transform-style: preserve-3d. Це гарантує нам те, що сторони куба будуть залишатися в тривимірному просторі, а не ставати плоскими при трансформаціях.

Браузерна підтримка

Перспектива, переходи та анімацію підтримуються в браузері IE10 і вище, в той час як трансформації підтримуються в IE9 і вище. У зв’язку з цим дуже легко буде використовувати запасні рішення. Я протестував весь наведений код в нових версіях браузерів Chrome, Safari і Firefox. У них можна спокійно реалізовувати дані ефекти. Однак, переконайтеся, що ви додали всі необхідні вендорные префікси! Якщо ви будете завантажувати zip-архів з исходниками за наведеними посиланнями, то там префікси вже будуть додані.

Висновок

Ось і підійшла до кінця ця повчальна стаття! У ній ми докладно розглянули поняття перспективи в CSS3, а також деякі інші можливості комбінування перспективи з трансформаціями, переходами і анімаціями. Не забудьте подивитися демо-приклади та завантажити код за наведеними посиланнями. Якщо у вас є які-небудь питання, коментарі або відгуки, поділіться ними в коментарях.