I am trying to build an image slider in which when pressing the previous or next button my image slider first rotates 180deg then translates the width of the image to show next/previous image.
I can't get it to work and I think that I may need a solution using an async/await function which I am really not very good at right now. I tried to write an asynchronus function but could not get it right.
Maybe someone can show me the way to solve this?
const container = document.querySelectorAll('.image-container')
const prevBtn = document.querySelector('.prev')
let counter = 0
prevBtn.addEventListener('click', moveSlide)
function moveSlide() {
counter++
container.forEach((image, index) => {
let width = image.getBoundingClientRect().width
image.style.transform = `rotateY(180deg)`
setTimeout(() => {
image.style.transform = `translate(-${counter*width}px`
}, 450)
})
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
display: flex;
height: 100vh;
overflow: hidden;
align-items: center;
align-content: center;
justify-content: center;
}
.wrapper {
display: flex;
flex-direction: column;
}
.slider-container {
height: 50vh;
width: 300px;
display: flex;
margin: auto;
flex-direction: row;
overflow: hidden;
}
.image-container {
display: block;
width: 300px;
transition: transform 450ms ease;
}
.btn-container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
gap: 5px;
}
.btn-container .btn {
width: 15vw;
padding: 5px;
}
<div class="wrapper">
<div class="slider-container">
<div class="image-container">
<img src="https://picsum.photos/id/237/300/200" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/seed/picsum/300/200" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/300/200?grayscale" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/300/200/?blur" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/id/870/300/200?grayscale&blur=2" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/id/1/300/200" alt="">
</div>
</div>
<div class="btn-container">
<button class="btn prev">Previous</button>
<button class="btn next">Next</button>
</div>
</div>
There were 2 issues. In your code you rotated all the containers of the images at the same time. This caused them all to shrink to the left. Other issue - you needn't rotate the container, but rather the img
within it. So I added the transition
property to the .image-container img
and made sure to rotate the image.
Also, it is better to use events instead of timeout to detect when the transition ends. I didn't go there. Also, consider using a library for this common task.
const container = document.querySelectorAll('.image-container')
const prevBtn = document.querySelector('.prev')
let counter = 0
prevBtn.addEventListener('click', moveSlide)
function moveSlide() {
counter++
image = document.querySelector(".image-container:nth-child(" + counter + ") img")
image.style.transform = `rotateY(180deg)`
image.style.border = "2px solid red"
container.forEach((image, index) => {
let width = image.getBoundingClientRect().width
setTimeout(() => {
image.style.transform = `translate(-${counter*width}px`
}, 450)
})
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
display: flex;
height: 100vh;
overflow: hidden;
align-items: center;
align-content: center;
justify-content: center;
}
.wrapper {
display: flex;
flex-direction: column;
}
.slider-container {
height: 50vh;
width: 300px;
display: flex;
margin: auto;
flex-direction: row;
overflow: hidden;
}
.image-container,
.image-container img {
display: block;
width: 300px;
transition: transform 450ms ease;
}
.btn-container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
gap: 5px;
}
.btn-container .btn {
width: 15vw;
padding: 5px;
}
<div class="wrapper">
<div class="slider-container">
<div class="image-container">
<img src="https://picsum.photos/id/237/300/200" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/seed/picsum/300/200" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/300/200?grayscale" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/300/200/?blur" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/id/870/300/200?grayscale&blur=2" alt="">
</div>
<div class="image-container">
<img src="https://picsum.photos/id/1/300/200" alt="">
</div>
</div>
<div class="btn-container">
<button class="btn prev">Previous</button>
<button class="btn next">Next</button>
</div>
</div>