Рекурсивный таймер неправильно останавливается

1

У меня есть таймер, построенный для циклирования через данные JSON, который подается на него через переменную. На данный момент, когда я нажимаю кнопку паузы, обратный отсчет делает паузу правильно, но как только я нажимаю кнопку снова, таймер начинается с первого набора данных, а не от того, где он был приостановлен. Как я могу избежать этого из-за того, что функция паузы работает правильно?

    var label = document.getElementById("exerciseLabel");
    var button = document.getElementById("pauseButton");
    var counter = document.getElementById("exerciseCounter");
    var routine = document.getElementById("info");
    var current = 0;
    var playing = false;
    var countdownTimer = null;
    var workout =
    {
      "title": "Full Body",
      "exercises":
      [
        {
          "name": "Push Ups",
          "duration": 3,
          "break": 3
        },
        {
          "name": "Squats",
          "duration": 3,
          "break": 3
        },
        {
          "name": "Running in place",
          "duration": 3,
          "break": 3
        }
      ]
    };
    
    // LOOPING TIMER FUNCTION
    // Initialise virtual trainer.
    init();
    
    /**
    * Bind loop start to click on button.
    *
    * @return {void}
    */
    function init()
    {
      loop();
      button.addEventListener("click", toggle);
    }
    
    /**
    * Play / Stop exercising.
    *
    * @return {void}
    */
    function toggle()
    {
      if (playing)
      {
        pause();
      }
      else
      {
        loop();
      }
    }
    
    /**
    * Reset timer. <--SHOULD BE PAUSE
    *
    * @return {void}
    */
    function pause()
    {
      playing = false;
      setLabel("Paused");
      //setCounter('--')
      if (countdownTimer)
      {
        clearTimeout(countdownTimer); // FIGURE OUT HOW NOT TO CLEAR
      }
    }
    
    // TIMER FUNCTION
    /**
    * Timer loop function
    *
    * @return {void}
    */
    function loop()
    {
      playing = true;
    
      // Change button label
      setButtonText("Pause");
    
      // Get current exercise
      var exercise = workout.exercises[current];
    
      // If out of the exercises Array bounds, call 'done'
      if (!exercise)
      {
        return done();
      }
      // Otherwise run countdown and update UI.
      countdown(exercise.duration, exercise.name, function ()
      {
        countdown(exercise.break, "Break", function ()
        {
          // Next exercise.
          current++;
          // Re-iterate until finished.
          loop();
        });
      });
    }
    
    /**
    * Exercise session is now over.
    *
    * @return {void}
    */
    function done()
    {
      pause();
      document.getElementById("feedbackScreen").style.display = "block";
    }
    
    /**
    * Recursive timer function.
    *
    * @param  {Number} seconds
    * @param  {String} label
    * @param  {Function} callback
    * @return {void}
    */
    function countdown(seconds, label, callback)
    {
      setLabel(label);
      setCounter(seconds);
    
      // Set timeout to next second
      countdownTimer = setTimeout(function ()
      {
        // Decrease seconds.
        seconds--;
    
        // Check whether the countdown is over - execute callback if so.
        if (seconds <= 0)
        {
          return callback();
        }
    
        // Call itself with a lower number otherwise.
        countdown(seconds, label, callback);
      }, 1000); // (1 sec).
    }
    
    /**
    * Set counter text.
    *
    * @param  {Number} val
    * @return {void}
    */
    function setCounter(val)
    {
      counter.innerHTML = val;
    }
    
    /**
    * Set label text.
    *
    * @param  {String} text
    * @return {void}
    */
    function setLabel(text)
    {
      if (label.textContent === text)
      {
        return;
      }
      label.innerHTML = text;
    }
    
    /**
    * Set button text.
    *
    * @param  {String} text
    * @return {void}
    */
    function setButtonText(label)
    {
      button.innerHTML = label;
    }
    <div id="exerciseLabel"></div>
    <button id="pauseButton"></button>
    <div id="exerciseCounter"></div>
    <div id="info"></div>
  • 0
    Вы не сохраняете текущую информацию об игровом упражнении, ее нужно сохранять при приостановке и запросе при возобновлении / воспроизведении.
  • 0
    Вы можете использовать window.localstorage для хранения места остановки цикла; это может быть то, что вам нужно stackoverflow.com/questions/46957249/…
Показать ещё 7 комментариев
Теги:

1 ответ

1
Лучший ответ

var pause = false;
var displayBreak = false;

 window.onload = function() {
    initCounter();
 };

 var count;
 var counter;
 var current = 0
var element = document.getElementById("exerciseLabel");
  var workout =
{
  "title": "Full Body",
  "exercises":
  [
    {
      "name": "Push Ups",
      "duration": 1,
      "break": 2
    },
    {
      "name": "Squats",
      "duration": 2,
      "break": 0.5
    },
    {
      "name": "Running in place",
      "duration": 0.25,
      "break": 1
    }
  ]
};

 function initCounter() {
 
    count = workout.exercises[0].duration*60; 
    breakCount = workout.exercises[0].break*60;
    launchTimer();
  }

 function timer() {
    
    if(displayBreak){
      breakCount = breakCount - 1;
    }
    else{
    count = count -1;
    }
    
    var seconds = (displayBreak ? breakCount : count ) % 60;
    
    var minutes = Math.floor((displayBreak ? breakCount : count ) / 60);
    var hours = Math.floor(minutes / 60);
    minutes %= 60;
    
    document.getElementById("timer").innerHTML = ""+ hours + ":" + minutes + ":" + seconds
    display();

   if(seconds === 0 && minutes === 0 && hours === 0)
   	{
    //After duration of exercise or break
      if(!(current === workout.exercises.length - 1  && displayBreak === true)){
      // Display the next exercise or break
      displayBreak = !displayBreak;
      display();
        if(!displayBreak){
        current = current + 1 ;
        //set break duration
        breakCount = (workout.exercises[current].break)*60;
        }
        else{
        //set next exercise duration
        if(current < workout.exercises.length - 1){
        count = (workout.exercises[current + 1].duration)*60;
        }
        }
       }
      else
       {
        // All the exercises have already been displayed
        clearInterval(counter);
        pauseButton.innerHTML = "end";
       }   
     
      }
      
      }
      
function launchTimer(){
counter = setInterval(timer, 100); //(I put 100 to make it quick) 1000 will  run it every 1 second
}
  
function pauseOrResume(){
  pause = !pause
  if(pauseButton.innerHTML !== "end"){
    if(pause){
    clearInterval(counter);
    pauseButton.innerHTML = "resume"
  }
  else {
        launchTimer();
        pauseButton.innerHTML = "pause"
    }

  }
  }
  
  function display(){
    if(!displayBreak){
    element.innerHTML = workout.exercises[current].name
    }
    else{
    element.innerHTML = "break"
    }
  }
<script type="text/javascript">
 
 </script>


<div id="timer"></div>

<div id="exerciseLabel"></div>
<button id="pauseButton" onclick="pauseOrResume()">pause</button>
<div id="exerciseCounter"></div>
<div id="info"></div>
  • 0
    Это хорошо и работает, но счетчик, похоже, пропускает значение Break?
  • 1
    @ Брайан, я обновил код с учетом перерывов. И вы даже можете установить другую продолжительность для перерывов и упражнений
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню