Slajder produktów — 4Hand
Dwa moduły Divi obok siebie:
Galeria z klasą
Kod z załączonym niżej kodem — to jest sam slajder
Galeria zostaje ukryta, slajder buduje się z niej sam.
Galeria z klasą
sp-zrodlo — to jest źródło zdjęćKod z załączonym niżej kodem — to jest sam slajder
Galeria zostaje ukryta, slajder buduje się z niej sam.
Jak dołożyć produkt
- Otwórz moduł Galeria → Aktualizuj galerię → zaznacz zdjęcia w bibliotece mediów.
- Podpis na pionowym pasku bierze się z pola Tytuł zdjęcia w bibliotece mediów — wpisz tam nazwę modelu, np.
classic-012. - Kolejność ustawiasz przeciąganiem w oknie wyboru zdjęć.
- W ustawieniach Galerii podnieś liczbę zdjęć do tylu, ile ich masz, i wyłącz stronicowanie — inaczej Divi pokaże tylko pierwszą porcję.
Co robi
- Przesuwa się sam o jeden kafel, w lewo, w zapętleniu bez przeskoku.
- Po najechaniu myszą przesuw staje, kafel rośnie w dół (górna krawędź zostaje w miejscu) i pojawia się żółty kwadrat z plusem.
- Po kliknięciu otwiera się powiększenie — strzałki na klawiaturze i
Escdziałają. - Bez żadnej biblioteki zewnętrznej. Ten sam mechanizm co karuzela realizacji na stronie głównej.
Ustawienia
Wszystko siedzi w zmiennych na .sp-karuzela — zmieniasz na górze kodu, bez szukania w środku.
--sp-na-ekranie— ile kafli widać naraz (10 na komputerze, 5 na tablecie, 3 na telefonie)--sp-odstep— przerwa między kaflami--sp-proporcja— kształt kafla--sp-przerwa— co ile milisekund następny krok--sp-przejscie— jak długo trwa jeden krok--sp-powiekszenie— o ile rośnie kafel po najechaniu
Uwaga na nazwy plików
Wgrywaj zdjęcia z nazwami bez polskich znaków. Nazwa z ogonkiem zapisuje się w dwóch różnych postaciach Unicode i część adresów przestaje działać.
Kod do skopiowania
Całość wklejasz w jeden moduł Kod, razem ze znacznikami.
<style>
.sp-zrodlo{ display:none !important; }
.sp-karuzela{
--sp-na-ekranie: 10; /* ile kafli widac naraz */
--sp-odstep: 30px; /* przerwa miedzy kaflami */
--sp-proporcja: 128/215; /* ksztalt kafla */
--sp-przerwa: 3000; /* co ile ms nastepny krok */
--sp-przejscie: 1500; /* jak dlugo trwa krok */
--sp-powiekszenie: 1.05; /* o ile rosnie kafel po najechaniu */
--sp-zolty: #F0C609;
position:relative;
}
/* padding-bottom robi miejsce na kafel, ktory po najechaniu rozrasta sie
w dol - przycinanie dziala dopiero na krawedzi wypelnienia, wiec
powiekszony kafel i jego cien pozostaja widoczne */
.sp-karuzela .sp-viewport{ overflow:hidden; padding-bottom:26px; }
.sp-karuzela .sp-track{ display:flex; gap:var(--sp-odstep); will-change:transform; }
.sp-karuzela .sp-kafel{
flex:0 0 calc((100% - (var(--sp-na-ekranie) - 1) * var(--sp-odstep)) / var(--sp-na-ekranie));
position:relative; display:block; overflow:hidden; text-decoration:none; background:#000;
transform-origin: top center; /* gora stoi w miejscu, kafel rosnie w dol */
transition: transform .5s cubic-bezier(.2,0,.2,1), box-shadow .5s ease;
}
.sp-karuzela .sp-kafel:hover{
transform: scale(var(--sp-powiekszenie));
z-index:5;
box-shadow:0 0 20px 0 rgba(0,0,0,.35);
}
.sp-karuzela .sp-foto{ display:block; position:relative; overflow:hidden; aspect-ratio:var(--sp-proporcja); }
.sp-karuzela .sp-foto img{ display:block; width:100%; height:100%; object-fit:cover; }
/* nakladka: zolty kwadrat + dwie kreski jadace od krawedzi = plus
ten sam mechanizm co w module hover-plus */
.sp-karuzela .sp-foto::after{
content:""; position:absolute; inset:0; z-index:3; opacity:0;
background-image:
linear-gradient(#fff,#fff),
linear-gradient(#fff,#fff),
linear-gradient(var(--sp-zolty),var(--sp-zolty));
background-repeat:no-repeat;
background-size:3px 26px, 26px 3px, 56px 56px;
background-position:50% 0%, 0% 50%, 50% 50%;
transition:opacity .25s ease, background-position .5s cubic-bezier(.2,0,.2,1);
pointer-events:none;
}
.sp-karuzela .sp-kafel:hover .sp-foto::after{
opacity:1;
background-position:50% 50%, 50% 50%, 50% 50%;
}
/* pionowy pasek z nazwa modelu przy prawej krawedzi kafla */
.sp-karuzela .sp-etykieta{
position:absolute; top:0; right:0; bottom:0; width:24px; z-index:4;
writing-mode:vertical-rl; background:rgba(0,0,0,.5); color:#fff;
font-size:13px; font-weight:300; letter-spacing:3px; text-transform:uppercase;
display:flex; align-items:center; justify-content:center;
padding:5px 0; overflow:hidden; pointer-events:none;
}
.sp-karuzela .sp-arrows{ display:flex; gap:48px; justify-content:center; margin-top:10px; }
.sp-karuzela .sp-arrows button{
background:none; border:0; cursor:pointer; color:var(--sp-zolty);
font:600 14px/1 Poppins,system-ui,Arial,sans-serif; letter-spacing:2px;
display:inline-flex; align-items:center; gap:10px; padding:8px;
}
.sp-karuzela .sp-arrows button:hover{ color:#323232; }
.sp-karuzela .sp-prev::before{ content:"\2190"; font-size:19px; }
.sp-karuzela .sp-next::after{ content:"\2192"; font-size:19px; }
@media (max-width:990px){ .sp-karuzela{ --sp-na-ekranie:5; } }
@media (max-width:590px){ .sp-karuzela{ --sp-na-ekranie:3; --sp-odstep:15px; } }
/* powiekszenie zdjecia */
.sp-lightbox{
position:fixed; inset:0; z-index:99999; background:rgba(0,0,0,.92);
display:flex; align-items:center; justify-content:center;
opacity:0; visibility:hidden; transition:opacity .25s ease, visibility .25s;
}
.sp-lightbox.jest-otwarty{ opacity:1; visibility:visible; }
.sp-lightbox img{ max-width:88vw; max-height:84vh; display:block; }
.sp-lb-podpis{
position:absolute; left:0; right:0; bottom:22px; text-align:center; color:#fff;
letter-spacing:3px; text-transform:uppercase; font-size:13px;
}
.sp-lb-zamknij,.sp-lb-prev,.sp-lb-next{
position:absolute; background:none; border:0; color:#fff; cursor:pointer;
font-size:34px; line-height:1; padding:14px;
}
.sp-lb-zamknij:hover,.sp-lb-prev:hover,.sp-lb-next:hover{ color:#F0C609; }
.sp-lb-zamknij{ top:10px; right:14px; }
.sp-lb-prev{ left:10px; top:50%; transform:translateY(-50%); }
.sp-lb-next{ right:10px; top:50%; transform:translateY(-50%); }
</style>
<div class="sp-karuzela">
<div class="sp-viewport"><div class="sp-track"></div></div>
<div class="sp-arrows">
<button class="sp-prev" type="button">PREV</button>
<button class="sp-next" type="button">NEXT</button>
</div>
</div>
<script>
(function(){
function start(){
document.querySelectorAll('.sp-karuzela').forEach(function(root){
if(root.dataset.init) return; root.dataset.init='1';
var track = root.querySelector('.sp-track');
var viewport = root.querySelector('.sp-viewport');
var styl = getComputedStyle(root);
var PRZERWA = parseFloat(styl.getPropertyValue('--sp-przerwa')) || 3000;
var PRZEJSCIE = parseFloat(styl.getPropertyValue('--sp-przejscie')) || 1500;
/* ---------- kafle budowane z Galerii Divi ---------- */
var zrodlo = document.querySelector(root.dataset.zrodlo || '.sp-zrodlo');
if(zrodlo){
[].forEach.call(zrodlo.querySelectorAll('.et_pb_gallery_item'), function(poz){
var a = poz.querySelector('a');
var img = poz.querySelector('img');
if(!a || !img) return;
var tytul = a.getAttribute('title') || img.getAttribute('alt') || '';
var kafel = document.createElement('a');
kafel.className = 'sp-kafel';
kafel.setAttribute('href', a.getAttribute('href'));
kafel.setAttribute('title', tytul);
kafel.dataset.tytul = tytul;
var foto = document.createElement('span');
foto.className = 'sp-foto';
var kopia = document.createElement('img');
kopia.setAttribute('src', img.getAttribute('src'));
if(img.getAttribute('srcset')) kopia.setAttribute('srcset', img.getAttribute('srcset'));
kopia.setAttribute('alt', tytul);
kopia.setAttribute('loading', 'lazy');
foto.appendChild(kopia);
var etykieta = document.createElement('span');
etykieta.className = 'sp-etykieta';
etykieta.textContent = tytul;
kafel.appendChild(foto);
kafel.appendChild(etykieta);
track.appendChild(kafel);
});
}
if(!track.children.length) return; /* nie ma z czego budowac */
/* numerujemy dopiero teraz - kafle moga pochodzic z galerii albo z kodu */
[].forEach.call(track.children, function(a, i){ a.dataset.i = i; });
/* lista do powiekszenia zbierana PRZED klonowaniem */
var lista = [].map.call(track.children, function(a){
return { src: a.getAttribute('href'), tytul: a.dataset.tytul || '' };
});
var oryg = track.children.length;
track.innerHTML = track.innerHTML + track.innerHTML; /* klon -> plynne zapetlenie */
var offset = 0, tween = null, ostatni = null;
var doNastepnego = PRZERWA, najechane = false, lbOtwarty = false;
var bezRuchu = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
function krok(){ /* szerokosc kafla + odstep */
var a = track.children[0].getBoundingClientRect();
var b = track.children[1].getBoundingClientRect();
return b.left - a.left;
}
function jednostka(){ return krok() * oryg; }
function ease(p){ return 1 - Math.pow(1 - p, 3); }
function przesun(kierunek, czas){
var od = tween ? tween.to : offset;
tween = { from: offset, to: od + kierunek * krok(), start: performance.now(), dur: czas };
}
var prev = root.querySelector('.sp-prev'), next = root.querySelector('.sp-next');
if(prev) prev.addEventListener('click', function(){ przesun(-1, 450); doNastepnego = PRZERWA; });
if(next) next.addEventListener('click', function(){ przesun( 1, 450); doNastepnego = PRZERWA; });
viewport.addEventListener('mouseenter', function(){ najechane = true; });
viewport.addEventListener('mouseleave', function(){ najechane = false; });
function klatka(t){
if(ostatni === null) ostatni = t;
var dt = t - ostatni; ostatni = t;
if(tween){
var p = (t - tween.start) / tween.dur;
if(p >= 1){ offset = tween.to; tween = null; doNastepnego = PRZERWA; }
else { offset = tween.from + (tween.to - tween.from) * ease(p); }
} else if(!najechane && !lbOtwarty && !bezRuchu){
doNastepnego -= dt;
if(doNastepnego <= 0) przesun(1, PRZEJSCIE);
}
var u = jednostka();
if(u > 0) offset = ((offset % u) + u) % u;
track.style.transform = 'translateX(' + (-offset) + 'px)';
requestAnimationFrame(klatka);
}
requestAnimationFrame(klatka);
/* ---------- powiekszenie zdjecia ---------- */
var lb = document.createElement('div');
lb.className = 'sp-lightbox';
lb.innerHTML = '<button class="sp-lb-zamknij" type="button" aria-label="Zamknij">×</button>'
+ '<button class="sp-lb-prev" type="button" aria-label="Poprzednie">‹</button>'
+ '<img alt=""><span class="sp-lb-podpis"></span>'
+ '<button class="sp-lb-next" type="button" aria-label="Nastepne">›</button>';
document.body.appendChild(lb);
var lbImg = lb.querySelector('img'), lbPodpis = lb.querySelector('.sp-lb-podpis');
var biezacy = 0;
function pokaz(i){
biezacy = ((i % lista.length) + lista.length) % lista.length;
lbImg.src = lista[biezacy].src;
lbImg.alt = lista[biezacy].tytul;
lbPodpis.textContent = lista[biezacy].tytul;
}
function otworz(i){ pokaz(i); lb.classList.add('jest-otwarty'); lbOtwarty = true; }
function zamknij(){ lb.classList.remove('jest-otwarty'); lbOtwarty = false; }
track.addEventListener('click', function(e){
var a = e.target.closest('.sp-kafel');
if(!a) return;
e.preventDefault();
otworz(parseInt(a.dataset.i, 10));
});
lb.querySelector('.sp-lb-zamknij').addEventListener('click', zamknij);
lb.querySelector('.sp-lb-prev').addEventListener('click', function(e){ e.stopPropagation(); pokaz(biezacy - 1); });
lb.querySelector('.sp-lb-next').addEventListener('click', function(e){ e.stopPropagation(); pokaz(biezacy + 1); });
lb.addEventListener('click', function(e){ if(e.target === lb || e.target === lbImg) zamknij(); });
document.addEventListener('keydown', function(e){
if(!lbOtwarty) return;
if(e.key === 'Escape') zamknij();
if(e.key === 'ArrowLeft') pokaz(biezacy - 1);
if(e.key === 'ArrowRight') pokaz(biezacy + 1);
});
});
}
if(document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start);
else start();
})();
</script>