Красивая 3D карусель, которая управляется зажатием и движением мышки.

Красивая 3D карусель, которая управляется зажатием и движением мышки.

Возможности карусели:
  • Любое количество фотографий.
  • Произвольный радиус.
  • Автоматическое движение с заданной скоростью.
  • Отсутствие дополнительных библиотек.
  • Всего 90 строк кода. 

Более подробно о настройках и вариантах карусели описано внизу страницы.

Пример:


HTML:

Количество фотографий может быть любое.

<div id="carousel">

    <div id="drag-container">

        <div id="spin-container">

            <a href="/photo-large.jpg"><img src="/photo-small.jpg" alt="" /></a>

            <!-- Еще фото -->

            <a href="/photo-large.jpg"><img src="/photo-small.jpg" alt="" /></a>

            <p>3D Carousel</p>

        </div>

        <div id="ground"></div>

    </div>

</div>{codeBox}


CSS:

#carousel  {touch-action: none; display: flex; height: 400px; perspective: 1000px; transform-style: preserve-3d; }

#drag-container, #spin-container { position: relative;  display: flex; margin: auto; transform-style: preserve-3d; transform: rotateX(-10deg);}

#drag-container a { transform-style: preserve-3d; position: absolute; left: 0; top: 0; width: 100%; height: 100%;  box-shadow: 0 4px 8px rgba(0,0,0,0.2), 0 10px 16px rgba(0,0,0,0.1);  border: 8px solid }

#drag-container img { width: 100%; height: 100%;  filter: grayscale(50%) contrast(0.8);  transition: filter 0.3s; }     

#drag-container a:hover img{ filter: grayscale(0) contrast(1); }          

#drag-container p { line-height: 1; font-size: 50px; font-weight: bold;  text-align: center; font-family: Serif; position: absolute; top: 100%; left: 50%; transform: translate(-50%, -50%) rotateX(90deg); color: #337AB7; font-family: Verdana, sans-serif;}

#ground { width: 900px; height: 900px; position: absolute;  top: 100%;

    left: 50%;  transform: translate(-50%, -50%) rotateX(90deg); }

@keyframes spin { from {  transform: rotateY(0deg); }

    to {  transform: rotateY(360deg); } }

@keyframes spinRevert { from {  transform: rotateY(360deg); }

    to { transform: rotateY(0deg); } }{codeBox}  


JS:

let radius = 240; 

let autoRotate = true;

let rotateSpeed = -60; 

let imgWidth = 140; 

let imgHeight = 205;

setTimeout(init, 300);

let odrag = document.getElementById("drag-container");

let ospin = document.getElementById("spin-container");

let carousel = document.getElementById("carousel");

let aImg = ospin.getElementsByTagName("a");

ospin.style.width = imgWidth + "px";

ospin.style.height = imgHeight + "px";

let ground = document.getElementById("ground");

ground.style.width = radius * 3 + "px";

ground.style.height = radius * 3 + "px";

function init(delayTime) {

    for (let i = 0; i < aImg.length; i++) {

        aImg[i].style.transform =

        "rotateY(" +

        i * (360 / aImg.length) +

        "deg) translateZ(" +

        radius +

        "px)";

        aImg[i].style.transition = "transform 1s";

        aImg[i].style.transitionDelay =

        delayTime || (aImg.length - i) / 4 + "s";

    }

}

function applyTranform(obj) {

    if (tY > 180) tY = 180;

    if (tY < 0) tY = 0;

    obj.style.transform = "rotateX(" + -tY + "deg) rotateY(" + tX + "deg)";

}

function playSpin(yes) {

    ospin.style.animationPlayState = yes ? "running" : "paused";

}

let sX,

sY,

nX,

nY,

desX = 0,

desY = 0,

tX = 0,

tY = 10;

if (autoRotate) {

    let animationName = rotateSpeed > 0 ? "spin" : "spinRevert";

    ospin.style.animation = `${animationName} ${Math.abs(

    rotateSpeed

    )}s infinite linear`;

}

carousel.onpointerdown = function(e) {

    clearInterval(odrag.timer);

    e = e || window.event;

    let sX = e.clientX,

    sY = e.clientY;

    this.onpointermove = function(e) {

        e = e || window.event;

        let nX = e.clientX,

        nY = e.clientY;

        desX = nX - sX;

        desY = nY - sY;

        tX += desX * 0.1;

        tY += desY * 0.1;

        applyTranform(odrag);

        sX = nX;

        sY = nY;

    };

    this.onpointerup = function(e) {

        odrag.timer = setInterval(function() {

            desX *= 0.95;

            desY *= 0.95;

            tX += desX * 0.1;

            tY += desY * 0.1;

            applyTranform(odrag);

            playSpin(false);

            if (Math.abs(desX) < 0.5 && Math.abs(desY) < 0.5) {

                clearInterval(odrag.timer);

                playSpin(true);

            }

        }, 17);

        this.onpointermove = this.onpointerup = null;

    };

    return false;

};{codeBox}


Где:

  • radius - Радиус карусели
  • autoRotate - Автоматическое вращение (true / false)
  • rotateSpeed - Скорость вращения
  • imgWidth - Ширина фотографии
  • imgHeight - Высота фотографии

Чтобы карусель вращалась зажатием и движением мыши в любом месте документа, а не только в ее контейнере, нужно заменить carousel.onpointerdown = function(e) {...} на  document.onpointerdown = function(e) {...}

Если в карусели не используются ссылки, а только фотографии, то:

  • В HTML убираем ссылки
  • В CSS удаляем класс #drag-container img и заменяем #drag-container a на #drag-container img
  • В JS заменяем let aImg = ospin.getElementsByTagName("a"); на let aImg = ospin.getElementsByTagName("img");

У автора сделано одновременно оба варианта (с ссылкой и без), но в этом случае происходит конфликт в Firefox

Видео, которое также присутствует в оригинале, я удалил за ненадобностью, как и фоновую музыку.

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

document.onmousewheel = function(e) {

    e = e || window.event;

    let d = e.wheelDelta / 20 || -e.detail;

    radius += d;

    init(1);

};{codeBox} 



TM

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

Новые Старые