Tutorial

3D Carousel

Aspect-Ratio: 4/3

Aspect-Ratio: 1

HTML

Download HTML

<div class="outer-gallery"><div id="gallery1" class="gallery3D"></div></div>
<div class="outer-gallery"><div id="gallery2" class="gallery3D"></div></div>
Select

CSS

.outer-gallery { width: 100%; max-width: 1200px; margin: 50px auto 50px auto; overflow: hidden; } .gallery3D { display: flex; transform-style: preserve-3d; position: relative; left: -29.7%; } .img-wrapper { position: absolute; width: 41.9%; min-width: 41.9%; transform-style: preserve-3d; backface-visibility: hidden; pointer-events: auto; } .transition .img-wrapper { transition: transform 0.4s, margin 0.4s, left 0.4s; } .img-wrapper img { width: 100%; height: auto; display: block; object-fit: cover; object-position: center; pointer-events: auto; } .img-wrapper:nth-child(2), .img-wrapper:nth-child(4) { cursor: pointer; } /* responsive Korrektur, gegebenenfalls anpassen */ @media only screen and (max-width: 1000px) { .img-wrapper { width: 43.6%; min-width: 43.6%; } .gallery3D { left:-32.5%; } }
Select

jQuery - für WordPress geeignet

inviduelles HTML anlegen. (unter dem HTML)

<script> (function ($) { class Gallery3D { constructor(id, path, pics, autoplay, duration, aspectRatio) { this.id = id; this.path = path; this.pics = pics; this.autoplay = autoplay; this.duration = duration; this.aspectRatio = aspectRatio; } gallery() { const id = this.id; const pics3D = this.pics; const path = this.path; var autoplay = this.autoplay; // true or false const duration = this.duration; // Slider Duration const aspectRatio = this.aspectRatio; const innerFactor = 0.611; const outerFactor = 0.790; var isRunning = false; var startTime; var outerPersWidth, marginsOuter, marginsInner, absoluteLeft = []; var allowedToClick = true; let image3D = id + " .img-wrapper"; function wrapperHTML(src, id) { return ` <div class="img-wrapper" data-id="${id}"> <img src="${path + src}"> </div>`; } var startHTML = wrapperHTML(pics3D[pics3D.length - 1], pics3D.length - 1); for (let i = 0; i < 4; i++) { startHTML += wrapperHTML(pics3D[i], i); } $(id).html(startHTML); $(id + " img").css("aspect-ratio", aspectRatio); let imagesLoaded = 0; $(image3D + " img").on("load", function () { imagesLoaded++; if (imagesLoaded == $(image3D).length) { setStart(); setTimeout(function () { $(id).addClass("transition"); }, 10); if (autoplay) { loop(); } } }); function setStart() { $(id).parent().css("height", ""); $(id).parent().css("height", $(image3D).eq(2).height()); $(image3D).css({"left": "", "width": "", "position": "relative"}); var originWidth = $(image3D).eq(0).width() / $(id).width(); var width = $(image3D).eq(0).width(); const factors = [outerFactor, innerFactor, 1, innerFactor, outerFactor]; let widthSum = 0; absoluteLeft = []; $(image3D).each(function (index) { widthSum += $(this).width() * factors[index]; absoluteLeft.push(widthSum); }); $(image3D).css("position", "absolute"); $(image3D).each(function (index) { let w = $(id).width() * originWidth; if (index > 0) { $(this).css({left: absoluteLeft[index - 1], width: w}); } else { $(this).css({left: "0px", width: w}); } }); marginsOuter = (width - (width * outerFactor)) / 2; marginsInner = (width - (width * innerFactor)) / 2; $(image3D).eq(0).css({marginLeft: -marginsOuter, marginRight: -marginsOuter, transform: "perspective(800px) rotateY(30deg) scale(0.8)"}); $(image3D).eq(1).css({marginLeft: -marginsInner, marginRight: -marginsInner, transform: "perspective(800px) rotateY(30deg) scale(0.8)"}); $(image3D).eq(2).css({marginLeft: "", marginRight: "", transform: "perspective(800px) rotateY(0deg) scale(1)"}); $(image3D).eq(3).css({marginLeft: -marginsInner, marginRight: -marginsInner, transform: "perspective(800px) rotateY(-30deg) scale(0.8)"}); $(image3D).eq(4).css({marginLeft: -marginsOuter, marginRight: -marginsOuter, transform: "perspective(800px) rotateY(-30deg) scale(0.8)"}); } function leftSlides(index, factor) { let currStyle = $(image3D).eq(index).attr("style"); let leftDiff = $(image3D).eq(index).width() * factor; let curLeft = parseInt($(image3D).eq(index + 1).css("left")); let newLeft = curLeft - leftDiff; $(image3D).eq(index + 1).attr("style", currStyle).css("left", newLeft); } function rightSlides(index, factor) { let currStyle = $(image3D).eq(index + 1).attr("style"); let curLeft = parseInt($(image3D).eq(index + 1).css("left")); $(image3D).eq(index).attr("style", currStyle).css("left", curLeft); } $(document).on('click', id + ' .img-wrapper:nth-child(2)', function () { if (!allowedToClick) { return; } isRunning = true; startTime = Date.now(); autoplay = false; allowedToClick = false; let rightID = $(image3D).eq(4).data("id") + 1; if (rightID >= pics3D.length) rightID = 0; leftSlides(4, outerFactor); leftSlides(3, innerFactor); leftSlides(2, 1); leftSlides(1, innerFactor); leftSlides(0, outerFactor); setTimeout(function () { $(image3D).eq(0).remove(); $(id).append(wrapperHTML(pics3D[rightID], rightID)); $(image3D).eq(4).css({ marginLeft: -marginsOuter, marginRight: -marginsOuter, transform: "perspective(800px) rotateY(-30deg) scale(0.8)", left: absoluteLeft[3] }); $(id + " img").eq(4).css("aspect-ratio", aspectRatio); allowedToClick = true; isRunning = false; }, 400); }); $(document).on('click', id + ' .img-wrapper:nth-child(4)', function () { if (!allowedToClick) { return; } isRunning = true; startTime = Date.now(); autoplay = false; allowedToClick = false; let leftID = $(image3D).eq(0).data("id") - 1; if (leftID < 0) leftID = pics3D.length - 1; rightSlides(0, outerFactor); rightSlides(1, 1); rightSlides(2, innerFactor); rightSlides(3, outerFactor); rightSlides(4, outerFactor); setTimeout(function () { $(image3D).eq(4).remove(); $(id).prepend(wrapperHTML(pics3D[leftID], leftID)); $(image3D).eq(0).css({ marginLeft: -marginsOuter, marginRight: -marginsOuter, transform: "perspective(800px) rotateY(30deg) scale(0.8)", left: 0 }); $(id + " img").eq(0).css("aspect-ratio", aspectRatio); allowedToClick = true; isRunning = false; }, 400); }); function loop() { setTimeout(function () { if (autoplay) { $(id + ' .img-wrapper:nth-child(2)').trigger("click"); autoplay = true; loop(); } }, duration); } var single = true; $(window).resize(function () { if (!isRunning) { setStart(); single = true; } else { if (single) { let elapsed = Date.now() - startTime; single = false; setTimeout(function () { setStart(); single = true; }, 420 - elapsed); } } }); } } window.Gallery3D = Gallery3D; })(jQuery); </script>
Select

Darunter folgendes Script einfügen:

Hier kommen die Anpassungen: (Beispiel mit 2 Galerien, man kann natürlich auch nur eine anlegen) const gallery = new Gallery3D( "ID der Galerie","Pfad zu den Bildern","Bilder (Array)","Autoplay:true or false","Autoplay Duration","Aspect-Ratio");
<script> (function ($) { const picsGallery1 = ["bild1.jpg", "bild2.jpg", "bild3.jpg", "bild4.jpg", "bild5.jpg", "bild6.jpg", "bild7.jpg", "bild8.jpg"]; const gallery = new Gallery3D("#gallery1", "img1/",picsGallery1,true,2000,"4/3"); gallery.gallery(); const picsGallery2 = ["bild9.jpg", "bild10.jpg", "bild11.jpg", "bild12.jpg", "bild13.jpg", "bild14.jpg", "bild15.jpg", "bild16.jpg"]; const gallery2 = new Gallery3D("#gallery2","img2/", picsGallery2,true,1500,"1"); gallery2.gallery(); })(jQuery); </script>
Select

Javascript

Für HTML empfohlen

class Gallery3D { constructor(id, path, pics, autoplay, duration, aspectRatio) { this.id = id; this.path = path; this.pics = pics; this.autoplay = autoplay; this.duration = duration; this.aspectRatio = aspectRatio; } gallery() { const id = this.id; const pics3D = this.pics; const path = this.path; var autoplay = this.autoplay; // true or false const duration = this.duration; // Slider Duration const aspectRatio = this.aspectRatio; const innerFactor = 0.611; const outerFactor = 0.790; var clickIndex; var isRunning = false; var startTime; var outerPersWidth, marginsOuter, marginsInner, absoluteLeft = []; var allowedToClick = true; function wrapperHTML(src, id) { return ` <div class="img-wrapper" data-id="${id}"> <img src="${path + src}"> </div>`; } var startHTML = wrapperHTML(pics3D[pics3D.length - 1], pics3D.length - 1); for (let i = 0; i < 4; i++) { startHTML += wrapperHTML(pics3D[i], i); } document.querySelector(id).innerHTML = startHTML; for (let el of document.querySelectorAll(id + " img")) { el.style.aspectRatio = aspectRatio; } let imagesLoaded = 0; for (let el of pics3D) { var img = new Image(); img.src = path + el; img.onload = function () { imagesLoaded++; if (imagesLoaded === pics3D.length) { setStart(); setTimeout(function () { document.querySelector(id).classList.add("transition"); }, 10); if (autoplay) { loop(); } } }; } function leftClick() { if (!allowedToClick) { return; } isRunning = true; startTime = Date.now(); autoplay = false; allowedToClick = false; let rightID = parseInt(document.querySelectorAll(id + " .img-wrapper")[4].getAttribute("data-id")) + 1; if (rightID >= pics3D.length) { rightID = 0; } leftSlides(4, outerFactor); leftSlides(3, innerFactor); leftSlides(2, 1); leftSlides(1, innerFactor); leftSlides(0, outerFactor); setTimeout(function () { document.querySelectorAll(id + " .img-wrapper")[0].remove(); document.querySelector(id).insertAdjacentHTML('beforeend', '<div class="img-wrapper" data-id="' + rightID + '"><img src="' + path + pics3D[rightID] + '">'); const appendedStyles = document.querySelectorAll(id + " .img-wrapper"); appendedStyles[4].style.marginLeft = -marginsOuter + "px"; appendedStyles[4].style.marginRight = -marginsOuter + "px"; appendedStyles[4].style.transform = "perspective(800px) rotateY(-30deg) scale(0.8)"; appendedStyles[4].style.left = absoluteLeft[3] + "px"; appendedStyles[4].querySelector("img").style.aspectRatio = aspectRatio; allowedToClick = true; isRunning = false; }, 400); } function setStart() { document.querySelector(id).parentElement.style.height = ""; document.querySelector(id).parentElement.style.height = document.querySelectorAll(id + " .img-wrapper")[2].offsetHeight + "px"; let img3D = document.querySelectorAll(id + " .img-wrapper"); for (let el of document.querySelectorAll(id + " .img-wrapper")) { el.style.left = ""; el.style.width = ""; el.style.position = "relative"; } var originWidth = img3D [0].offsetWidth / document.querySelector(id).offsetWidth; var width = img3D [0].offsetWidth; const factors = [outerFactor, innerFactor, 1, innerFactor, outerFactor]; let widthSum = 0; absoluteLeft = []; for (let i = 0; i < img3D.length; i++) { widthSum += img3D [i].offsetWidth * factors[i]; absoluteLeft.push(widthSum); } for (let el of img3D) { el.style.position = "absolute"; } for (let i = 0; i < img3D.length; i++) { let w = document.querySelector(id).offsetWidth * originWidth; if (i > 0) { img3D [i].style.left = absoluteLeft[i - 1] + "px"; img3D [i].style.width = w + "px"; } else { img3D [i].style.left = "0px"; img3D [i].style.width = w + "px"; } } marginsOuter = (width - (width * outerFactor)) / 2; marginsInner = (width - (width * innerFactor)) / 2; img3D [0].style.marginLeft = -marginsOuter + "px"; img3D [0].style.marginRight = -marginsOuter + "px"; img3D [0].style.transform = "perspective(800px) rotateY(30deg) scale(0.8)"; img3D [1].style.marginLeft = -marginsInner + "px"; img3D [1].style.marginRight = -marginsInner + "px"; img3D [1].style.transform = "perspective(800px) rotateY(30deg) scale(0.8)"; img3D [2].style.marginLeft = ""; img3D [2].style.marginRight = ""; img3D [2].style.transform = "perspective(800px) rotateY(0deg) scale(1)"; img3D [3].style.marginLeft = -marginsInner + "px"; img3D [3].style.marginRight = -marginsInner + "px"; img3D [3].style.transform = "perspective(800px) rotateY(-30deg) scale(0.8)"; img3D [4].style.marginLeft = -marginsOuter + "px"; img3D [4].style.marginRight = -marginsOuter + "px"; img3D [4].style.transform = "perspective(800px) rotateY(-30deg) scale(0.8)"; } function leftSlides(index, factor) { const imageElements = document.querySelectorAll(id + " .img-wrapper"); const current = imageElements[index]; const next = imageElements[index + 1]; if (!current || !next) { return; } const currStyle = current.getAttribute('style'); const leftDiff = current.offsetWidth * factor; const curLeft = parseInt(window.getComputedStyle(next).left, 10) || 0; const newLeft = curLeft - leftDiff; next.setAttribute('style', currStyle); next.style.left = `${newLeft}px`; } function rightSlides(index, factor) { const imageElements = document.querySelectorAll(id + ' .img-wrapper'); const current = imageElements[index]; const next = imageElements[index + 1]; if (!current || !next) { return; } const currStyle = next.getAttribute('style'); const curLeft = parseInt(window.getComputedStyle(next).left, 10) || 0; current.setAttribute('style', currStyle); current.style.left = `${curLeft}px`; } document.querySelector(id).addEventListener("click", function (e) { const elements = document.querySelectorAll(id + ' .img-wrapper'); const clicked = e.target.closest('.img-wrapper'); clickIndex = Array.from(elements).indexOf(clicked); if (clickIndex == 1) { leftClick(); } if (clickIndex == 3) { if (!allowedToClick) { return; } isRunning = true; startTime = Date.now(); autoplay = false; allowedToClick = false; let leftID = parseInt(document.querySelectorAll(id + " .img-wrapper")[0].getAttribute("data-id")) - 1; if (leftID < 0) { leftID = pics3D.length - 1; } rightSlides(0, outerFactor); rightSlides(1, 1); rightSlides(2, innerFactor); rightSlides(3, outerFactor); rightSlides(4, outerFactor); setTimeout(function () { document.querySelectorAll(id + " .img-wrapper")[4].remove(); document.querySelector(id).insertAdjacentHTML('afterbegin', '<div class="img-wrapper" data-id="' + leftID + '"><img src="' + path + pics3D[leftID] + '">'); const prependedStyles = document.querySelectorAll(id + " .img-wrapper"); prependedStyles[0].style.marginLeft = -marginsOuter + "px"; prependedStyles[0].style.marginRight = -marginsOuter + "px"; prependedStyles[0].style.transform = "perspective(800px) rotateY(30deg) scale(0.8)"; prependedStyles[0].style.left = "0px"; prependedStyles[0].querySelector("img").style.aspectRatio = aspectRatio; allowedToClick = true; isRunning = false; }, 400); } }); function loop() { setTimeout(function () { if (autoplay) { leftClick(); autoplay = true; loop(); } }, duration); } var single = true; window.addEventListener('resize', function (event) { if (!isRunning) { setStart(); single = true; } else { if (single) { let elapsed = Date.now() - startTime; single = false; setTimeout(function () { setStart(); single = true; }, 420 - elapsed); } } }, true); } } window.Gallery3D = Gallery3D;
Select

Darunter folgendes Script einfügen:

Hier kommen die Anpassungen: (Beispiel mit 2 Galerien, man kann natürlich auch nur eine anlegen) const gallery = new Gallery3D( "ID der Galerie","Pfad zu den Bildern","Bilder (Array)","Autoplay:true or false","Autoplay Duration","Aspect-Ratio");
const picsGallery1 = ["bild1.jpg", "bild2.jpg", "bild3.jpg", "bild4.jpg", "bild5.jpg", "bild6.jpg", "bild7.jpg", "bild8.jpg"]; const gallery = new Gallery3D("#gallery1", "img1/",picsGallery1,true,2000,"4/3"); gallery.gallery(); const picsGallery2 = ["bild9.jpg", "bild10.jpg", "bild11.jpg", "bild12.jpg", "bild13.jpg", "bild14.jpg", "bild15.jpg", "bild16.jpg"]; const gallery2 = new Gallery3D("#gallery2","img2/", picsGallery2,true,1500,"1"); gallery2.gallery();
Select

Hier Links zu CodePen (HTML, CSS und Javascript):

jQuery (empfohlen für WordPress)
https://codepen.io/Oliver7777/pen/OPyRZXp

Javascript (empfohlen für HTML)
https://codepen.io/Oliver7777/pen/dPYpevY
Download HTML