Home > Software design >  How to synchronize some counters all increasing at the same rate and ending at different values
How to synchronize some counters all increasing at the same rate and ending at different values

Time:09-25

I have 4 span elements inside an HTML document starting at 0, and i want to increase their value by 1 till they arrive at a marked value.

They all should end at the same time even with different values.

This is the function that i'm using, the item param is the span and the number is the number where i want to stop increasing the value.

let animateNumberInItem = (number,item) =>{
  let startingNum = 0;
  let animationSpeed = 0;

  
  let interval = setInterval(()=>{
    if(startingNum === number-1){
      clearInterval(interval);
    }
    startingNum  ;
    item.innerHTML = startingNum;
  },animationSpeed);
};

Any idea on how to calculate the time required to reach the number in milliseconds using the number value?

Another solution could be changing the number by which they increase or/and the time to make them end at the same time.

CodePudding user response:

If you increase the startingNum based on the ratio in which target numbers are present, then they will reach the target at the same time.

let animateNumberInItem = (number,item, ratio) =>{
  let startingNum = 0;
  let animationSpeed = 30;
  
  let interval = setInterval(()=>{
    if(startingNum >= number){
      clearInterval(interval);
    } else {
      // Increase the startingNum based on the ratio in which target number is present
       startingNum  = ratio;
      item.innerHTML = Math.round(startingNum);
    }
   
  },animationSpeed);
};

// e.g. first element has to reach target of 201 and second element has to reach target of 100
const ratio = 100/201;
animateNumberInItem(201, document.getElementById('first'), 1);
animateNumberInItem(100, document.getElementById('second'), ratio);
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <span id="first">0</span>
  <span id="second">0</span>
</body>
</html>

CodePudding user response:

I just found the solution and it's easier than it seems.

This is the edited function:

let animateNumberInItem = (number,item) =>{
  let startingNum = 0;
  let animationSpeed = 30;
  let animationGrowNumber = number / 100;
  
  let interval = setInterval(()=>{
    if(startingNum >= number- animationGrowNumber){
      clearInterval(interval);
    }
    startingNum =animationGrowNumber;
    item.innerHTML = Math.round(startingNum);
  },animationSpeed);
};

You just need to divide the number between a value (i used 100 because it gives a smoother animation) and then set that as the increasing value.

It will not increase by 1 but the animation looks good anyways, you can also set the time that you want because it doesn't affect the end result, only the animation appearence.

  • Related