0

In my example code i'm printing two seperate texts to a Canvas element. Both called to print from inside one function. Inside the function i have a for-loop which, for a specified amount of time, should clear the Canvas and print the first text. Once the for-loop ends it should then print the second text. Then setInterval calls the function again to clear the Canvas completely and print only the first text during the for-loop and the second text at the end of the loop. But the second text prints at the same time as the first text and it is never cleared. So it seems like the code in the for-loop doesn't execute until the for-loop comes to an end. But i also set up console.logs inside and outside the for-loop and the console log inside the for-loop executes in real time, and not at the end of the for-loop. So is it that console.log is a special case in this situation....yet other function calls inside a for-loop must wait till the end before execution? Note: Text won't show till 3 seconds after snippet is run because of the setInterval. Then the snippet page tends to lag, i think, because the for-loop runs for 1.5 secs. Just noticed that now because it wasnt doing that in my text editor.

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

function drawText(text, x, y, color, size) {
  ctx.font = size + 'px sans-serif';
  ctx.fillStyle = color;
  ctx.fillText(text, x, y);
}

function test() {
  var beginTime = Date.now();

  for (; Date.now() < beginTime + 1500;) {

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawText('Clear canvas and only show this', 100, 100, 'black', '20');

   // console.log('for loop ran');
  }

  drawText('Dont display this till for-loop stops clearing canvas', 100, 200, 'red', '20');

  // console.log('for loop finished');
}

setInterval(test, 3000);
<canvas id="canvas" width="800" height="600" style="border: 1px solid black"></canvas>
xxkaiwaxx
  • 115
  • 1
  • 2
  • 8
  • Longest text I've seen yet in a question, try making paragraphs into your question :PCode inside the for loop gets executed during the loop, as example: a break would never work otherwise. – seahorsepip Aug 23 '16 at 00:50
  • 1
    The canvas doesn't update until the event is exited, IE after both the for loop and code after the for loop. For example, if you make that loop an infinite loop, nothing will ever happen because the event loop can't run the code that re-draws the canvas onto the screen – Joseph Young Aug 23 '16 at 00:51
  • 1
    `for (; Date.now() < beginTime + 1500;)` <- this will iterate **many, MANY** times more than you think it will – Phil Aug 23 '16 at 00:52
  • 1
    http://stackoverflow.com/questions/4982631/how-to-force-a-display-update-in-canvas The code in the for loop does get executed but the browser has to wait till the for loop has finished to call it's redraw method since it's JavaScript engine is single threaded. If there was something like ``canvas.update`` you could put that in the for loop. Or add a setTimeout for 1ms in the for loop so the browser has 1ms to redraw, or use setInterval. – seahorsepip Aug 23 '16 at 01:00
  • @seahorsepip Yup thanks. Think i understand now. Will try using setTimeout for 1ms. – xxkaiwaxx Aug 23 '16 at 01:11
  • Using setInterval with clearInterval is a better idea though, and don't use small values like 1ms, poor browsers xD You should look into animationFrame, it runs the code as much as needed to get a proper fps and also runs the code fewer times if needed for the device to handle it. AnimationFrame is the best option for animations but if the code needs to be run on a specific interval then you should use setInterval as the name suggests. – seahorsepip Aug 23 '16 at 01:17

1 Answers1

1

Functions such as clearRect() and drawText() are only requests to perform the action as soon as the browser has an opportunity. However, that opportunity doesn't come until after the for loop finishes executing. When the browser finally has a chance to update the canvas, it will process the requests all at once. This means you will only see the final message.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • Hum everything called in the for loop will be executed in the for loop, otherwise you couldn't break it based on the result of a function call. Canvas manipulations are not delayed, it's done synchronously in the js flow. There is no repaint delay like with DOM manipulation since it is self-dependant, and that everything is done on the row pixels of the canvas. – Kaiido Aug 23 '16 at 02:49