user3123418
user3123418

Reputation: 45

javascript canvas function not working without an alert

I'm doing some demo web pages as part of a portfolio to show potential employers.
One page is the simulation of a plasma arc in a 'plasma ball' which then rotates to view the 'arc' through 360 degrees.
The redraw of the arc through each of the rotations ONLY works if I put an 'alert' after each redraw and then cancel the alerts when the script runs. Without the alert, nothing happens.

Does anyone have an explanation/solution for this? Here's the redraw function:

function reDraw(yAngle) //work in progress - redraw the arc through 360 degrees to see the path
{
   var xCs;
   var yCs;

   for(degrees=10; degrees<360; degrees+=1)//spin sphere through 360 degrees
   {   

      context1 = document.getElementById("canvas1").getContext("2d");

      context1.clearRect(0,0,600,600);

      radialGrad(1,'canvas1',300,300,300,300,300,0,0,1,colour1,colour2,0,0,600,600);

      firstMove=true;

      for(moves=0; moves<axisMove; moves++)
      {
         if(firstMove)//start at centre of sphere for each re-draw
         {
            xCs=300;
            yCs=300;
            firstMove=false;         
         }

         context1.beginPath();

         context1.moveTo(xCs,yCs);         

         spinAngle=(degrees/180*Math.PI);

         //we are spinning in the X-Z plane so resolve X-Z moves only - retrieve each positive or negative move from the axis move arrays

         xCs=xCs+(zCStep[moves]*Math.sin(spinAngle))+(xCStep[moves]*Math.cos(spinAngle));

         yCs=yCs+yCStep[moves];

         context1.lineTo(xCs,yCs);

         context1.shadowBlur=2;
         context1.shadowColor="grey";

         context1.strokeStyle="white";
         context1.stroke();

      }
      alert();   
   }

}

Upvotes: 3

Views: 595

Answers (2)

GitaarLAB
GitaarLAB

Reputation: 14665

Due to their (historically) single-threaded nature, Webbrowsers re-draw content when a (javascript) function(handler) ends (same problem with progress bars, ajax-loading gif, etc).
So, even when one iteration of your loop would take a full second (resulting in 1FPS), the canvas still wouldn't redraw (same goes for the rest of the page's content) until your javascript ends.

Small side note: one of the biggest advantages of HTML5 web-workers is that they run in their own thread so they don't 'block the browser'.

The (historically) common solution to the above problems is to use a timer (setInterval seems best for your particular case, or setTimeout) in order to have the browser redraw the content (in this case the canvas-element).

EDIT:
Stefano Ortisi reminded me in his comment below about requestAnimationFrame and provided an excellent link: http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
Basically it's main reason for existence is so we don't need to keep using the same timers, having a browser-optimised implementation (vs timers) and ideally to use it together with webworkers (yay, extra thread).

At first this API was quite a 'living' specification (which is why I forgot about it), but by now the dust seems to have settled enough to create a nice polyfill (see above link).
I agree that anno dec. 2013 this is a better solution then defining your own timer, since "if you’re running the animation loop in a tab that’s not visible, the browser won’t keep it running, which means less CPU, GPU, and memory usage, leading to much longer battery life."

Upvotes: 1

c-smile
c-smile

Reputation: 27480

By its definition the <canvas> element uses bitmap buffer. You can think about the <canvas> as of <img> with modifiable bitmap.

Script draws in that bitmap (but not on the screen). And browser renders that bitmap when it has the chance.

To give the browser a chance to draw your bitmap at some step you should yield execution from your script to the browser in some way: call alert(), setTimeout/Interval or do your drawing in animation frames ( requestAnimationFrame ).

requestAnimationFrame is pretty much a request to redraw the browser view that will happen after next 16ms (60 fps max in browsers) or so.

Upvotes: 0

Related Questions