- Любое количество фотографий.
- Произвольный радиус.
- Автоматическое движение с заданной скоростью.
- Отсутствие дополнительных библиотек.
- Всего 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}