It's incredible how this brought back memories of some old carousel code that I had stashed away back in 2017! It's been a while.
I spent some time figuring it out again. It seems like there is some resize code to ensure that the images fit nicely inside the container. For instance, even though the images are 512px wide, they need to scale down to fit into a 300px wide container.
The code includes a show
method that can be linked to buttons. This method requires two parameters: an integer to specify the number of images to move (negative for backward movement) and a boolean value to indicate if the carousel should wrap around when reaching the end.
By manipulating the margin offset, the code displays each "slide", showcasing a CSS transition effect that animates the slides smoothly.
var Slides;
(function(Slides) {
let slides_container = document.querySelector(".slides-container");
let slides = document.querySelector(".slides");
let images = slides.querySelectorAll("img");
let img_idx = 0;
for (let ix = 0; ix < images.length; ix++) {
images[ix].addEventListener("load", function() {
scaleElementToAncestor(this, slides_container);
});
}
function show(next, wrap) {
if (!slides.children[img_idx + next]) {
if (!wrap)
return;
img_idx = img_idx + next;
if (img_idx < 0)
img_idx = slides.children.length - 1;
if (img_idx > slides.children.length - 1)
img_idx = 0;
} else {
img_idx = img_idx + next;
}
let offset = 0;
for (let ix = 0; ix < img_idx; ix++) {
offset += slides.children[ix].clientWidth;
}
slides.style.marginLeft = -offset + "px";
}
Slides.show = show;
function scaleElementToAncestor(el, ancestor) {
const max_width = ancestor.clientWidth;
const max_height = ancestor.clientHeight;
const initial_width = el.clientWidth;
const initial_height = el.clientHeight;
let width = (max_height * initial_width) / initial_height;
let height = (max_width * initial_height) / initial_width;
if (width > max_width)
width = (height * initial_width) / initial_height;
if (height > max_height)
height = (width * initial_height) / initial_width;
el.style.width = width + "px";
el.style.height = height + "px";
}
})(Slides || (Slides = {}));
.slides-container {
font-size: 0;
width: 300px;
height: 150px;
overflow: hidden;
white-space: nowrap;
margin: 0 auto;
}
.slides {
display: inline-block;
-webkit-transition: margin-left 0.5s;
transition: margin-left 0.5s;
}
.slides img {
vertical-align: top;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="slides-container">
<!-- add class -->
<div class="slides" onclick="Slides.show(1, true)">
<!-- add class -->
<!-- add click-handler, or not -->
<img src="https://dummyimage.com/512x256/000/fff">
<img src="https://dummyimage.com/512x128/f00/fff">
<img src="https://dummyimage.com/512x256/0f0/000">
<img src="https://dummyimage.com/256x256/00f/fff">
<img src="https://dummyimage.com/512x256/999/000">
</div>
</div>
<div style="margin-top: 1em; text-align: center;">
<button onclick="Slides.show(-1, false)">Previous</button>
<!-- add click-handler -->
<button onclick="Slides.show(1, true)">Next</button>
<!-- add click-handler -->
</div>
</div>
</div>