// DOM utility functions:
const els = (sel, par) => (par || document).querySelectorAll(sel);
// Utility functions:
const mod = (n, m) => ((n % m) + m) % m; // Fix negative Modulo
// Images wheeler component:
const imagesWheeler = (elParent) => {
const elsImages = els(".image", elParent);
const tot = elsImages.length;
let itv = null;
let c = 0; // current index
const anim = () => {
elsImages.forEach((elImage, i) => {
elImage.classList.toggle("is-active", i === c);
});
};
const next = () => {
c = mod(++c, tot);
anim();
};
const prev = () => {
c = mod(--c, tot);
anim();
};
const play = () => {
itv = setInterval(next, 3000);
};
const stop = () => {
clearInterval(itv);
};
const handleWheel = (evt) => {
evt.preventDefault();
c += Math.sign(evt.deltaY); // get 1, -1
c = mod(c, tot);
anim();
};
// Events:
elParent.addEventListener("pointerenter", stop);
elParent.addEventListener("pointerleave", play);
elParent.addEventListener("pointerdown", next);
addEventListener("wheel", handleWheel);
// Init:
anim(); // animate to first image
play(); // start autoplay!
};
els(".images-container").forEach(imagesWheeler);
.images-container {
position: relative;
width: 10rem;
aspect-ratio: 1;
&>* {
position: absolute;
width: inherit;
aspect-ratio: inherit;
object-fit: cover;
cursor: pointer;
transition: opacity 0.4s;
opacity: 0;
pointer-events: none;
&.is-active {
opacity: 1;
pointer-events: auto;
}
}
}
Use click to advance, wheel to prev/next, mouseleave to autoplay!
<div class="images-container">
<img class="image" src="//picsum.photos/seed/01/200/200" alt="">
<img class="image" src="//picsum.photos/seed/02/200/200" alt="">
<img class="image" src="//picsum.photos/seed/03/200/200" alt="">
<img class="image" src="//picsum.photos/seed/04/200/200" alt="">
<img class="image" src="//picsum.photos/seed/05/200/200" alt="">
<img class="image" src="//picsum.photos/seed/06/200/200" alt="">
<img class="image" src="//picsum.photos/seed/07/200/200" alt="">
<img class="image" src="//picsum.photos/seed/08/200/200" alt="">
<img class="image" src="//picsum.photos/seed/09/200/200" alt="">
<img class="image" src="//picsum.photos/seed/10/200/200" alt="">
</div>
<p>Hey, you can have multiple!</p>
<div class="images-container">
<img class="image" src="//picsum.photos/seed/21/200/200" alt="">
<img class="image" src="//picsum.photos/seed/22/200/200" alt="">
<img class="image" src="//picsum.photos/seed/23/200/200" alt="">
<img class="image" src="//picsum.photos/seed/24/200/200" alt="">
<img class="image" src="//picsum.photos/seed/25/200/200" alt="">
<img class="image" src="//picsum.photos/seed/26/200/200" alt="">
<img class="image" src="//picsum.photos/seed/27/200/200" alt="">
<img class="image" src="//picsum.photos/seed/28/200/200" alt="">
<img class="image" src="//picsum.photos/seed/29/200/200" alt="">
<img class="image" src="//picsum.photos/seed/30/200/200" alt="">
</div>