0

I'm trying to figure out why drawing a shape, then drawing over it in a new color (as though to highlight it), and then re-drawing the original (un-highlighting it) is leaving traces of the highlighted color.

I've reproduced the issue in this fiddle. The wedge is drawn in a light-blue color. There's a red button that'll draw over it in red, then another button that re-draws the original shape. All parameters are identical (except for the color), but yet after clicking the button to reset the color, there's a faint trace of red over the wedge.

Before:

enter image description here

After:

enter image description here

Here's the relevant code:

drawWedge(250, 250, 200, 0, 18, "rgb(150, 254, 223)");

$("#red").click(function () {
    drawWedge(250, 250, 200, 0, 18, "rgb(255, 0, 0)");
});

$("#back").click(function () {
    drawWedge(250, 250, 200, 0, 18, "rgb(150, 254, 223)");
});

function d2r(degrees) {
    return degrees * (Math.PI / 180.0);
}

function drawWedge(centerX, centerY, r, start, end, color) {
    context.beginPath();
    context.moveTo(centerX, centerY);
    context.arc(centerX, centerY, r, d2r(start), d2r(end), false);
    context.closePath();
    context.fillStyle = color;
    context.fill();
}
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • 1
    Are you purposely not clearing the canvas before drawing new frame? If not, then the fix is simple: http://jsfiddle.net/X7deh/1/ – Esailija Jan 12 '12 at 23:06
  • @Esailija - just learning canvas, so I'm not doing anything purposefully. Throw that up - it's the correct answer. – Adam Rackis Jan 12 '12 at 23:16
  • @Esailija - I just looked up that method and it seems it does what its name implies. I can't really clear a rectangle around this wedge because there will be many others right next to it. (I'm making a pie chart for fun). There's not clearArc method, so what would you recommend – Adam Rackis Jan 12 '12 at 23:19

2 Answers2

2

This question was already answered, but I wanted to give a little more thorough explanation.

enter image description here

When you draw at a diagonal, your passing through "parts" of pixels (show in my example). So what does the browser do to the part of the pixel outside of the shape? It uses anti-aliasing (anti-aliasing is always on by default for browsers) to color the rest of the pixel (if you didnt have anti-aliasing the line would look jagged). If you notice, the faint trace of red is not a bright red because its getting blended due to anti-aliasing. And the reason you see it is because when you draw your shape on the canvas, the faint trace of red is not part of your shape, its part of the pixel on the outside of your shape.

Now as the answer mentioned, you can call clearRect to clear the canvas. However, you should read this SO question as it explains things in more detail (the selected answer is not as good as the second answer). Also, ever wonder why they call it a "canvas"? Think of an actual art canvas used by artists, once they paint on the canvas there is no way to take it off unless you get a new canvas or paint over it!

Community
  • 1
  • 1
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
1

When drawing on canvas, it just keeps stacking things on top of each other until you clear it. The easiest way to clear it is ctx.clearRect(0,0,width,height)

I put that in your drawWedge function here:

http://jsfiddle.net/X7deh/1

Esailija
  • 138,174
  • 23
  • 272
  • 326
  • See my comment above. So if I were making a pie chart, would you recommend I just clear the whole chart and re-draw just to get a wedge highlighted/unhilighted? That hardly seems efficient – Adam Rackis Jan 12 '12 at 23:21
  • @AdamRackis you are correct, it's not efficient. Sooner or later you have to clear the canvas and paint a new frame. To highlight, you would redraw the entire pie chart with that highlighted wedge in different color. I never had any performance problems with this though, if that helps. – Esailija Jan 12 '12 at 23:24
  • Re-drawing each time would actually make my code much cleaer, so I'll pursue that, but out of curiosity, do you know why *this example* didn't work? Shouldn't those arcs have been identical in size? – Adam Rackis Jan 12 '12 at 23:40
  • @AdamRackis Well the wedge is complex on the edges, it isn't one solid color but emulated partial pixels, so when you draw on top of old one you will get that effect on the edges because the partial pixels keep stacking up. This is related http://www.codinghorror.com/blog/2011/12/fast-approximate-anti-aliasing-fxaa.html – Esailija Jan 12 '12 at 23:41