Яндекс.Метрика

Дизайн-журнал №1. Актуальная информация для дизайнеров, веб дизайнеров, программистов и разработчиков сайтов.

Создание раскладывающейся трехмерной галереи изображений

7 сентября 2018 | Опубликовано в css | Нет комментариев »

Нам хотелось создать галерею изображений, которая бы последовательно разворачивалась для показа всех изображений и при раскладывании которой происходила бы интересная трехмерная анимация. Когда галерея слегка развернута, но все еще сложена, она выглядит подобным образом:

 

 


Для создания впечатления бумажных задних сторон у большинства изображений в галерее используются элементы подписи изображений.

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

<figure id="dolls" onclick="unwrap()">
        <img src="brazillian-indian-child.jpg" alt>
                <figure id="dolls-inner1">
                        <img src="burmese-child-monk.jpg" alt>
                        <figcaption>Faces Around The World</figcaption>
                                <figure id="dolls-inner2">
                                <img src="egyptian-girl.jpg" alt>
                                <figcaption></figcaption>
                                        <figure id="dolls-inner3">
                                                <img src="lesotho-girl.jpg" alt>
                                                <figcaption></figcaption>
                                        </figure>
                                </figure>
                </figure>
</figure>

Ниже схематично показано расположение первых трех элементов фигур в галерее:

Содержащему блоку задано подходящее значение свойства перспективы, и каждый элемент фигуры присоединяется к нему с левой стороны:

* {
        box-sizing: border-box;
}
#dolls {
        width: 100%;
        font-size: 0;
        perspective: 1500px;
}
#dolls:hover {
        cursor: pointer;
}
#dolls figure {
        margin: 0;
        display: inline-block;
        transform-origin: left center;
        transform-style: preserve-3d;
        position: relative;
}
#dolls > img { width: 25%;  }
#dolls figure {
        transition-duration: 1s;
}
#dolls-inner1 > figcaption {
        border: 2px solid #333;
}
#dolls-inner1 figcaption span {
        display: block;
        font-size: 1.2rem;
}

Изначально изображениям задана ширина, равная четверти ширины содержащего блока, и каждому элементу фигуры задан переход продолжительностью в одну секунду:

#dolls > img { width: 25%;  }
#dolls figure { transition-duration: 1s; }

Элементы подписи фигуры используются для создания впечатления о наличии задней стороны у каждой фотографии путем сдвигания их по оси Z на один пиксель:

#dolls-inner1 > figcaption {
        border: 2px solid #333;
}
#dolls figcaption {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0; left: 0;
        transform: translateZ(-1px);
        background-image: url(paper-background.jpg);
        background-size: contain;
        font-size: 1.4rem;
        text-align: center;
        padding-top: .5rem;
}

Класс .rewrap будет применен к содержащему блоку, чтобы сворачивать изображения обратно после того, как они развернуты:

.rewrap #dolls-inner1 {
        transition-delay: 2s;
}
.rewrap #dolls-inner2 {
        transition-delay: 1s;
}
.rewrap #dolls-inner3 {
        transition-delay: 0s;
}

Если окно браузера шириной хотя бы 751 пиксель, развернутые изображения будут расположены в ряд. Вложенная структура элементов создает необычный эффект у изображений внутри, и чтобы компенсировать это, нужно использовать масштабирование:

@media screen and (min-width: 751px) {
        #dolls-inner1 {
                width: 75%;
                transform: rotateY(-175deg);
        }
        #dolls-inner1 figcaption {
                transform: translateZ(-2px) rotateY(180deg);
        }
        #dolls-inner1 > * {
                width: 33.33%;
        }
        #dolls-inner2 {
                width: 50%;
                transform: rotateY(-175deg);
        }
        #dolls-inner2 > * {
                width: 66.66%;
        }
        #dolls-inner3 {
                width: 25%;
                transform: rotateY(-180deg);
        }
        #dolls-inner3 > * {
                width: 266%;
        }
}

Когда они разворачиваются, каждая группа изображений трансформируется, пока не станет почти плоской:

.unwrap #dolls-inner1,
        .unwrap #dolls-inner2,
        .unwrap #dolls-inner3 {
                transform: rotateY(-1deg);
}
.unwrap #dolls-inner2 {
        transition-delay: 1s;
}
.unwrap #dolls-inner3 {
        transition-delay: 2s;
}

Если окно браузера шириной менее 750 пикселей, изображения появляются друг над другом:

@media screen and (max-width: 750px) {
        #dolls {
                width: 80%;
                margin: 2rem auto;
        }
        #dolls figure {
                transform-origin: center top;
                width: 100%; display: block;
        }
        #dolls-inner1, #dolls > img,
                #dolls-inner1 > *, #dolls-inner2 > *,
                #dolls-inner3 > *  {
                        width: 100%;
                }
        #dolls-inner1 {
                transform: rotateX(175deg);
        }
        #dolls-inner1 > figcaption {
                transform: translateZ(-1px) rotateX(180deg);
        }
        #dolls-inner2 {
                transform: rotateX(177deg);
        }
        #dolls-inner3 {
                transform: rotateX(178deg);
        }
        #dolls-inner1 > figcaption {
                height: 33%;
        }
        #dolls-inner2 > figcaption {
                height: 50%;
        }
        #dolls-inner3 > figcaption {
                height: 100%;
        }
        .unwrap #dolls-inner1,
                .unwrap #dolls-inner2,
                .unwrap #dolls-inner3 {
                        transform: rotateX(-1deg);
        }
        unwrap #dolls-inner2 {
                transition-delay: 1s;
        }
        .unwrap #dolls-inner3 {
                transition-delay: 2s;
        }
}

И, наконец, JavaScript используется, чтобы начать разворачивание и сворачивание элементов фигуры:

function unwrap(){
        if (dolls.classList.length == 0 || dolls.classList.contains("rewrap")) {
                dolls.classList.remove("rewrap");
                dolls.classList.add("unwrap");
                } else {
                dolls.classList.remove("unwrap");
                dolls.classList.add("rewrap");
                }
}

В результате получим следующее:

Конечно, подобный результат может быть достигнут разными путями. Надеемся, наш урок вдохновит dас на эксперименты.

Использованы фотографии David Lazar.

Автор урока Dudley Storey

Перевод — Дежурка

Смотрите также: