CaraGee CaraGee - 2 years ago 94
jQuery Question

How to clear only the animated section of the canvas between loops

The animation linked in this JSFiddle should show an EKG style machine, with a set of lines scrolling across the screen, which repeats on a loop after reverting briefly to a blank screen.

It's a modification of some great HTML5 Canvas a clipping animation sample code (

First loop works a charm but there are some flickering artefacts from then on.

How do I to 'revert' to the original look (machine image with a blank, black screen) before each iteration?

I thought c1.clearRect(0, 0, 386, 380); - line 42 of the JSFiddle - did that, but no joy.


function animateManaging() {
// Grabs the canvas element we made above
var ca1=document.getElementById("cvs3");

// Defines the 2d thing, standard for making a canvas
var c1=ca1.getContext("2d");

// Creates an image variable to hold and preload our image (can't do animations on an image unless its fully loaded)
var img1 = document.createElement('IMG');

// Loads image link into the img element we created above
img1.src = "";

// Creates the first save event, this gives us a base to clear our clipping / mask to since you can't just delete elements.;

// Our function for when the image loads
img1.onload = function () {
// clear off the canvas

// First call to our canvas drawing function, the thing that is going to do all the work for us.

// The function that is doing all the heavy lifting. The reason we are doing a function is because
// to make an animation we have to draw the circle (or element) frame by frame, to do this manually would be to time
// intensive so we are just going to create a loop to do it. 'i' stands for the radius of our border
// so over time our radius is going to get bigger and bigger.
function drawc1r(i) {
// Creates a save state. Imagine a save state like an array, when you clear one it pops last element in the array off the stack
// When you save, it creates an element at the top of the stack. So if we cleared without making new ones, we would end up with nothing on our stage.;

// This clears everything off the stage, I do this because our image has transparency, and restore() (the thing that pops one off the stack)
// Doesn't clear off images, and so if we stick an image on the stage over and over, the transparency will stack on top of each other and
// That isn't quite what we want.

c1.clearRect(0, 0, 386, 380);

// Adds one to the interval count

// Tells canvas we are going to start creating an item on the stage - it can be a line, a rectangle or any shape you draw, but whatever
// after this path will be added to the clip when its called. I can have 3 rectangles drawn and that would make a clip.

// make the clipping rectangle, using i to make it grow on each interval

// After everything is defined, we make a clip area out of it.

// Now that we have the clip added to it, we are going to add the image to the clip area.
c1.drawImage(img1, 0, 0);

// This pops one off the stack which gets rid of the clip so we can enlarge it and make it again on the next pass

// Here is the final size of the rectangle, I want it to grow until it hits 380 so we set a timeout to run this function again
// until we get the size we want. The time in milliseconds pretty much defines your framerate

if (i < 380) {
setTimeout(function () {
}, 100);

Answer Source

Biggest issue here is that you are calling animateManaging every six seconds, so you are creating many 'instances' of a drawer that will draw at the same time and create that flickering.

Rather than that, just call animateManaging once, and handle the loop yourself : what you want is, when right side is reached, to clear things and to restart on the left : remove your clearRect and change your last if to :

  if (i * moveSpeed < viewWidth) {
    // just resume if right side not reach
    setTimeout(function() {
    }, animInterval);
  } else {
    // clear and restart from 0 when right side reached.
    setTimeout(function() {
      c1.clearRect(0, 0, viewWidth, viewHeight);
    }, animInterval);

Besides that, i added some vars to avoid hard coded constants ( moveSpeed, viewWidth, viewHeight, animInterval), and i set the source of the image after setting the onload handler.

Following fiddle should be close to your needs :

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download