1

Doing Infix to PostFix Stack Implementation using HTML5 canvas. The desired output is, element box in the canvas must have to output every character for 1 sec and then fade away. While the problem is element box in the canvas is updating after the code execution finished, which results in overlapping of all the character in the canvas element box and then fading out after 1 sec.

Please have a look at the code below:

function convert(e){         // when convert button click
    var x = document.getElementById('infix').value;
    var stack = new Stack();
    stack.postFix(x);
}

function elementVisualize(ele){
    var eleVis = canvas.getContext('2d');

    eleVis.fillText(ele,150,150);
    console.log(ele);

    setTimeout(function(){
        eleVis.clearRect(100,80,148,148);
    }, 1000);
}

postFix(exp){           // Stack.postFix function
    for(var i = 0; i < exp.length ; i++){
        var c = exp[i];
        if((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z')){
            elementVisualize(c);
        }
    }

}

is their anyway to update the canvas for each character separately ?

daedsidog
  • 1,732
  • 2
  • 17
  • 36
Noor Muhammad
  • 73
  • 3
  • 10
  • `setTimeout` is not "waited for" - otherwise, why would you need to put stuff in the callback – Jaromanda X Dec 04 '18 at 05:29
  • There is nothing that would generate a fading here. Do you have only visible/hidden states or is there really a fadeout to be implemented? – Kaiido Dec 04 '18 at 05:39

1 Answers1

0

One option would be for elementVisualize to return a Promise that resolves when the rectangle is cleared, and to await that Promise on every iteration of the for loop:

function elementVisualize(ele){
    var eleVis = canvas.getContext('2d');

    eleVis.fillText(ele,150,150);

    return new Promise((resolve) => {
        setTimeout(function(){ 
            eleVis.clearRect(100,80,148,148);
            resolve();
        }, 1000);
    });
}

async postFix(exp){           // Stack.postFix function
     for(var i = 0; i < exp.length ; i++){
     var c = exp[i];
     if((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z')){
           await elementVisualize(c);
     }
}

If the postFix method can also be called again before all animations are done, and you want it to wait for the previous postFix call's animations to finish, you might consider a persistent queue of sorts, to which postFix pushes items (the characters of exp), and have elementVisualize shift() an item from that array and then call itself again after the animation if there some characters remain in the array.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thanks Alot @CertainPerformance. It worked as per my need :) Can you please refer me to something I can get my hands clear on JS. (Noobie here) – Noor Muhammad Dec 04 '18 at 05:45
  • You mean a tutorial? I don't know, sorry, I've never taken one myself, I've learned mostly just from Google, MDN docs, and here :) – CertainPerformance Dec 04 '18 at 05:47