Добавьте еще одно измерение к веб-страницам с помощью новых функций 3D-преобразования в CSS. Разберемся с масштабированием, вращением, перспективой, а также проблемами z-index и подводными камнями браузеров.

HTML-элементы могут быть трансформированы в трех направлениях:

  • горизонтальная ось X;
  • вертикальная ось Y;
  • и уходящая вглубь монитора ось Z.

Считается, что поверхность экрана — это начало Z-оси. Объекты с положительными Z-координатами будут выдвигаться ближе к пользователю, а с отрицательными — перемещаться вдаль. При добавлении перспективы слой с большим отрицательным Z-значением может полностью пропасть.

Следует отметить несколько моментов:

  1. CSS может только преобразовать двумерные элементы HTML в трехмерном пространстве. Сами элементы остаются плоскими и имеют нулевую глубину. Масштабирование в z-плоскости не сделает из квадрата куб. В принципе, вы можете создать полноценный куб, но для этого потребуется шесть элементов: по одному для каждой стороны.
  2. 3D-преобразования отлично подходят для создания эффектов страницы, но вряд ли позволят создать следующий MineCraft или Call of Duty. Сложные модели лучше реализовать с использованием WebGL.

3D преобразования хорошо поддерживаются во всех современных браузерах (включая IE10+) с некоторыми исключениями:

  • Internet Explorer не поддерживает transform-style: preserve-3d, что делает невозможным создание 3D сцен.
  • Все версии Safari должны использовать префикс -webkit-backface-visibility для скрытия задних граней. Все остальные браузеры поддерживают свойство backface-visibility.

На примере вы можете увидеть, как работают CSS-трансформации, которые будут разобраны ниже:

See the Pen 3D transform functions by Craig Buckler (@craigbuckler) on CodePen.

transform

К любому элементу можно применить свойство transform. Оно принимает функцию с одним или несколькими параметрами. Например:

.element {
  transform: function1(parameter1, [...parameterN]);
}

Если требуется две или более трансформаций, можно указать несколько функций, разделенных пробелами:

.element {
  transform: function1(p1, [...pN]) function2(p1, [...pN]);
}

Например, горизонтальное масштабирование и вертикальный сдвиг:

.element {
  transform: scaleX(2) translateY(50px);
}

Правило transform: none отменяет все существующие трансформации.

Функции сдвига

С помощью translate-функций можно переместить элемент по горизонтали или по вертикали вдоль осей X и Y:

transform: translateX(50px);        /* 50px вправо */
transform: translateY(-100%);       /* 100% вверх */
transform: translate(50px, -100%);  /* одновременно */

Можно использовать любые единицы измерения расстояния. Проценты будут отсчитываться от размеров самого элемента, таким образом, блок с высотой 100px функция при использовании translateY(80%) будет сдвинут на 80px.

Для сдвига в третьем направлении существует translateZ:

transform: translateZ(-200px);      /* 200px вглубь экрана */

Возьмем три элемента – #box1, #box2 и #box3 – и спозиционируем их абсолютно в одной точке. К #box применим translateZ(-200px), а к #box3translate(-400px). Результат довольно скучный:

Повернем весь родительский контейнер #scene по z-оси, чтобы понять, что происходит:

#scene {
  transform-style: preserve-3d;
  transform: rotateX(-10deg) rotateY(-10deg);
}

Функция translate3d позволяет сдвинуть элемент по всем трем осям одновременно:

transform: translate3d(50px, 100%, 7em);

transform-style

По умолчанию (и всегда в IE), свойство transform-style имеет значение flat. Это означает, что все преобразованные дочерние элементы контейнера лежат в плоскости самого элемента. Другими словами, какую бы трансформацию вы не назначили, она не выйдет за двумерные рамки родителя.

В большинстве случаев transform-style: preserve-3d; указывает, что дочерние элементы блока позиционируются в 3D-пространстве и все трансформации контейнера должны этому соответствовать.

Вращение

2D-функция rotate() поворачивает элементы вокруг Z-оси и идентична rotateZ(). Для примера:

transform: rotateZ(45deg); /* аналогичный эффект rotate(45deg) */

rotateX() управляет вращением вокруг горизонтальной оси, а rotateY() – вокруг вертикальной.

Угол вращения может быть определен несколькими способами:

  • turn: например, 0.5turn – это половина оборота по часовой стрелке;
  • deg (градусы): 90deg – четверть оборота по часовой стрелке;
  • rad (радианы): -3.1416rad – половина оборота против часовой стрелки;
  • grad (градианы): один полный оборот равен 400grad, таким образом, -200grad – это четверть оборота против часовой стрелки;

Три оси вращения могут быть установлены функцией rotate3d(). Немного путает то, что она принимает четыре параметра для определения вектора вращения:

  • x – x-координата вектора, обозначающая ось вращения (0 или 1).
  • y – y-координата вектора, обозначающая ось вращения (0 или 1).
  • z – z-координата вектора, обозначающая ось вращения (0 или 1).
  • a – угол вращения. Положительное значение определяет поворот по часовой стрелке, а отрицательное – против.

Любители математики мазохисты могут ознакомиться с детальной документацией свойства rotate3d на MDN.

Масштабирование

Функции scaleX() и scaleY растягивают или сжимают элемент по горизонтали или по вертикали соответственно.

transform: scaleX(2);   /* ширина в 2 раза больше */
transform: scaleY(0.5); /* высота в 2 раза меньше */

scaleZ() делает то же самое, но в глубину. В самом первом примере установка свойства transform: scaleZ(0.5) уменьшит расстояние между квадратами в два раза.

Функция scale3d(x, y, z) позволяет масштабировать сразу во всех направлениях:

#scene {
  transform-style: preserve-3d;
  transform: scale3d(2, 1, 0.5) rotateX(-10deg) rotateY(-10deg);
}

Центр трансформаций

По умолчанию элемент вращается и масштабируется относительно его центральной точки. Это поведение можно изменить, установив свойство transform-origin с одним, двумя или тремя разделенными пробелами значениями:

  • одно значение: смещение по x-оси. Может быть указано в единицах расстояния или процентах. Также можно использовать ключевые слова left, center, right, top или bottom. Тут top и bottom устанавливают y-смещение, а x при этом остается в центре.
  • два значения: смещение по x и y.
  • три значения: смещение по x, y и z. Для последнего можно использовать только единицы длины (px, em).

Перемещение координаты по одной оси влияет на плоскости вращения по другим. Например, transform-origin: left center 0; перемещает начало координат в центр левой грани. Это повлияет на функции rotateY() и rotateZ().

Видимость задних граней

Задняя часть элемента отображается, когда он вращается вокруг оси x или y более чем на 90, но менее чем на 270 градусов в любом направлении. Задняя часть зеркально повторяет переднюю, и по умолчанию она видна (значение visible).

Ее можно скрыть, установив backface-visibility: hidden;:

#box2 {
  backface-visibility: hidden;
}

#scene {
  transform: rotateX(-10deg) rotateY(-135deg);
}

backface-visibility: hidden; часто используется для анимации переворачивания карты, где два элемента обозначают переднюю и заднюю часть карты, но только один может быть виден в текущий момент.

Перспектива

Примеры, разобранные выше, не используют перспективу. Элемент, перемещенный глубже в плоскости z, остается того же размера, независимо от того, как далеко он находится от пользователя. По умолчанию свойство perspective равно none, но может иметь любое положительное значение. Например:

#scene {
  perspective: 1000px;
  transform: rotateX(-15deg) rotateY(-15deg);
}

Чем меньше длина перспективы, тем ближе точка схода и тем более выражен 3D-эффект:

#scene {
  perspective: 200px;
  transform: rotateX(-15deg) rotateY(-45deg);
}

Точка схода

По умолчанию точка схода перспективы находится в центре трансформируемого элемента. Его можно изменить, установив perspective-origin: x y;, где:

x – ключевое слово (left, center, right) или процент от ширины элемента (значения 0%, 50% и 100% эквивалентны ключевым словам).
y – ключевое слово (top, center, bottom) или процент от высоты элемента (значения 0%, 50% и 100% эквивалентны ключевым словам).

Точка схода в верхнем левом углу:

#scene {
  perspective-origin: left top; /* or 0% 0% */
  perspective: 1000px;
}

Точка схода в нижнем правом углу:

#scene {
  perspective-origin: right bottom; /* or 100% 100% */
  perspective: 1000px;
}

Кроме того, существует функция perspective() – например, transform: perspective(200px). Однако, она, кажется, не учитывает perspective-origin.

Все вместе

Масштабирование, вращение и сдвиг могут быть определены в одной функции matrix3d(), которая требует не менее 16 значений для трехмерного аффинного преобразования.

Ее лучше всего использовать в JavaScript и только тем, кто хорошо разбирается в геометрии! В CSS удобнее и проще использовать простые функции преобразования.

Полезные ссылки

CSS-трансформации позволяют упростить манипуляции с объектам в трех измерениях. В интернете много потрясающих примеров 3D-преобразований, включая виртуальную реальность, шутеры от первого лица, галереи изображений и скользящий текст из Star Wars. Не все они могут использоваться в реальных проектах. Тем не менее, несколько изящных и плавных 3D-эффектов добавят на ваши страницы новое измерение реальности.

0 комментариев

Оставить комментарий

*Доступные HTML-теги: a, abbr, blockquote, code, pre, del, i, em, strong, b, strike
*Не будет опубликован