Как создать 3D-эффект с помощью CSS Perspective и анимации книги

Как создать 3D-эффект с помощью CSS Perspective и анимации книги

5 апреля 2024 г.

Если вы читали о 3D в CSS и не до конца поняли, как сделать 3D так, как вы хотите, используя простой CSS, я надеюсь, что эта мини-статья может вам помочь. В конце концов у вас получится построить что-то вроде этого :)

https://codepen.io/juliashlykova/pen/XWQzXVm?embedable=true

Перспектива

Что такое перспектива в CSS? Когда мы устанавливаем perspective для элемента, он сообщает браузеру, что дочерний элемент этого элемента должен вести себя так, как если бы он находился в трехмерном пространстве.

<блок-цитата>

Величина перспективы определяет расстояние между пользователем и плоскостью z=0.

Я пытался выяснить, как может быть, что чем большую перспективу мы устанавливаем, тем меньше перспективы мы видим. Поначалу меня это действительно сбивало с толку. Если только я не нарисую какую-нибудь схему:

Imaginary perspective

Когда мы меняем координату Z (translateZ()) для дочернего элемента, мы перемещаем дочерний элемент вдоль этой воображаемой оси Z по направлению к пользователю. Таким образом, чем дальше от нас находится плоскость z=0, тем менее заметно изменение.

Происхождение перспективы

perspective-origin: horisontal-positionverter-position определяет положение глаз пользователя относительно преобразованных элементов. По умолчанию эта позиция центрирована: perspective-origin: 50% 50%

Стиль трансформации

transform-style: save-3d позволяет позиционировать дочерние элементы элемента в трехмерном пространстве. И у меня вопрос был: а не для чего это перспектива? Вообще-то, нет. Transform-style не добавляет глубины. Если в родительском элементе нет перспективы, то мы не увидим настоящего 3D-представления:

https://codepen.io/juliashlykova/pen/BaEmWqq?editors=1100&embedable = верно

transform-style: save-3d просто позволяет детям жить в своем собственном трехмерном пространстве.

Анимация книг

Теперь давайте сделаем классную анимацию :smiley:.

Прежде всего, наше тело index.html будет выглядеть так:

  <div class="container">
    <div class="book">
      <span class="shadow"></span>
      <div class="back"></div>
      <div class="cover-end"></div>
      <div class="page last">
        <button class="btn-tale">Tale begins...</button>
      </div>
      <div class="page third"></div>
      <div class="page second"></div>
      <div class="page first"></div>
      <div class="cover">
        <img src="https://cdn.pixabay.com/photo/2024/03/30/12/44/landscape-8664708_1280.png" alt="">
      </div>
    </div>
  </div>

<блок-цитата>

Далее я опускаю несущественные для темы свойства; вы можете посмотреть их в исходном коде во введении.

У нас есть блок div для каждой страницы, поскольку каждая страница ведет себя по-разному. Давайте сначала добавим perspective в блок-контейнер:

.container {
  perspective: 500px;
  perspective-origin: 50% 50%;
}

Мы используем перспективное происхождение по умолчанию. Но я предпочел указать это явно для лучшего понимания. Итак, наши глаза находятся в центре контейнера, а плоскость z=0 находится на расстоянии 500 пикселей от нас.

На данный момент наш блок book установлен на плоскости z=0 и не имеет никаких трехмерных функций. Давайте добавим transform-style, чтобы страницы могли вести себя в своем собственном трехмерном пространстве:

.book {
  position: relative;
  transform-style: preserve-3d;
}

.book>div {
  position: absolute;
  top: 0;
  left:0;
  transition: transform 2s;
}

Теперь давайте добавим настоящее 3D :)

.cover {
  transform: scaleY(1.05) rotateY(-10deg);
}

.page.first {
  transform: translateX(2px) rotateY(-10deg);
}

.page.second {
  transform: translateX(4px) rotateY(-10deg);
}

.page.third {
  transform: translateX(6px) rotateY(-10deg);
}

.page.last {
  transform: translateX(8px) rotateY(-10deg);
}

Чтобы добиться объема, мы сдвигаем каждую страницу немного вправо и вращаем ее вокруг оси Y. Теперь давайте изменим поведение книги при наведении на нее курсора:

.book:hover .cover{
  transform: rotateY(-150deg);
}

.book:hover .page.first{
  transform: translateX(2px) rotateY(-150deg);
}

.book:hover .page.second{
  transform: translateX(4px) rotateY(-130deg);
}

.book:hover .page.third{
  transform: translateX(6px) rotateY(-110deg);
}

Хорошо, здесь мы изменяем поворот с -10deg на более экстремальные значения, чтобы добиться «эффекта открытия». Кроме того, нам следует сохранить наш translateX, поскольку преобразование перезаписывает все свои предыдущие значения.

Вот и все! Надеюсь, теперь вы понимаете немного больше о перспективе в CSS :slightly_smiling_face:.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE