class Carousel {
constructor(options) {
Object.assign(this, {
slides: [],
index: 0,
pause: 4000, // Pause between slides
EL: document.querySelector(options.target || "#Carousel"),
autoplay: true,
}, options);
this.total = this.slides.length;
this.EL_area = this.EL.querySelector(".Carousel-area");
this.EL_prev = this.EL.querySelector(".Carousel-prev");
this.EL_next = this.EL.querySelector(".Carousel-next");
const NewEL = (tag, prop) => Object.assign(document.createElement(tag), prop);
// Preload images
this.ELs_items = this.slides.reduce((DF, item) => {
const EL_slide = NewEL("div", {
className: "Carousel-slide"
});
const EL_image = NewEL("img", {
className: "Carousel-image",
src: item.image,
alt: item.title
});
const EL_content = NewEL("div", {
className: "Carousel-title",
textContent: item.title
});
EL_slide.append(EL_image, EL_content);
DF.push(EL_slide);
return DF;
}, []);
this.EL_area.append(...this.ELs_items);
// Events
this.EL_prev.addEventListener("click", () => this.prev());
this.EL_next.addEventListener("click", () => this.next());
this.EL.addEventListener("mouseenter", () => this.stop());
this.EL.addEventListener("mouseleave", () => this.play());
// Init
this.anim();
this.play();
}
// Methods:
anim() {
this.index = this.index < 0 ? this.total - 1 : this.index >= this.total ? 0 : this.index;
this.ELs_items.forEach((EL, i) => EL.classList.toggle("is-active", i === this.index));
}
prev() {
this.index -= 1;
this.anim();
}
next() {
this.index += 1;
this.anim();
}
stop() {
clearInterval(this.itv);
}
play() {
if (this.autoplay) this.itv = setInterval(() => this.next(), this.pause);
}
}
// Use like:
new Carousel({
target: "#carousel-one",
slides: [{
title: "We're part of nature",
image: "https://picsum.photos/id/10/400/300"
},
{
title: "Remember to read and learn",
image: "https://picsum.photos/id/24/400/300"
},
{
title: "Up for a coffee?",
image: "https://picsum.photos/id/30/400/300"
},
]
});
/* CAROUSEL */
.Carousel {
position: relative;
height: 300px;
max-height: 100vh;
}
.Carousel-slide {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transition: opacity 0.5s; /* DESIRED SLIDE TRANSITIONS */
opacity: 0; /* INACTIVE SLIDE*/
}
.Carousel-slide.is-active { /* ACTIVE SLIDE! */
opacity: 1;
z-index: 1;
}
.Carousel-prev,
.Carousel-next {
position: absolute;
z-index: 2;
top: 50%;
transform: translateY(-50%);
user-select: none; /* Prevent highlight */
}
.Carousel-prev {
left: 1em;
}
.Carousel-next{
right: 1em;
}
.Carousel-image {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
.Carousel-title {
position: absolute;
width: 100%;
height: 100%;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 3em;
}
<div class="Carousel" id="carousel-one">
<div class="Carousel-area"></div>
<button class="Carousel-prev" type="button" aria-label="Previous slide">←</button>
<button class="Carousel-next" type="button" aria-label="Next slide">→</button>
<div class="Carousel-desc"></div>
</div>