Прницип работы данной карусели заключается в том, что все изображения в ней равномерно размещаются по кругу:
А далее происходит ее движение в одну или другую сторону
Примеры:
3 фотографии:
6 фотографий:
10 фотографий:
10 фотографий с промежутком 20px:
12 фотографий с промежутком 20px и скрытыми задними:
Установка:
HTML:
1 2 3 4 5 6 7 8 9 10 11 12 |
<div class="carousel-3d"> <figure> <div><a href="#any"><img src="photo-1.jpg" alt=""/></a></div> <div><a href="#any"><img src="photo-2.jpg" alt=""/></a></div> ... <div><a href="#any"><img src="photo-10.jpg" alt=""/></a></div> </figure> <nav> <button class="nav prev">Назад</button> <button class="nav next">Вперед</button> </nav> </div> |
Для добавления промежутков между фотографиями для блока карусели используется атрибут data-gap, например:
<div class="carousel-3d" data-gap="20">
(расстояние 20 пикселей)
Чтобы скрыть тыловые фотографии используется атрибут data-bfc, например:
<div class="carousel-3d" data-bfc>
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 |
.carousel-3d { padding: 20px; -webkit-perspective: 500px; perspective: 500px; display: flex; flex-direction: column; align-items: center; overflow: hidden; } .carousel-3d > * { flex: 0 0 auto; } .carousel-3d figure { margin: 0; width: 50%; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; transition: -webkit-transform 0.5s; transition: transform 0.5s; transition: transform 0.5s, -webkit-transform 0.5s; } .carousel-3d figure img, .carousel-3d figure div { width: 100%; box-sizing: border-box; padding: 0; } .carousel-3d figure img { user-select: none; } .carousel-3d figure div:not(:first-of-type), .carousel-3d figure img:not(:first-of-type) { position: absolute; left: 0; top: 0; } .carousel-3d nav { display: flex; justify-content: center; margin: 20px 0 0; } .carousel-3d nav button { flex: 0 0 auto; margin: 0 5px; cursor: pointer; color: #337AB7; background: #BFE2FF; border: 1px solid #337AB7; padding: 5px 10px; font-weight: bold; transition: all .3s ease; } .carousel-3d nav button:hover { color: #FFF; background: #337AB7; } |
JavaScript:
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
window.addEventListener("load", () => { var carousels = document.querySelectorAll(".carousel-3d"); for (var i = 0; i < carousels.length; i++) { carousel(carousels[i]); } }); function carousel(root) { var figure = root.querySelector("figure"), nav = root.querySelector("nav"), images = figure.children, n = images.length, gap = root.dataset.gap || 0, bfc = "bfc" in root.dataset, theta = 2 * Math.PI / n, currImage = 0; setupCarousel(n, parseFloat(getComputedStyle(images[0]).width)); window.addEventListener("resize", () => { setupCarousel(n, parseFloat(getComputedStyle(images[0]).width)); }); setupNavigation(); function setupCarousel(n, s) { var apothem = s / (2 * Math.tan(Math.PI / n)); figure.style.transformOrigin = `50% 50% ${-apothem}px`; for (var i = 0; i < n; i++) images[i].style.padding = `0 ${gap}px`; for (i = 0; i < n; i++) { images[i].style.transformOrigin = `50% 50% ${-apothem}px`; images[i].style.transform = `rotateY(${i * theta}rad)`; } if (bfc) for (i = 0; i < n; i++) images[i].style.backfaceVisibility = "hidden"; rotateCarousel(currImage); } function setupNavigation() { nav.addEventListener("click", onClick, true); function onClick(e) { e.stopPropagation(); var t = e.target; if (t.tagName.toUpperCase() != "BUTTON") return; if (t.classList.contains("next")) { currImage++; } else { currImage--; } rotateCarousel(currImage); } } function rotateCarousel(imageIndex) { figure.style.transform = `rotateY(${imageIndex * -theta}rad)`; } var xClick; var mouseDown; /* Смена слайдов мышкой */ figure.onmousedown = (event) => { xClick = event.pageX; mouseDown = true; }; figure.onmouseup = (event) => { mouseDown = false; }; figure.onmousemove = (event) => { if (mouseDown) { var xMove = event.pageX; if (Math.floor(xClick - xMove) > 5) { currImage++; rotateCarousel(currImage); mouseDown = false; } else if (Math.floor(xClick - xMove) < -5) { currImage--; rotateCarousel(currImage); mouseDown = false; } } }; /* Смена слайдов пальцем */ figure.ontouchstart = (event) => { xClick = event.changedTouches[0].pageX; mouseDown = true; }; figure.ontouchend = (event) => { mouseDown = false; }; figure.ontouchmove = (event) => { if (mouseDown) { var xMove = event.changedTouches[0].pageX; if (Math.floor(xClick - xMove) > 5) { currImage++; rotateCarousel(currImage); mouseDown = false; } else if (Math.floor(xClick - xMove) < -5) { currImage--; rotateCarousel(currImage); mouseDown = false; } } }; } |
Автор карусели и оригинальная статья: Giulio Mainardi
Я добавил смену слайдов пальцем или мышкой и обернул фотографии в тег <div></div>
для больших возможностей, например, для добавления ссылки или текста на изображение.
Автоматическое вращение карусели:
Для того, чтобы карусель вращалась и останавливалась при заходе курсора, ниже функции rotateCarousel
добавляем:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
let cur; function showcur() { cur = setInterval(function() { currImage++; rotateCarousel(currImage); }, 2000); } function clearcur() { clearInterval(cur); } root.onmouseover = function() { clearcur(); } root.onmouseout = function() { showcur(); } showcur(); |
Пока был html и css вникал в код. Когда же пошёл js... Сначала ничего не хотело работать, начал паниковать, читать комменты. Потом пошёл перепроверять код: 1 - я забыл вообще подключить js файл, 2 - забыл поменять название класса в js-коде (хотя я его менял, хз). Радости не было предела когда всё заработало. Теперь меня интересует одно - у вас есть наверху в навигационной панели кнопка "услуги", когда на неё наводишь всплывает список. Подскажите пожалуйста как сделать так же))
супер карусель спасибо большое))
А вот есть у кого возможность, подсказать как написать код для кружков (подсчет картинок в карусели+переход по ним), например как https://l-pak.ru/
В принципе можно, но это будет именно написать, а не подсказать 🙂
А вообще это изобретение велосипеда уже, намного проще использовать готовые библиотеки для этого, как в случае с этим сайтом, где используется swiper
Подскажите как можно сделать в коде JS что бы на пк можно было мышкой листать слайдер, а на телефоне пальцем? Может кто подсказать?
Попробуйте по аналогии с Смена слайдов мышкой или пальцем на Bootstrap 3
Непонятно как соединить с этой каруселью, карусель сама работает, а вот что где менять для работы от мышки и пальца для этой карусели без понятия, в JS не разбираюсь, может кто подскажет?
Через пару дней скину код, после НГ аврал тут целый по работе 🙂
Благодарю, буду ждать с нетерпением! :))
Обновил код, проверьте
Благодарю! Все работает!
Спасибо. Интересно. Но я по кодам полный чайник. Можете показать куда именно вставлять коды. и где должны быть размещены картинки что бы они считывались. Я учитель физкультуры и понадобилось поработать с сайтом
Ну я так даже не подскажу...
От сайта все зависит, что куда и как там...
Здравствуйте,данный код не работает в таплинке(
Ну тут 2 варианта, либо вы что то не так делаете, либо таплинк это не позволяет.
Не забывайте, что там вы не владелец сайта со всеми правами, а всего лишь пользователь ресурса.
возможно(
Добрый день. у меня фотографии разных размеров (имею ввиду часть 16:9, другая к примеру 4:3, некоторые 9:16 (вертикальные)), не подскажите пожалуйста как сделать что бы они все были строго по центру, и не перекрывали кнопки навигации?
Добавить:
И первую фотку ставить самую высокую.
Или высоту указывать не 100%, а конкретную.
Еще можно указать конкретную высоту для фоток и обрезать через object-fit
Подскажите, как сделать чтобы карусель останавливалась при наведении на центральный слайд мыши?
И чтобы, при убирании со слайда курсора мыши, карусель возобновляла вращение
Добавил код в заметку
Спасибо, Александр! Признателен за Ваш труд
Шикарная каруселька!!! Долго такую искал... Только маленькое но.... Что то под safari совсем не хочет работать. Два дня голову ломаю. https://borodinfoto.ru/useful.html
help!!!
А как кнопки назад и вперёд поставить слева и справа а не внизу?
Вместо:
Ставим:
Огромное спасибо
Приветствую! Не пробовал повернуть карусель, сделать ее не горизонтальной а вертикальной, и прокручивалась вверх или вниз? Или это реализовано и я слепой? :))
Подскажите, как сделать чтобы карусель начинала показ не с первой картинки. Если указать currImage то получается автопрокрутка до элемента, можно сделать без прокрутки, чтобы сразу показывался указанный элемент.
А не проще ли поставить нужную картинку первой? 🙂
У меня идет генерация элементов в зависимости от полученного контента. И если я нахожусь на n-ой позиции и произошло обновление то происходит прокрутка с 0 эл. до n элемента на котором я находился.
Ну это уже смотреть надо и пробовать.
У автора этой карусели не написано?
Там отличная статья с примерами и т.д.
Если правильно понял, то убираем из стилей
В скриптах ставим:
И добавляем внимацию поворота по клику ( function onClick(e) )
Сделал карусель ((( а на мобильном не работает центр вращения передняя картинка
Замечательная штука. Подскажите, а как сделать зум картинки при клике? пытался посмотреть в исходниках https://codepen.io/dudleystorey/pen/sntEk но к сожалению здесь было переделано в div'ы, так что не получается переделать, знаний не хватает((((
Так я тут и менял как раз для зума такого 🙂
Подключайте любую модальную галерею, например, fancybox и прописывайте ссылку.
Итого будет:
Для других гелерей соотв. как то иначае
fancybox это конечно крутая штука, но слишком нагружать тоже не очень хочется, поэтому я хотел чисто что бы зум был, просто при клике картинка на 15-20% увеличивалась. Здесь 3D Gallery II человек делает через css и меняет класс у картинки в целом c current на focus, соответственно она увеличивается в зависимости от css, а подключать отдельную галерею, имею такую крутую карусель не хотелось бы. плюс у вас в коде каждой фотке уже проставлена ссылка как #any, вот я и думал что возможно можно сделать так же, через изменения стиля и чисто небольшой зум) а не целая галерея)) в любом случае спасибо, я еще покумекаю как это лучше провернуть, и если не получится, тогда буду цеплять целую галерею (что не оч хотелось бы(( )
Ну там другой человек делает и это другое решение.
Я, например, не понимаю зачем увеличивать фото на 10-20% и мое решение иное.
То что вы сделали, это действительно круто, и большое спасибо)))
эту карусель я использую для блока с отзывами из инстаграма. там все фото это скрины с телефона (пока добавил ~50, буду менять каждый месяц наверное, так то их больше), они все вертикальные, а делать слишком большим блок не хочется, и сделал его в 330px, из за этого не на всех фотографиях видно что пишут люди, в итоге рационально использование зумирования при клике, не намного, но так что бы человек смог прочитать отзыв реального человека. в итоге не додумался как сделать, и подключил как вы и предлагали FANCYBOX )))
подскажите, как можно изменить размер карусели? сделать ее больше?
И правда, так и напрашивается (даже в этом логическое завершение карусели) вместо кнопок применить боковые фото для навигации. Все подобные карусели с кнопками. А это было бы ново... Но, код просто ужасно запутанный, чтобы как-то это сделать. Я бы с удовольствием применила с таким вот ноу-хау !
Спасибо! Выручили новичка) Просто, удобно и адаптивно. А не подскажите, как реализовать прокрутку при клике на фото, а не по кнопке? Теоретически я понимаю, что нужно получить картинки в переменную, навесить на них прослушивальщик, потом, наверное, запустить rotateCarousel, что-то передав функции в аргументе, но практически не могу пока сообразить, как это состыковать с исходным кодом.
Да нет, зачем так сложно.
Определить фотку что в центре и на боковые повесить currImage++ и currImage--
А если нужно просто поворачивать карусель по клику по ней, то еще проще, повесьте событие не на кнопку а на нее
Очень классная карусель. А как ее сделать автоматической, чтобы сама поворачивалась?
Попробуйте ниже функции
добавить:
2000 - это 2 секунды
Крутится как вентилятор