Question

Good day, Programmer:

I am looking to print out a series of strings, from an array, onto a canvas. Currently, it does not clear the canvas and prints all the text in a single iteration.

var test1 = ["This","is","a","test","to","see","if","it","really","works"];

function printWord(i){
    setTimeout( function(){ ctx.fillText(test1[i], 150, 90) }, 1000 ) }

function clearScreen(){
    ctx.clearRect(0, 0, 300, 100);
}

function playText(){
    for(var i = 0; i < test1.length; i++){
        clearScreen;
        printWord(i);
    };
}
playText();

Here is the JSFiddle. Updated link, thanks to Bigood for fixing the timing. Still require help with clearing the canvas.

Thank you,

LLCreatini

Was it helpful?

Solution

Your problem was that your loop was calling all those timeouts at once, not delaying the call. Instead, you need an interval and then clear it when you're finished with the array (I took some inspiration from this: setTimeout inside for loop). Here's a modified example, using the same approach as the link I posted:

var test1 = ["This","is","a","test","to","see","if","it","really","works."];

var c = document.getElementById("screen"); //Setup screen.
var ctx = c.getContext("2d");   
ctx.font = "normal 42px Arial";
ctx.textAlign= "center";
var i = 0;

function clearScreen(){
    ctx.clearRect(0, 0, 300, 100);
}

var timer = setInterval(function(){
    clearScreen();
    ctx.fillText(test1[i], 150, 91);
    i++; 
    if(i >= test1.length) {
        clearInterval(timer);
    }
}, 200);

timer();

And here's a link to the working JSFiddle

OTHER TIPS

Your script isn't printing everything in one iteration : in fact, the callback of your timeouts are called as many time as you asked (put a breakpoint to verify that).

The main problem here is that you initiate all the timeouts in the same time (with a few milliseconds of delay), so they all trigger at the same time.

To resolve this, you could use the index to set different timeouts for each word :

setTimeout( function(){ 
    ctx.fillText(test1[index], 150, 91);
}, 200 * index );  //Multiply by index, it'll trigger at 200ms, 400ms, 600ms...

See this fiddle for a demonstration!


Edit

If you want to clean the screen between each word, call your method clearScreen in the timeout, as following :

setTimeout( function(){ 
    clearScreen();
    ctx.fillText(test1[index], 150, 91);
}, 200 * index ); 

Here is a demonstration of this.

You don't need to use the for loop, the index of array can be handle by setTimeout() something like.

function printWord(index){
    setTimeout( function(){ 
        if(index < test1.length){
            ctx.fillText(test1[index], 150, 91);
            index++
            printWord(index);        
        }

    }, 1000);
}

function playText(){
   printWord(0);
}
playText();

DEMO

You essentially have two separate problems: Adding a delay between each text and clearing the canvas

Delay between each text

setTimeout is not blocking as in most other languages; code after the setTimeout statement will run before the timeout has hit.

Your code basically run printWord 10 times in a row, without any delay, with a different index, which will cause your setTimeout functions to be run at the same time.

If you need to have a delay, you can't use a regular for loop. You either have to multiply the delay with i, or do it this way (which I think looks more clean):

var i = 0;
function playNextText(){
    setTimeout(function () {
        printWord(i);

        i++;
        if(i < test1.length)
            //There are more texts left
            playNextText();
    }, 200);
}
playNextText();

Clearing the drawing area

Your other problem is very simple;

context.clearRect(x, y, width, height);

A complete example: http://jsfiddle.net/EUz7T/2/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top