Search code examples
javascripthtmlsetintervalstopwatch

When my stopwatch updates with setInterval, it blinks, how to make it smooth?


Hi i made a stopwatch in javascript and every time it updates, it deletes, and then after a second appears again and deletes. So every second it appears and disappears, making it blink. How can i make it appear until the next second updates, making a smooth transition.

Here is my code:

function GameTimer() {
  var gameTimeMinutes = 0;
  var gameTimeSeconds = 0;
  var gameTime = "";

  this.addTime = function() {
    gameTimeSeconds += 1;
    if (gameTimeSeconds < 10) {
      gameTime = gameTimeMinutes + " : 0" + gameTimeSeconds;
    } else {
      gameTime = gameTimeMinutes + " : " + gameTimeSeconds;
    }

    if (gameTimeSeconds == 60) {
      gameTimeSeconds = 0;
      gameTimeMinutes++;
    }
  };

  this.draw = function() {
    graph.clearRect(0, 0, canvas.width, canvas.height);
    var fontSize = 25;
    graph.lineWidth = playerConfig.textBorderSize;
    graph.fillStyle = playerConfig.textColor;
    graph.strokeStyle = playerConfig.textBorder;
    graph.miterLimit = 1;
    graph.lineJoin = 'round';
    graph.textAlign = 'right';
    graph.textBaseline = 'middle';
    graph.font = 'bold ' + fontSize + 'px sans-serif';
    graph.strokeText(gameTime, 100, 30);
    graph.fillText(gameTime, 100, 30);
  };

  this.update = function() {
    this.addTime();
    this.draw();
  }.bind(this);

  this.update();
}

var playerConfig = {textBorderSize: "1px", textColor: "black", textBorder: "solid"};
var canvas = document.getElementById("timer");
var graph = canvas.getContext("2d");
var gameTimer = new GameTimer();
setInterval(gameTimer.update, 1000);
<canvas id="timer" width="200" height="100"></canvas>

So just to clarify, i tried changing the interval time to ten seconds, and every ten seconds it appears and disappears, meaning that it is gone for the next ten seconds until it appears and disappears again. It doesn't stay there until the next update.

Thanks!


Solution

  • I believe that the flashing could be a result of setInterval not synchronizing with the screen's refresh rate. If so, requestAnimationFrame may be able to solve this.

    This does use unnecessary system resources, but may solve your problem regardless.

    Try this:

    this.timeUntilUpdate = Date.now();
    this.update = function(){
        if(Date.now() - this.timeUntilUpdate > 1000){
            this.addTime();
            this.draw();
        }
        requestAnimationFrame(this.update);
    }
    

    And then at the end replace setInterval(gameTimer.update, 1000); with requestAnimationFrame(GameTimer.update) or possibly just GameTimer.update();