Создание 3D эффекта на примере простых объектов
7 октября 2013 | Опубликовано в css | 3 Комментариев »
В данном уроке пойдет речь о технике, что может быть применена к объектам, у которых есть несколько сторон. Нашим примером будет 3D киногалерея с глянцевыми плакатами. Когда плакаты будут вращаться, стороны будут отображать матовые информационные карты с метаданными о фильме.
Работая с 3D трансформированными элементами, вы могли заметить, что они выглядят довольно плоско и не имеют затемнения. В реальности объекты блокируют свет и имеют тени. Если у вас есть желание рассмотреть примеры со сложной структурой, то есть доступные варианты, например, Photon.
Разметка
На странице будет несколько разных частей. Во-первых, нам нужно все, что есть, разместить в центре на странице. Затем, мы создадим список, который будет содержать все 3D постеры. Добавим класс «stage» к элементу ul
и «scene» каждому элементу li
. В CSS элементы класса «stage» будут выступать в качестве контейнера для элементов класса «scene», которые будут их 3D средой.
<div class="wrapper"> <ul class="stage"> <li class="scene"></li> <li class="scene"></li> <li class="scene"></li> </ul> </div>
Для каждого li
, нужно добавить немного разметки. Они будут содержать кинопостеры и все данные про каждый фильм.
<li class="scene"> <div class="movie"> <div class="poster"></div> <div class="info"> <header> <h1>It's a Wonderful Life</h1> <span class="year">1946</span> <span class="rating">PG</span> <span class="duration">130 minutes</span> </header> <p> In Bedford Falls, New York on Christmas Eve, George Bailey is deeply troubled. Prayers for his well-being from friends and family reach Heaven. Clarence Odbody, Angel Second Class, is assigned to visit Earth to save George, thereby earning his wings. Franklin and Joseph, the head angels, review George's life with Clarence. </p> </div> </div> </li>
В списке будет еще два фильма в придачу к этому. Данные немного содержательные и также есть еще изображения, которые понадобятся. Все это есть в загрузочных материалах.
Давайте перейдем к стилям.
CSS
wrapper
и убрать значения по умолчанию со списка класса stage
..wrapper { margin: 0 auto 100px auto; max-width: 960px; } .stage { list-style: none; padding: 0; }
Затем необходимо задать стили класса «scene» с высотой и шириной (такой же, как и у постеров).
Отступ margin
между элементами «scene» позволит сделать так, чтобы они не накладывались друг на друга. Задаем float
для всех элементов списка слева, чтобы они выстроились вряд друг за другом в галерею.
Добавляем свойство perspective
. Это позволит создать 3D сцену во вложенных элементах. Значение в 1000px даст объектам достаточную глубину, но вы можете экспериментировать и выбрать то значение, которое больше вам подходит.
.scene { width: 260px; height: 400px; margin: 30px; float: left; perspective: 1000px; }
Аналогично .scene
, также необходимо установить ширину и высоту для класса .movie
. Это поможет каждому постеру выглядеть правильно при трансформации. Затем установим стили трансформации так, чтобы можно было преобразовать элементы в 3D пространство. Наконец, добавим трансформации «translateZ» в размере «-130px». Это даст постерам немного больше места для движения и придаст им реального отображения зрителю.
.movie { width: 260px; height: 400px; transform-style: preserve-3d; transform: translateZ(-130px); transition: transform 350ms; }
.movie
. Выбор времени перехода установлен на 350ms, но, если вы желаете, можете замедлить переход..movie
в :hover
. Благодаря чему 3D постеры будут вращаться вдоль оси Y и затем перемещаться к экрану по оси Z..movie:hover { transform: rotateY(-78deg) translateZ(20px); }
Создаем каждый 3D постер. Каждый .poster
и .info
необходимо позиционировать абсолютно, так или иначе они будут выдвигать друг друга. Мы этого не хотим, потому что собираемся позиционировать их с использованием трансформации. Затем необходимо установить размеры двух классов так, чтобы каждая из сторон была точно такая же, как другая.
.movie .poster, .movie .info { position: absolute; width: 260px; height: 400px; background-color: #fff; backface-visibility: hidden; }
Классу .poster
необходимо задать трансформации «translateZ» в размере "130px" (так же, как мы двигали .movie
в размере «-130px»). Размер фона должен быть установлен таким образом, чтобы покрывать (cover) весь блок. Это просто предупредительная мера.
Класс .info
принимает те же трансформации, что и .poster
, но его нужно еще и повернуть. Мы хотим сформировать квадратную коробку, задаем вращение на 90 градусов.
.movie .poster { transform: translateZ(130px); background-size: cover; background-repeat: no-repeat; } .movie .info { transform: rotateY(90deg) translateZ(130px); border: 1px solid #B8B5B5; font-size: 0.75em; }
Будем использовать псевдоэлементы ::after
для создания другой стороны квадратной коробки, у которой будет «box shadow» ниже блока «movie»:
.movie::after { content: ''; width: 260px; height: 260px; position: absolute; bottom: 0; box-shadow: 0 30px 50px rgba(0,0,0,0.3); transform-origin: 100% 100%; transform: rotateX(90deg) translateY(130px); transition: box-shadow 350ms; } .movie:hover::after { box-shadow: 20px -5px 50px rgba(0,0,0,0.3); }
Далее прописываем стили метаданных, которые содержатся внутри класса .info.
.info header { color: #FFF; padding: 7px 10px; font-weight: bold; height: 195px; background-size: contain; background-repeat: no-repeat; text-shadow: 0px 1px 1px rgba(0,0,0,1); } .info header h1 { margin: 0 0 2px; font-size: 1.4em; } .info header .rating { border: 1px solid #FFF; padding: 0px 3px; } .info p { padding: 1.2em 1.4em; margin: 2px 0 0; font-weight: 700; color: #666; line-height: 1.4em; border-top: 10px solid #555; }
Вот здесь используем свойство box-shadow
. Радиус размытия будет установлен на 40px,
а тени - rgba(255,255,255,0)
.
.movie .poster, .movie .info, .movie .info header { transition: box-shadow 350ms; } .movie .poster { box-shadow: inset 0px 0px 40px rgba(255,255,255,0); } .movie:hover .poster { box-shadow: inset 300px 0px 40px rgba(255,255,255,0.8); }
Точно так же, как и для постера, мы хотим применить тени и для другой стороны коробки. Для панели .info
берем темные тени, которые исчезают, когда элемент вращается вперед и появляются, когда он отступает назад, в зазоре между каждым 3D постером. На странице с глянцевым плакатом слева появляется тень справа, как будто есть источник света, прибывающий из левой стороны страницы.
.movie .info, .movie .info header { box-shadow: inset -300px 0px 40px rgba(0,0,0,0.5); } .movie:hover .info, .movie:hover .info header { box-shadow: inset 0px 0px 40px rgba(0,0,0,0); }
Последнее, но не не менее важно то, что мы должны добавить изображение постера и изображение предварительного просмотра к каждому кино. Используем псевдокласс :nth-child
.
.scene:nth-child(1) .movie .poster { background-image: url(../img/poster01.jpg); } .scene:nth-child(2) .poster { background-image: url(../img/poster02.jpg); } .scene:nth-child(3) .poster { background-image: url(../img/poster03.jpg); } .scene:nth-child(1) .info header { background-image: url(../img/still01.jpg); } .scene:nth-child(2) .info header { background-image: url(../img/still02.jpg); } .scene:nth-child(3) .info header { background-image: url(../img/still03.jpg); }
Это все!
Перевод — Дежурка.
Автор урока - Nick Pettit.
Возможно, вас также заинтересует: Слайдер на CSS3 с эффектом параллакса.
21 октября 2013 в 23:46
Очень интересно! Но всё же как то всё привязано к конкретным картинкам. Как бы, это, по-абстрактнее что ли. Чтобы без лишних переделок можно было адаптировать сей код, например, для фотогалереи.