Более подробно о настройках и вариантах карусели описано внизу страницы.
Пример:
Увеличение фотографий в модальных окнах в данное решение не входит и используется только для примера.
HTML:
Количество фотографий может быть любое.
1 2 3 4 5 6 7 8 9 10 11 |
<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> |
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
#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 #BFE2FF; } #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); } } |
JS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
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; }; |
Где:
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
Видео, которое также присутствует в оригинале, я удалил за ненадобностью, как и фоновую музыку.
Если нужно изменять радиус карусели колесом мыши, добавьте вниз скрипта:
1 2 3 4 5 6 |
document.onmousewheel = function(e) { e = e || window.event; let d = e.wheelDelta / 20 || -e.detail; radius += d; init(1); }; |
3D Carousel на github
Отличная карусель! Заработала сразу. Хорошо объяснена. Легко настраивается. Пока только не смог изменить первоначальный вертикальный наклон, чтобы надпись на дне с самого начала просматривалась полностью. Надеюсь на подсказку. Очередная "копеечка" за мной. Спасибо!
Ура! Нашёл. Параметр "transform: rotateX(-10deg)"
подскажите, возможно ли сделать не ссылками а указать путь к примеру data/gallery/image/ чтоб оттуда уже подгружались фотографии сами в разнобой,i = i || " "; не пойдет так как у меня фотографии создаются по времени timestamp() .
А как у нас совпадет timestamp, который в именах файлов (создал сервер) с тем, который создался в браузере на JS ?
На PHP сразу генерируйте HTML с нуждными фото и все.
Добрый день, в Firefox при увеличении радиуса, качество картинки резко падает, как будто он увеличивает уменьшенный в начале js img. Chorme и Yandex отображает нормально. Не знаете как починить?
Тут я не подскажу, так не должно быть, по идеи.
Если картинка 1000 точек и уменьшена до 200, то при увеличении до 500, как она может остаться 200...
Это уже тараканы браузера какие то.
Добрый день очень понравилось только вот установить не смог вот как встаёт Чатик ФМ
Посмотрите пути к фотографиям
Добрый день подскажите, можно ли сделать сразу две карусели на странице?
В этом варианте нет, нужно менять JS
Доброго времени суток! Могу ли использовать карусель у себя в проекте?
Доброго времени суток и спасибо за контент! Как выпутаться с этим слайдером из ситуации что он разворачивается сразу. В том плане в середине страницы не будет эффекта раскидывания карт. Задержку ставить не понятно когда пользователь долистает. Это было бы идеальным решением, и возможно простым, но я до этого не допетрю)
Удаляем
И в самый низ скрипта добавляем:
Блин одно дело с html css ковыряться, но такое понимать это добротные мозги нужны) Сайт пушка, за помощь респект, увижу рекламу с недвижкой кликну)
Добрый вечер! Как как изменить радиус карусели для мобильной версии(радиус прописан в JS
Ниже переменных, где задается радиус и размеры изображений, можно добавить:
Спасибо Вам огромное! Всё работает!!!
Доброго дня. Я так понимаю часть слайдера после нажатия с паузой и т.д сделана отдельно как то. Фото просто на черном экране увеличивается.
Фото и должно так открываться.
Тут для примера я подключил свою fancybox, у вас может использоваться другой лайтбокс или открываться по ссылкам не фото, а страницы.
Спасибо понятно
у меня не показывает изображения, в чём может быть проблема?
Смотреть нужно, как я угодаю почему 🙂
Можно с Вами по этому вопросу как-то связаться?
Напишите в ВК или Телеграм завтра.
Контакты
Прикольно!
Шикарная карусель! Как всегда контент топовый у тебя 🙂