Как создать 3D-эффект с помощью CSS Perspective и анимации книги
5 апреля 2024 г.Если вы читали о 3D в CSS и не до конца поняли, как сделать 3D так, как вы хотите, используя простой CSS, я надеюсь, что эта мини-статья может вам помочь. В конце концов у вас получится построить что-то вроде этого :)
https://codepen.io/juliashlykova/pen/XWQzXVm?embedable=true р>
Перспектива
Что такое перспектива
в CSS? Когда мы устанавливаем perspective
для элемента, он сообщает браузеру, что дочерний элемент этого элемента должен вести себя так, как если бы он находился в трехмерном пространстве.
Величина перспективы определяет расстояние между пользователем и плоскостью z=0.
Я пытался выяснить, как может быть, что чем большую перспективу мы устанавливаем, тем меньше перспективы мы видим. Поначалу меня это действительно сбивало с толку. Если только я не нарисую какую-нибудь схему:
Когда мы меняем координату 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:.
Оригинал