Question:
I am trying to draw a matrix of squares on a canvas depending on the number of elements in the array. The task is to draw the squares gradually, that is, first arr [0] [0], then after a short delay arr [0] [1], and so on. I draw all the squares at once. Even if I try to delay using setTimeout (), after the delay all the squares appear instead of being drawn one at a time.
Any thoughts on this would be appreciated. Thank you.
My code:
var drawingCanvas = document.getElementById('myCanvas');
if(drawingCanvas && drawingCanvas.getContext) {
var context = drawingCanvas.getContext('2d');
var arr = <?=json_encode($arr) ?>;
console.log(arr);
var x = 0;
var y = 50;
var timer = 1000;
function animate(){
context.stroke();
}
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
context.rect(x, y, 50, 50);
setTimeout(animate, timer);
context.textAlign = "center";
context.font = "12px Arial";
context.fillStyle = "black";
context.fillText(arr[i][j],x+25,y+28, 50);
x = x + 50;
timer = timer+1000;
}
x=0;
y=y+50;
}
}
Answer:
It is possible through setTimeout
. We pass the drawing function, and so that the variables are not lost, we wrap the function through bind
and pass all the necessary variables
var drawingCanvas = document.getElementById('myCanvas');
if (drawingCanvas && drawingCanvas.getContext) {
var context = drawingCanvas.getContext('2d');
var arr = [
['a', 'b'],
['c', 'd']
];
var x = 0;
var y = 50;
var c = 0;
context.textAlign = "center";
context.font = "12px Arial";
context.fillStyle = "black";
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
setTimeout(function(x, y,num) {
context.strokeRect(x, y, 50, 50);
context.fillText(num, x + 25, y + 28, 50);
}.bind(this, x, y, arr[i][j]), (c++) * 500);
x = x + 50;
}
x = 0;
y = y + 50;
}
}
<canvas id="myCanvas"></canvas>