Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
402 views
in Technique[技术] by (71.8m points)

javascript - Erasing previously drawn lines on an HTML5 canvas

To play around with HTML5 canvas, I decided to make an app which draws an analogue clockface. Everything's fine, except that old lines don't get erased in the way that I would expect. I've included part of the code below - DrawHands() gets called once a second:

var hoursPoint = new Object();
var minutesPoint = new Object();
var secondsPoint = new Object();

function drawHands()
{
    var now = new Date();

    drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "white", 1);
    var seconds = now.getSeconds();
    secondsPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * seconds, 0.75 * radius);
    drawLine(centerX, centerY, secondsPoint.X, secondsPoint.Y, "black", 1);

    drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "white", 3);
    var minutes = now.getMinutes();
    minutesPoint = getOtherEndOfLine(centerX, centerY, 2 * Math.PI / 60 * minutes, 0.75 * radius);
    drawLine(centerX, centerY, minutesPoint.X, minutesPoint.Y, "black", 3);

    drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "white", 3);
    var hours = now.getHours();
    if (hours >= 12) { hours -= 12; } // Hours are 0-11
    hoursPoint = getOtherEndOfLine(centerX, centerY, (2 * Math.PI / 12 * hours) + (2 * Math.PI / 12 / 60 * minutes), 0.6 * radius);
    drawLine(centerX, centerY, hoursPoint.X, hoursPoint.Y, "black", 3);
}

To make sense of the above, there are two helper functions:

  • drawLine(x1, y1, x2, y2, color, thickness)
  • getOtherEndOfLine(x, y, angle, length)

The problem is that while all the hands get drawn as expected in black, they never get erased. I would expect that since the same line is drawn in white (the background colour) it would effectively erase what was previously drawn at that point. But this doesn't seem to be the case.

Anything I'm missing?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Instead of erasing the things you don't want you can:

  1. save the state of the canvas
  2. draw the things you don't want
  3. restore the canvas to the saved state to 'erase' them

This can be accomplished pretty easily using ImageData:

var canvas = document.querySelector('canvas'),
    context = canvas.getContext('2d');

context.fillStyle = 'blue';
context.fillRect(0,0,200,200);

// save the state of  the canvas here
var imageData = context.getImageData(0,0,canvas.width,canvas.height);

// draw a red rectangle that we'll get rid of in a second
context.fillStyle = 'red';
context.fillRect(50,50,100,100);

setTimeout(function () {
    // return the canvas to the state right after we drew the blue rect
    context.putImageData(imageData, 0, 0);
}, 1000);
<canvas width=200 height=200>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...