Search code examples
javascriptparsefloat

parseFloat is doubling operand in animation


I'm very new to JavaScript and to coding in general. I'm creating an animation that expands and contract an image to simulate breathing. I am also adding a "breath count" to count the number of breaths. This is the code I used to create the breath count:

 <h1> Breath Number: <span id= "countingBreaths">0</span> </h1>

Then in the script tag:

//function for breath number increase
    var countingTo = function() {
      countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));

      var startCounting = setInterval(countingTo, 4000);

      var stopCounting = function () {
        clearInterval(startCounting);
      }
      stopButton.addEventListener("click", stopCounting);
    }

    startButton.addEventListener("click", countingTo);

My problem is in the parseFloat function. My intention is to increase the breath number by 1 (+1). But, instead, it is doubling my number (1, 2, 4, 8, 16, 32, etc). I'm not sure what I did wrong. I've tried everything and looked on this site for help but can't find any information. I'd really appreciate the help!


Solution

  • As Pointy wrote in the comment setInterval will create a timer that calls it's function every 4 seconds.

    And you start a new timer every time time the function runs, so eventually you have a lot of timers. And each one will increase your breathCount.

    Maybe you confused setInterval with setTimeout. Then every function call would only prepare the next one:

    var countingTo = function() {
      countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));
    
      var startCounting = setTimeout(countingTo, 4000);
    
    …
    

    But you still would add a new click eventListener to your stop button on every function call. That means your stop function would be called a lot of times. In your example it runs for each created interval.

    So you should move that out of your countingTo function like this:

    var intervalId = null
    var countingTo = function() {
      countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));
    }
    
    var startCounting = function () {
      intervalId = setInterval(countingTo, 4000);
    }
    
    var stopCounting = function () {
      clearInterval(intervalId);
    }
    
    startButton.addEventListener("click", startCounting);
    stopButton.addEventListener("click", stopCounting);
    

    Or with setTimeout:

    var timeoutId = null
    var countingTo = function() {
      countingBreaths.textContent = 1 + (parseFloat(countingBreaths.textContent));
    
      timeoutId = setTimeout(countingTo, 4000);
    }
    
    var stopCounting = function () {
      clearTimeout(timeoutId);
    }
    
    startButton.addEventListener("click", countingTo);
    stopButton.addEventListener("click", stopCounting);
    

    Also if you are doing animations you might want to look into requestAnimationFrame