Tutorial
3D Carousel
Aspect-Ratio: 4/3
Aspect-Ratio: 1
HTML
<div class="outer-gallery"><div id="gallery1" class="gallery3D"></div></div>
<div class="outer-gallery"><div id="gallery2" 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