Слайд-шоу изображений — это скучно. Давайте создадим кубики
Вы когда-нибудь задумывались о создании куба изображений?🤭 Да, я не задумывался, пока однажды, просматривая веб-сайт, не наткнулся на это объявление:
Это объявление я видел не впервые, но в тот день оно привлекло мое внимание. Как ни странно, в то время я работал над проектом, где мне нужно было реализовать слайд-шоу изображений в лайтбоксе, и я подумал про себя, как было бы здорово, чтобы изображения отображались в форме куба, как это, а не обычные слайд-шоу, к которым мы привыкли? Я не совсем был уверен, как это реализовать, но после нескольких часов проб и ошибок я в конце концов пришел к следующему😁:
Я называю это Куб-Шоу🤭. Вы можете проверить это на живом сайте
Самой сложной частью этого проекта было точное определение времени вращения куба для обновления изображений на каждой стороне куба и сохранение стабильности вращения куба при вращении куба вперед или назад.
Интересно, как мне удалось это реализовать? Что ж, тогда давайте узнаем. Чтобы начать, нам просто нужно создать три файла: HTML, CSS и JS.
Настройка HTML
Первое, что нам нужно сделать, это объявить структуру куба в HTML-файле.
<div id="container">
<ion-icon name="chevron-back" id="back-icon"></ion-icon>
<div id="cube">
<div class="side front"><img src="https://source.unsplash.com/500x500?car" alt="front" class="side-img" /></div>
<div class="side left"><img src="https://source.unsplash.com/500x500?lake" alt="left" class="side-img" /></div>
<div class="side back"><img src="https://source.unsplash.com/500x500?man" alt="back" class="side-img" /></div>
<div class="side right"><img src="https://source.unsplash.com/500x500?dog" alt="right" class="side-img" /></div>
</div>
<ion-icon name="chevron-forward" id="forward-icon"></ion-icon>
</div>
В приведенном выше коде мы объявили контейнер div; внутри этого div у нас есть 3 элемента: левый значок для поворота куба назад, еще один элемент div для куба и правый значок для поворота куба вперед. Внутри div куба у нас есть еще 4 div для сторон куба, и в каждом из них есть тег изображения для отображения изображений.
Это все, что нам нужно в нашем HTML-файле. Настоящая работа еще впереди😬. Далее давайте стилизуем элементы.
Стилизация с помощью CSS
Внутри нашего CSS-файла нам сначала нужно объявить общие стили страницы следующим образом:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
place-items: center;
padding: 5px;
}
Далее мы зададим стиль для контейнера div
и значков «Назад» и «Вперед».
#container {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
ion-icon {
font-size: 50px;
cursor: pointer;
z-index: 100;
}
ion-icon:hover {
color: brown;
}
Двигаясь дальше, давайте настроим сам куб, а также анимацию вперед и назад, которую мы применим к кубу для его вращения влево или вправо.
#cube {
width: min(55vw, 500px);
aspect-ratio: 1;
margin: 40px;
border-radius: 15px;
position: relative;
transform-style: preserve-3d;
animation: turnRight 30s linear infinite;
cursor: pointer;
}
@keyframes turnRight {
0% {
transform: rotateX(5deg) rotateY(0deg);
}
100% {
transform: rotateX(5deg) rotateY(360deg);
}
}
@keyframes turnLeft {
0% {
transform: rotateX(5deg) rotateY(360deg);
}
100% {
transform: rotateX(5deg) rotateY(0deg);
}
}
Теперь давайте стилизуем четыре стороны куба вместе с тегами img
в них.
.side {
position: absolute;
width: 100%;
height: 100%;
border: 1px solid black;
text-align: center;
line-height: 200px;
border-radius: 15px;
-webkit-box-reflect: below 40px linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.2));
}
.side-img {
width: 100%;
height: 100%;
object-fit: cover;
}
Это очень важный шаг в достижении кубического эффекта. Нам нужно рассчитать угол поворота и перемещения каждой стороны куба в соответствии с шириной самого куба. Это также гарантирует, что стороны не станут больше или меньше куба при просмотре на экранах разных размеров.
.front {
transform: translateZ(calc(min(55vw, 500px) / 2));
}
.back {
transform: translateZ(calc(-1 * min(55vw, 500px) / 2)) rotateY(180deg);
}
.right {
transform: rotateY(90deg) translateZ(calc(min(55vw, 500px) / 2));
}
.left {
transform: rotateY(-90deg) translateZ(calc(min(55vw, 500px) / 2));
}
Это оболочка для нашего CSS-файла. Теперь у нас есть красивый вращающийся куб со статичными изображениями. Теперь давайте перейдем к нашему файлу JavaScript, чтобы добавить в куб функциональность и динамический просмотр изображений.
Добавление функциональности с помощью JavaScript
Чтобы начать работу с нашим JS-файлом, нам сначала нужно получить все элементы HTML, с которыми мы будем работать, объявить массив, содержащий источник изображений, с помощью которых мы будем обновлять куб. и объявим несколько переменных, которые мы будем использовать по мере продвижения вперед.
const cube = document.getElementById("cube");
const leftButton = document.getElementById("back-icon");
const rightButton = document.getElementById("forward-icon");
const cubeSides = document.querySelectorAll(".side-img");
let imagesFilePath = [
"https://source.unsplash.com/500x500?car",
"https://source.unsplash.com/500x500?lake",
"https://source.unsplash.com/500x500?man",
"https://source.unsplash.com/500x500?dog",
"https://source.unsplash.com/500x500?pond",
"https://source.unsplash.com/500x500?city",
"https://source.unsplash.com/500x500?trees",
"https://source.unsplash.com/500x500?volcano",
"https://source.unsplash.com/500x500?ice",
"https://source.unsplash.com/500x500?cat",
"https://source.unsplash.com/500x500?flowers",
"https://source.unsplash.com/500x500?koala",
"https://source.unsplash.com/500x500?bird",
"https://source.unsplash.com/500x500?girl",
"https://source.unsplash.com/500x500?valley"
];
let imgtag = 0;
let srcIndex = 4;
let intervalID;
let isAnimating = true;
Далее мы создадим две функции для последовательного обновления изображений на каждой стороне куба каждые 7,6 секунды. Мы рассчитываем продолжительность интервала, разделив продолжительность CSS-анимации на 4, гарантируя, что все стороны будут обновлены до завершения анимации.
// Moves through the image source array forwards and updates the cube's next side
function rotateForwards() {
clearInterval(intervalID); // Clear previous interval
intervalID = setInterval(() => {
cubeSides[imgtag].src = imagesFilePath[srcIndex];
imgtag = (imgtag + 1) % cubeSides.length;
srcIndex = (srcIndex + 1) % imagesFilePath.length;
}, 7500);
}
rotateForwards();
// Moves through the image source array backwards and updates the cube's previous side
function rotateBackwards() {
clearInterval(intervalID); // Clear previous interval
intervalID = setInterval(() => {
imgtag = (imgtag - 1 + cubeSides.length) % cubeSides.length;
srcIndex = (srcIndex - 1 + imagesFilePath.length) % imagesFilePath.length;
cubeSides[imgtag].src = imagesFilePath[srcIndex];
}, 7500);
}
После этого нам нужно прикрепить только что созданные функции к кнопкам со стрелками влево и вправо соответственно и установить стиль анимации куба на поворот влево или вправо.
leftButton.onclick = () => {
cube.style.animation = "turnLeft 30s linear infinite";
rotateBackwards();
};
rightButton.onclick = () => {
cube.style.animation = "turnRight 30s linear infinite";
rotateForwards();
};
Теперь мы хотим иметь возможность приостанавливать вращение куба, чтобы пользователь мог дольше просматривать фотографию. Для этого мы прикрепляем к кубу событие onclick
и проверяем, запущена ли уже анимация. Если да, то приостанавливаем его, а если не работает, возобновляем вращение куба.
cube.onclick = (e) => {
if (isAnimating) {
// If animation is running, pause it
clearInterval(intervalID);
cube.style.animationPlayState = "paused";
isAnimating = false;
} else {
// If animation is paused, resume it
rotateForwards();
cube.style.animationPlayState = "running";
isAnimating = true;
}
};
И благодаря этому, дамы и господа, нам удалось создать потрясающее имиджевое куб-шоу🤭. Ознакомьтесь с полным исходным кодом этого проекта на GitHub.
Дайте мне знать, что вы, ребята, думаете. Обратная связь очень приветствуется🤗✨. Пожалуйста, не стесняйтесь задавать мне любые вопросы или высказывать замечания. А пока удачного кодирования, ребята!✨✌