Johannes Staehlin
Johannes Staehlin

Reputation: 3720

canvas: wait between line strokes / js sleep()

I'm using canvas to draw a chart. I would like make it "animated", which means you can see how the lines are drawn. So I implemented a small "sleep" function. But now it waits the sum of ms of all sleep() callings before it starts drawing anything in the canvas. How can I make it waiting between each stroke?

function sleep(ms) {
    var time = new Date();
    time.setTime(time.getTime() + ms);
    while (new Date().getTime() < time.getTime()) {}
}

//this is how i use it, let me know if you need the whole context.

for ( var columnID in columns) {
    var tempX = startX;
    var tempY = startY;

    this.ctx.beginPath();
    this.ctx.strokeStyle = this.colors[columnID];
    for ( var key in this.data) {
        tempY = startY - this.data[key][columns[columnID]] * 2;
        tempX = tempX + stepWidth;
        this.ctx.lineTo(tempX, tempY);
        this.ctx.stroke();
        sleep(50);
        }
        this.ctx.closePath();
    }

//UDATE: setTimeout() is also beeing ignored:

jsfiddle(it messed up the scale, using fixed json, but it shows the context of my script)

Upvotes: 1

Views: 5431

Answers (3)

Flight Dude
Flight Dude

Reputation: 129

Waiting/Sleep in JavaScript

Okay, so there are two ways to tackle this. One is using the setTimeout() function.

setTimeout(() => {
  // Your code goes here
}, <time in miliseconds>)

setTimeout contains a callback and a second parameter for time in ms.
The second way of attacking this issue is by creating a sleep function.

function sleep(ms) {
  let currentTime = Date.now()
  while(currentTime + ms > Date.now()) {}
}

// Use it like so

console.log("This is printed first")
sleep(1000)
console.log("This is printed 1000ms (1s) from the first console.log")

Upvotes: 0

Diode
Diode

Reputation: 25135

You can use setTimeOut or setInterval in Javascript. These functions don't pause the execution, but sets a callback function which will be invoked after the given delay, and the syntax is as given below

setTimeout(function-identifier, delay, params);

e.g:

function doit(param1, param2){


} 

setTimeout(doit, 500, 20, 20);

In your case it should be

setTimeout(this.drawLine, 100, x, y);

and you have to pass this also, so it becomes

setTimeout(this.drawLine, 100, this, x, y);
....
....
this.drawLine = function(_this, x, y) {
    _this.ctx.lineTo(x, y);
    _this.ctx.stroke();
    console.log("draw line " + x + "/" + y);
};

And in your function you are calling setTimeout inside a loop which will make no difference in the time between the plotting of two consecutive points in the array. Instead it plots all the points after the given delay. So you have add a delay there. This way I have fixed your version of code.

see it : http://jsfiddle.net/diode/pQ4Qg/9/

But the right way to do this is to create a 2 dimensional array of points and use two functions : One to switch the path and other to draw each path.

demo here : http://jsfiddle.net/diode/pQ4Qg/11/

You can tweak this to achieve what you require.

Upvotes: 4

Josh Leitzel
Josh Leitzel

Reputation: 15199

Your sleep function is unnecessary. You can use the built-in JavaScript function setTimeout or setInterval, depending on your needs.

Upvotes: 0

Related Questions