JSFiddle - React, Tailwind, and code Playground
by Imabot
HTML
<div style="color:white; font-family:'Courier New';">
Left click => forward<br>
Right click => backward<br>
Middle click => reset<br>
<a href="https://lucidar.me/en/web-dev/building-a-carousel-in-vanilla-js-css/" style="color:CadetBlue">
More details on my blog
</a>
</div>
<div id="carousel">
<img src="https://lucidar.me/fr/web-dev/files/img0.svg" id="carousel-image-0" class="carousel-image">
<img src="https://lucidar.me/fr/web-dev/files/img1.svg" id="carousel-image-1" class="carousel-image">
<img src="https://lucidar.me/fr/web-dev/files/img2.svg" id="carousel-image-2" class="carousel-image">
<img src="https://lucidar.me/fr/web-dev/files/img3.svg" id="carousel-image-3" class="carousel-image">
<img src="https://lucidar.me/fr/web-dev/files/img4.svg" id="carousel-image-4" class="carousel-image">
<img src="https://lucidar.me/fr/web-dev/files/img5.svg" id="carousel-image-5" class="carousel-image">
</div>
CSS
body {
background-color: #323232;
caret-color: transparent;
margin: 0;
}
#carousel {
width: 100%;
max-width: 100vw;
height: 21vh;
position: absolute;
top: 50%;
transform: translateY(-50%);
overflow: hidden;
}
.carousel-image {
height: 20vh;
max-height: 200px;
position: absolute;
left: 50%;
border-radius: 7%;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
}
#carousel-image-0 {
transform: translateX(-50%) translateX(-120%) scale(0.6);
filter: brightness(40%);
z-index: 1;
}
#carousel-image-1 {
transform: translateX(-50%) translateX(-80%) scale(0.8);
filter: brightness(65%);
opacity: 1;
z-index: 2;
}
#carousel-image-2 {
transform: translateX(-50%) scale(1);
filter: brightness(100%);
opacity: 1;
z-index: 3;
}
#carousel-image-3 {
transform: translateX(-50%) translateX(80%) scale(0.8);
filter: brightness(65%);
opacity: 1;
z-index: 2;
}
#carousel-image-4 {
transform: translateX(-50%) translateX(120%) scale(0.6);
filter: brightness(40%);
opacity: 1;
z-index: 1;
}
#carousel-image-5 {
transform: translateX(-50%) scale(1.5);
filter: brightness(40%);
opacity: 0;
z-index: 1;
}
/* Forward */
.mv0to5 {
animation: 0.3s ease-out mv0to5;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.mv5to4 {
animation: 0.3s ease-out mv5to4;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.mv4to3 {
animation: 0.3s ease-out mv4to3;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.mv3to2 {
animation: 0.3s ease-out mv3to2;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.mv2to1 {
animation: 0.3s ease-out mv2to1;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
.mv1to0 {
animation: 0.3s ease-out mv1to0;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
/* Backward */
.mv0to1 {
...
JavaScript
// Class that manage the carousel
class Carousel {
// Constructor, initialise the carousel
constructor() {
// Get image elements
this.img = [];
this.img[0] = document.getElementById("carousel-image-0");
this.img[1] = document.getElementById("carousel-image-1");
this.img[2] = document.getElementById("carousel-image-2");
this.img[3] = document.getElementById("carousel-image-3");
this.img[4] = document.getElementById("carousel-image-4");
this.img[5] = document.getElementById("carousel-image-5");
// Set animation key frames forward and backward
this.animForward = ['mv0to5', 'mv1to0', 'mv2to1', 'mv3to2', 'mv4to3', 'mv5to4'];
this.animBackward = ['mv0to1', 'mv1to2', 'mv2to3', 'mv3to4', 'mv4to5', 'mv5to0'];
// Reset carousel
this.reset();
}
// Set a new image (src) to image at given position (pos)
// 0 first image on the left
// 2 middle image
// 4 last image
// 5 hidden image
setImage(pos, src) {
this.img[(pos+this.currentImage+4)%6].src = src;
}
// Hide an image at given position (pos)
// 0 first image on the left
// 2 middle image
// 4 last image
// 5 hidden image
hideImage(pos) {
this.img[(pos+this.currentImage+4)%6].style.visibility = 'hidden';
}
// Show an image at given position (pos)
// 0 first image on the left
// 2 middle image
// 4 last image
// 5 hidden image
showImage(pos) {
this.img[(pos+this.currentImage+4)%6].style.visibility = 'visible';
}
// Reset carousel, set image 2 in the middle
reset() {
// Remove animations
this.img.forEach((image) => {
this.animForward.forEach((animation) => {
image.classList.remove( animation );
})
this.animBackward.forEach((animation) => {
image.classList.remove( animation ); ...