skip to Main Content

I have made a slider where images flip either 180deg or 360deg before sliding. The problem that I can not understand is that everything works fine until the slide reach initial position. Then even though the rotateY style is added to images (as checked in console) it still does not revolve. Can someone explain the strange behavior

const container = document.querySelectorAll('.image-container')
const nextBtn = document.querySelector('.next')
let counter = 0


nextBtn.addEventListener('click', moveSlide)

function moveSlide() {
  counter++
  n =(counter%2) * 180 +180
    if(counter===6){
      console.log(counter)
      image = document.querySelector(`.image-container:nth-child( ${counter}) img `)
      console.log(image)
      image.style.transform = `rotateY(${n}deg)`
        container.forEach((image, index) => {
            let width = image.getBoundingClientRect().width
            console.log(width)
            image.style.transform = `translate(0%) rotateY(0deg)`
            counter=0
        return
        })
    }else{
      console.log({counter})
      console.log({n})
        image = document.querySelector(`.image-container:nth-child( ${counter}) img `)
        console.log(image)
        image.style.transform = `rotateY(${n}deg)`
        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; */
    overflow: auto;
  }
  
  .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>

2

Answers


  1. On the second iteration on the slides, the style is already applied on each slide.

    If you set a rotation of 180deg, on an object that already have 180deg applied, nothing will happened.

    One possible way of handling it could be to:

    • Reset rotation to 0deg once it’s done;
    • Handling transition dynamically, thinking for the timing, 0ms when it’s not animated, 450ms when it is actually rotating, so the reset to 0deg is not animated and not "visible" to the naked eyes.
    Login or Signup to reply.
  2. You need to remove the style:rotateY(180deg) that is already on the image and set it back to style:rotateY(0deg) to just after the flip . Your rotation actualy could not be seen but is there. Also it is better setting that with a setTimeout. So you can check this (I also changed the name of image to imageNode in forEach loop for a clearer code)

    const container = document.querySelectorAll('.image-container')
    const nextBtn = document.querySelector('.next')
    let counter = 0
    
    
    nextBtn.addEventListener('click', moveSlide)
    
    function moveSlide() {
      counter+=1
      n = 180
        if(counter===6){
          console.log(counter)
          image = document.querySelector(`.image-container:nth-child( ${counter}) img `)
          console.log(image)
          image.style.transform = `rotateY(${n}deg)`
            container.forEach((imageNode, index) => {
              let width = imageNode.getBoundingClientRect().width
              console.log(width)
              imageNode.style.transform = `translate(0%)`
              counter=0
              setTimeout(()=>{image.style.transform = `rotateY(0deg)`},300)
              return
            })
        }else{
          console.log({counter})
          console.log({n})
            image = document.querySelector(`.image-container:nth-child( ${counter}) img `)
            console.log(image)
            image.style.transform = `rotateY(${n}deg)`
            setTimeout(()=>{image.style.transform = `rotateY(0deg)`},300)
                container.forEach((imageNode, index) => {
                let width = imageNode.getBoundingClientRect().width
                  setTimeout(() => {
                    imageNode.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; */
        overflow: auto;
      }
      
      .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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search