Pause setTimeout() function when hovering the mouse

Asked

Viewed 67 times

1

I have this code and would like when the user passed the mouse over pause the setTimeout and be resumed when taking the mouse from above.

function slide(){
  let slides = document.querySelectorAll('.rotate');
  slide2 = slides[0];
  slide3 = slides[1];
  slide4 = slides[2];
  slide2.classList.add('slide2');
  slide3.classList.add('slide2');
  slide4.classList.add('slide2');
  setTimeout(function(){
    slide3.classList.add('slide3');
    slide4.classList.add('slide3');
    setTimeout(function(){
      slide4.classList.add('slide4');
    }, 5000);
  }, 5000);
};
div.rotate {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  margin: auto;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  border: 3px solid #000;
  border-right-color: transparent;
  border-left-color: transparent;
  border-bottom-color: transparent;
  transform: rotate(-45deg);
  transition: 5s linear;
  background-color: transparent;
}
.slide2 {
  transform: rotate(45deg)!important;
}
.slide3 {
  transform: rotate(135deg)!important;
}
.slide4 {
  transform: rotate(225deg)!important;
}
#container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
#anima {
  color: #fff;
  background-color: #171517;
  border: none;
  padding: 10px 20px;
  font-weight: bold;
  font-size: 1rem;
  text-transform: uppercase;
  cursor: pointer;
  position: absolute;
  margin: auto;
  top: 300px;
}
.container_anima {
  margin-top: 30px;
  position: relative;
  width: 205px;
  height: 205px;
/*   border: 2px solid #000; */
  border-radius: 50%;
}
.container_anima_interno {
  position: relative;
  width: calc(100% - 5px);
  height: calc(100% - 5px);
  border: 2px solid #cecece;
  border-radius: 50%;
  top: 0px;
  left: 0px;
}
.slides {
  position: absolute;
  color: #000;
  background-color: #fff;
  width: 30px;
  height: 30px;
  line-height: 30px;
  font-weight: bold;
  font-size: 1rem;
  text-align: center;
  border: 1px solid #000;
  border-radius: 50%;
}
.slides:first-of-type {
  margin: auto;
  left: 0;
  right: 0;
  top: -15px;
}
.slides:nth-of-type(2) {
  margin: auto;
  top: 0;
  bottom: 0;
  right: -15px;
}
.slides:nth-of-type(3) {
  margin: auto;
  left: 0;
  right: 0;
  bottom: -15px;
}
.slides:last-of-type {
  margin: auto;
  top: 0;
  bottom: 0;
  left: -15px;
}
<div id="container">
  <div class="container_anima">
    <div class="container_anima_interno"></div>
    <div class="rotate" data-slide='1'></div>
    <div class="rotate" data-slide='2'></div>
    <div class="rotate" data-slide='3'></div>
    <div class="rotate" data-slide='4'></div>
    <span class="slides">1</span>
    <span class="slides">2</span>
    <span class="slides">3</span>
    <span class="slides">4</span>
  </div>
  <button id="anima" onclick="slide()">animar</button>
</div>

  • 3

    There is no way to pause the setTimeout. Either you cancel or start again.

1 answer

2


As has already been said, there is no possibility to pause a setTimeout or even a setInterval. But you can change your code to "give that idea". In your case it is a little more work because you have to build the animation based on Javascript, and control whether every step should animate or not.

let animacaoCorrendo = false; //variavel para controlar se a animação esta a correr ou parada

function animar(){
  let slides = [...document.querySelectorAll('.rotate')];
  slides.pop(); //retirar o slide 4 que é fixo

  animacaoCorrendo = true;
  let rotacao = -45;
  
  let animacao = setInterval(function(){    
    //se a animação esta correndo altera as varias rotações, caso contrário nao faz nada
    if (animacaoCorrendo){ 
      for (let slide of slides){ //animar cada slide
        slide.style.transform = `rotate(${rotacao}deg)`;
      }
      rotacao++; //aumentar a rotação
      
      //descartar os slides que já animaram até ao seu ponto final
      if (rotacao == 45 || rotacao == 135 || rotacao == 225){
        slides.shift();
      }
      if (rotacao >= 315){ //ponto final de toda a animação
        clearInterval(animacao); //desligar a animação permanentemente
      }
    }
  }, 33);
};

const container = document.querySelector(".container_anima");
container.addEventListener("mouseenter", function(){
  animacaoCorrendo = false;
});

container.addEventListener("mouseleave", function(){
  animacaoCorrendo = true;
});
div.rotate {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  margin: auto;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  border: 3px solid #000;
  border-right-color: transparent;
  border-left-color: transparent;
  border-bottom-color: transparent;
  transform: rotate(-45deg);
  /*transition: 5s linear;*/
  background-color: transparent;
}
.slide2 {
  transform: rotate(45deg)!important;
}
.slide3 {
  transform: rotate(135deg)!important;
}
.slide4 {
  transform: rotate(225deg)!important;
}
#container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
#anima {
  color: #fff;
  background-color: #171517;
  border: none;
  padding: 10px 20px;
  font-weight: bold;
  font-size: 1rem;
  text-transform: uppercase;
  cursor: pointer;
  position: absolute;
  margin: auto;
  top: 300px;
}
.container_anima {
  margin-top: 30px;
  position: relative;
  width: 205px;
  height: 205px;
/*   border: 2px solid #000; */
  border-radius: 50%;
}
.container_anima_interno {
  position: relative;
  width: calc(100% - 5px);
  height: calc(100% - 5px);
  border: 2px solid #cecece;
  border-radius: 50%;
  top: 0px;
  left: 0px;
}
.slides {
  position: absolute;
  color: #000;
  background-color: #fff;
  width: 30px;
  height: 30px;
  line-height: 30px;
  font-weight: bold;
  font-size: 1rem;
  text-align: center;
  border: 1px solid #000;
  border-radius: 50%;
}
.slides:first-of-type {
  margin: auto;
  left: 0;
  right: 0;
  top: -15px;
}
.slides:nth-of-type(2) {
  margin: auto;
  top: 0;
  bottom: 0;
  right: -15px;
}
.slides:nth-of-type(3) {
  margin: auto;
  left: 0;
  right: 0;
  bottom: -15px;
}
.slides:last-of-type {
  margin: auto;
  top: 0;
  bottom: 0;
  left: -15px;
}
<div id="container">
  <div class="container_anima">
    <div class="container_anima_interno"></div>
    
    <div class="rotate" data-slide='1'></div>
    <div class="rotate" data-slide='2'></div>
    <div class="rotate" data-slide='3'></div>
    <div class="rotate" data-slide='4'></div>
    <span class="slides">1</span>
    <span class="slides">2</span>
    <span class="slides">3</span>
    <span class="slides">4</span>
  </div>
  <button id="anima" onclick="animar()">animar</button>
</div>

With this transformation it becomes more complicated to manage the animations because they are made by Javascript. This applies even to times, which are now managed based on the time of each "frame" of the animation (which I defined as 33) and how much the rotation increases in each frame (in this case I put 1).

Note that I had to additionally undo the transition: 5s linear; who was in the div.rotate because times are all controlled by Javascript.

  • 1

    The slide change is 5000ms, but the code was great.

  • Dude, you were great! You helped me so much, I’m getting into javascript, I don’t know much! But I see you did!! Thank you so much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.