Прницип работы данной карусели заключается в том, что все изображения в ней равномерно размещаются по кругу:
А далее происходит ее движение в одну или другую сторону
Примеры:
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(); |













и подключаем jQuery
CSS
[code].cube_cont {position:absolute;top:0; left:0; width:50vw; height:var(--cube-h);perspective: 2000px;background:#069; overflow:hidden;}
.cube {position: relative; top:150px; left:195px; width: 330px; font-size:50px;
transform-style: preserve-3d; transform: rotateX(0deg) rotateY(0deg);transition:transform .5s ease;}
.face {position: absolute; width: 330px; height: 250px; display: flex; justify-content: center; align-items: center;
background: linear-gradient(to left,rgba(255, 255, 255, 0.8),rgba(255, 255, 255, 0.9));
text-shadow: 0 0 1px #0C548D; border: 1px solid rgba(255, 255, 255, 0.9);
left: -7px; top: -69px; transition:opacity 1s ease;
}
:root {--main-sz:330px; --num-sz:0; --cube-h:450px;--poz:-100%;}
.nav{
position:absolute;
display:block;
top:calc(var(--cube-h) - 50px);
width:calc(var(--num-sz) * 30px);
height:30px;
left: calc(25vw - calc(var(--num-sz) * 30px));}
.pg_select{
position:relative;width:30px; height:30px; display:inline-block;
background: radial-gradient(circle,rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0) 38%, rgba(255, 255, 255, 1) 46%, rgba(0, 0, 0, 0) 52%, rgba(0, 0, 0, 0) 100%);background-size:30px 30px;}
.pg_select:hover{transform:scale(1.1,1.1);}
.pg_active{background: radial-gradient(circle,rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) 27%, rgba(0, 0, 0, 0) 31%, rgba(0, 0, 0, 0) 43%, rgba(255, 255, 255, 1) 49%, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, 0) 100%);}[/code]
HTML
[code]<div class="cube_cont"><div class="cube">
<div class="face pg1">Page1</div>
<div class="face pg2">Page2</div>
<div class="face pg3">Page3</div>
<div class="face pg4">Page4</div>
<div class="face pg5">Page5</div>
<div class="face pg6">Page6</div>
</div></div><div class="nav"></div> [/code]
jS
[code]var span="";var pg=document.querySelectorAll('.face');document.documentElement.style.setProperty('--num-sz',''+pg.length+'');
pg.forEach((element, index) => {
angl=index*360/pg.length*-1;newSpan=document.createElement('span');
span+="<span class='pg_select' sel="+(index+1)+" ang="+angl+"></span>";
$(element).css('transform', 'rotateY('+angl+'deg) translateZ(var(--main-sz))');
$('.nav').html(span);
$('.pg_select').on('click',function(){
$('.face').css('opacity','.3'); frontface='.pg'+$(this).attr('sel');$(frontface).css('opacity','1');
curpoint=$('.pg_active').attr('sel');newpoint=$(this).attr('sel');
if(curpoint=='6' && newpoint=='1'){
console.log(curpoint,newpoint);
$('.cube').css('transform', 'rotateY(360deg)');
$('.cube').on('transitionend', () => {
if(curpoint=='6' && newpoint=='1'){
$('.cube').css('transition','none');
$('.cube').css('transform', 'rotateY(0deg)');
$('.cube').on('transitionend', () => {
$('.cube').css('transition','transform .5s ease');
});}});
}
else{$('.cube').css('transform', 'rotateY('+$(this).attr('ang')*-1+'deg)');}
$('.pg_select').removeClass('pg_active');$(this).addClass('pg_active');
});});[/code]
Много кода... В моей разработке тот-же функционал , но в 4 раза меньше кода.
Привет! Спасибо, всё работает и всё круто. Есть вопрос, а есть ли возможность в этой карусели, прописать функционал, чтобы при клике по фотографии она увеличивалась на заданную величину?
Оно так и задумано, ссылку только поставьте не
[code]<a href="#any"><img src="photo-1.jpg" alt=""/></a>[/code]
а
[code]<a class="mymodal" href="photo-1.jpg"><img src="photo-1.jpg" alt=""/></a>[/code]
И соотв. нужно будет подключить какие то модальные окна для галереи
Спасибо! У Вас очень крутой ресурс! Так держать!
добрый день!
Куда мне вставить коды HTML, CSS и JavaScript в программе Xara Designer Pro X.
Если Вам знакома эта программа, то не откажите в пояснении.. буду благодарен!
Спасибо!
Xara Designer Pro X - это же графическая программа?
Могу конечно ошибаться, но это абсолютно разные вещи, т.е. повернуть фото и двигать туда-сюда на CSS не имеет ничего общего с таким эффектом при создании GIF или видео в графических редакторах.
Пока был html и css вникал в код. Когда же пошёл js... Сначала ничего не хотело работать, начал паниковать, читать комменты. Потом пошёл перепроверять код: 1 - я забыл вообще подключить js файл, 2 - забыл поменять название класса в js-коде (хотя я его менял, хз). Радости не было предела когда всё заработало. Теперь меня интересует одно - у вас есть наверху в навигационной панели кнопка "услуги", когда на неё наводишь всплывает список. Подскажите пожалуйста как сделать так же))
супер карусель спасибо большое))
А вот есть у кого возможность, подсказать как написать код для кружков (подсчет картинок в карусели+переход по ним), например как https://l-pak.ru/
В принципе можно, но это будет именно написать, а не подсказать 🙂
А вообще это изобретение велосипеда уже, намного проще использовать готовые библиотеки для этого, как в случае с этим сайтом, где используется [i]swiper[/i]
Подскажите как можно сделать в коде JS что бы на пк можно было мышкой листать слайдер, а на телефоне пальцем? Может кто подсказать?
Попробуйте по аналогии с [url="https://atuin.ru/blog/smena-slajdov-myshkoj-ili-palcem-na-bootstrap-3/"]Смена слайдов мышкой или пальцем на Bootstrap 3[/url]
Непонятно как соединить с этой каруселью, карусель сама работает, а вот что где менять для работы от мышки и пальца для этой карусели без понятия, в JS не разбираюсь, может кто подскажет?
Через пару дней скину код, после НГ аврал тут целый по работе 🙂
Благодарю, буду ждать с нетерпением! :))
Обновил код, проверьте
Благодарю! Все работает!
Спасибо. Интересно. Но я по кодам полный чайник. Можете показать куда именно вставлять коды. и где должны быть размещены картинки что бы они считывались. Я учитель физкультуры и понадобилось поработать с сайтом
Ну я так даже не подскажу...
От сайта все зависит, что куда и как там...
Здравствуйте,данный код не работает в таплинке(
Ну тут 2 варианта, либо вы что то не так делаете, либо таплинк это не позволяет.
Не забывайте, что там вы не владелец сайта со всеми правами, а всего лишь пользователь ресурса.
возможно(
Добрый день. у меня фотографии разных размеров (имею ввиду часть 16:9, другая к примеру 4:3, некоторые 9:16 (вертикальные)), не подскажите пожалуйста как сделать что бы они все были строго по центру, и не перекрывали кнопки навигации?
Добавить:
[code].carousel-3d figure div {
display: flex;
height: 100%;
align-items: center;
}[/code]
И первую фотку ставить самую высокую.
Или высоту указывать не 100%, а конкретную.
Еще можно указать конкретную высоту для фоток и обрезать через [url="https://developer.mozilla.org/ru/docs/Web/CSS/object-fit"]object-fit[/url]
Подскажите, как сделать чтобы карусель останавливалась при наведении на центральный слайд мыши?
И чтобы, при убирании со слайда курсора мыши, карусель возобновляла вращение
Добавил код в заметку
Спасибо, Александр! Признателен за Ваш труд
Шикарная каруселька!!! Долго такую искал... Только маленькое но.... Что то под safari совсем не хочет работать. Два дня голову ломаю. https://borodinfoto.ru/useful.html
help!!!
А как кнопки назад и вперёд поставить слева и справа а не внизу?
Вместо:
[code].carousel-3d nav
.carousel-3d nav button[/code]
Ставим:
[code].carousel-3d nav button {
position: absolute;
z-index: 10;
top: 50%;
left: 10px;
cursor: pointer;
color: #337AB7;
background: #BFE2FF;
border: 1px solid #337AB7;
padding: 5px 10px;
font-weight: bold;
transition: all .3s ease;
}
.carousel-3d nav button.next {
left: auto;
right: 10px;
}[/code]
Огромное спасибо
Приветствую! Не пробовал повернуть карусель, сделать ее не горизонтальной а вертикальной, и прокручивалась вверх или вниз? Или это реализовано и я слепой? :))
Подскажите, как сделать чтобы карусель начинала показ не с первой картинки. Если указать currImage то получается автопрокрутка до элемента, можно сделать без прокрутки, чтобы сразу показывался указанный элемент.
А не проще ли поставить нужную картинку первой? 🙂
У меня идет генерация элементов в зависимости от полученного контента. И если я нахожусь на n-ой позиции и произошло обновление то происходит прокрутка с 0 эл. до n элемента на котором я находился.
Ну это уже смотреть надо и пробовать.
У автора этой карусели не написано?
Там отличная статья с примерами и т.д.
Если правильно понял, то убираем из стилей
[code]transition: -webkit-transform 0.5s;
transition: transform 0.5s;
transition: transform 0.5s, -webkit-transform 0.5s;[/code]
В скриптах ставим:
[code]currImage = 5;[/code]
И добавляем внимацию поворота по клику ( [b]function onClick(e)[/b] )
[code]document.querySelector(".carousel-3d figure").style.transition = "transform 0.5s";[/code]
Сделал карусель ((( а на мобильном не работает центр вращения передняя картинка
Замечательная штука. Подскажите, а как сделать зум картинки при клике? пытался посмотреть в исходниках https://codepen.io/dudleystorey/pen/sntEk но к сожалению здесь было переделано в div'ы, так что не получается переделать, знаний не хватает((((
Так я тут и менял как раз для зума такого 🙂
Подключайте любую модальную галерею, например, [url="https://atuin.ru/blog/fancybox-3-s-temoj-oformleniya/"]fancybox [/url] и прописывайте ссылку.
Итого будет:
[code]<div><a data-fancybox="gallery" href="/photo-big-1.jpg"><img src="photo-1.jpg" alt=""/></a></div>[/code]
Для других гелерей соотв. как то иначае
[url="https://atuin.ru/blog/fancybox-3-s-temoj-oformleniya/"]fancybox[/url] это конечно крутая штука, но слишком нагружать тоже не очень хочется, поэтому я хотел чисто что бы зум был, просто при клике картинка на 15-20% увеличивалась. Здесь [url="https://codepen.io/dudleystorey/pen/sntEk"]3D Gallery II[/url] человек делает через css и меняет класс у картинки в целом c current на focus, соответственно она увеличивается в зависимости от css, а подключать отдельную галерею, имею такую крутую карусель не хотелось бы. плюс у вас в коде каждой фотке уже проставлена ссылка как #any, вот я и думал что возможно можно сделать так же, через изменения стиля и чисто небольшой зум) а не целая галерея)) в любом случае спасибо, я еще покумекаю как это лучше провернуть, и если не получится, тогда буду цеплять целую галерею (что не оч хотелось бы(( )
Ну там другой человек делает и это другое решение.
Я, например, не понимаю зачем увеличивать фото на 10-20% и мое решение иное.
То что вы сделали, это действительно круто, и большое спасибо)))
эту карусель я использую для блока с отзывами из инстаграма. там все фото это скрины с телефона (пока добавил ~50, буду менять каждый месяц наверное, так то их больше), они все вертикальные, а делать слишком большим блок не хочется, и сделал его в 330px, из за этого не на всех фотографиях видно что пишут люди, в итоге рационально использование зумирования при клике, не намного, но так что бы человек смог прочитать отзыв реального человека. в итоге не додумался как сделать, и подключил как вы и предлагали [url="https://atuin.ru/blog/fancybox-3-s-temoj-oformleniya/"]FANCYBOX [/url] )))
подскажите, как можно изменить размер карусели? сделать ее больше?
[code].carousel-3d figure {
width: 50%;
}[/code]
И правда, так и напрашивается (даже в этом логическое завершение карусели) вместо кнопок применить боковые фото для навигации. Все подобные карусели с кнопками. А это было бы ново... Но, код просто ужасно запутанный, чтобы как-то это сделать. Я бы с удовольствием применила с таким вот ноу-хау !
Спасибо! Выручили новичка) Просто, удобно и адаптивно. А не подскажите, как реализовать прокрутку при клике на фото, а не по кнопке? Теоретически я понимаю, что нужно получить картинки в переменную, навесить на них прослушивальщик, потом, наверное, запустить rotateCarousel, что-то передав функции в аргументе, но практически не могу пока сообразить, как это состыковать с исходным кодом.
Да нет, зачем так сложно.
Определить фотку что в центре и на боковые повесить [i]currImage++[/i] и [i]currImage--[/i]
А если нужно просто поворачивать карусель по клику по ней, то еще проще, повесьте событие не на кнопку а на нее
Очень классная карусель. А как ее сделать автоматической, чтобы сама поворачивалась?
Попробуйте ниже функции
[code]function rotateCarousel(imageIndex) {
figure.style.transform = `rotateY(${imageIndex * -theta}rad)`;
}[/code]
добавить:
[code]window.setInterval(function() {
currImage++;
rotateCarousel(currImage);
}, 2000);[/code]
2000 - это 2 секунды
Крутится как вентилятор