清空 HTML 画布

3

我目前正在尝试创建一个画布,它具有背景和十字线样式的对象,可以跟随鼠标移动,除了十字线仍然显示在先前绘制的位置外,一切都正常运行。我不确定在何处清除画布,而不清除画布上的所有内容并重新绘制。以下是我的代码:

canvas = document.querySelector("canvas");
ctx = canvas.getContext("2d");

canvas.width = innerWidth;
canvas.height = innerHeight;

class Background {
    constructor(x, y, width, height, color) {
        this.x = x,
        this.y = y,
        this.width = width,
        this.height = height,
        this.color = color
    }

    drawBackground() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

const backgroundSky = new Background(0, 0, canvas.width, canvas.height, "#89CFF0");
const backgroundGrass = new Background(0, canvas.height/1.2,canvas.width, canvas.height, "green");
backgroundSky.drawBackground();
backgroundGrass.drawBackground();

class Lens {
    constructor(x, y, radius, color) {
        this.x = x,
        this.y = y,
        this.radius = radius,
        this.color = color
    }

    drawLens() {
        ctx.lineWidth = 10;
        ctx.strokeStyle = "black";
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
        ctx.stroke();
        ctx.fillStyle = this.color;
        ctx.fill();
    }
}

class Cross {
    constructor(x, y, width, height, color) {
        this.x = x,
        this.y = y,
        this.width = width,
        this.height = height,
        this.color = color
    }

    drawCross() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

addEventListener("mousemove", function(event) { 
    mouseX = event.clientX;
    mouseY = event.clientY;
    const crossX = new Cross(mouseX, 0, 10, canvas.height, "black");
    const crossY = new Cross(0, mouseY, canvas.width, 10, "black");
    const lens = new Lens(mouseX, mouseY, 250, "transparent");
    crossX.drawCross();
    crossY.drawCross();
    lens.drawLens();
});
* {
    margin: 0;
    overflow:hidden;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <canvas></canvas>
        <script src="index.js" async defer></script>
    </body>
</html>


2
这个回答解决了你的问题吗?HTML5在画布中删除之前绘制的对象 - ggorlen
@ggorlen 谢谢!希望我不会打扰你,但我不太常用JS,也不确定如何做到这一点。 - nickg
1
特别是,请参见重复线程中的第二个答案。我发布了一个答案,但它仍然应该是一个重复项,所以不需要接受或点赞。将来,如果您向此应用程序添加动画循环,请应用相同的技术。 - ggorlen
2个回答

1
清空整个屏幕并在每帧重新绘制它:
ctx.clearRect(0, 0, canvas.width, canvas.height);
backgroundSky.drawBackground();
backgroundGrass.drawBackground();
crossX.drawCross();
crossY.drawCross();
lens.drawLens();

Full code:

canvas = document.querySelector("canvas");
ctx = canvas.getContext("2d");

canvas.width = innerWidth;
canvas.height = innerHeight;

class Background {
    constructor(x, y, width, height, color) {
        this.x = x,
        this.y = y,
        this.width = width,
        this.height = height,
        this.color = color
    }

    drawBackground() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

const backgroundSky = new Background(0, 0, canvas.width, canvas.height, "#89CFF0");
const backgroundGrass = new Background(0, canvas.height/1.2,canvas.width, canvas.height, "green");

class Lens {
    constructor(x, y, radius, color) {
        this.x = x,
        this.y = y,
        this.radius = radius,
        this.color = color
    }

    drawLens() {
        ctx.lineWidth = 10;
        ctx.strokeStyle = "black";
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
        ctx.stroke();
        ctx.fillStyle = this.color;
        ctx.fill();
    }
}

class Cross {
    constructor(x, y, width, height, color) {
        this.x = x,
        this.y = y,
        this.width = width,
        this.height = height,
        this.color = color
    }

    drawCross() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

addEventListener("mousemove", function(event) { 
    mouseX = event.clientX;
    mouseY = event.clientY;
    const crossX = new Cross(mouseX, 0, 10, canvas.height, "black");
    const crossY = new Cross(0, mouseY, canvas.width, 10, "black");
    const lens = new Lens(mouseX, mouseY, 250, "transparent");
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    backgroundSky.drawBackground();
    backgroundGrass.drawBackground();
    crossX.drawCross();
    crossY.drawCross();
    lens.drawLens();
});
* {
    margin: 0;
    overflow:hidden;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <canvas></canvas>
        <script src="index.js" async defer></script>
    </body>
</html>


0

在绘制准星之前,您可以重新绘制背景。

您的mousemove事件监听函数将变为:

addEventListener("mousemove", function(event) { 
    mouseX = event.clientX;
    mouseY = event.clientY;
    const crossX = new Cross(mouseX, 0, 10, canvas.height, "black");
    const crossY = new Cross(0, mouseY, canvas.width, 10, "black");
    const lens = new Lens(mouseX, mouseY, 250, "transparent");
    backgroundSky.drawBackground(); // ⚠️
    backgroundGrass.drawBackground(); // ⚠️
    crossX.drawCross();
    crossY.drawCross();
    lens.drawLens();
});

canvas = document.querySelector("canvas");
ctx = canvas.getContext("2d");

canvas.width = innerWidth;
canvas.height = innerHeight;

class Background {
    constructor(x, y, width, height, color) {
        this.x = x,
        this.y = y,
        this.width = width,
        this.height = height,
        this.color = color
    }

    drawBackground() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

const backgroundSky = new Background(0, 0, canvas.width, canvas.height, "#89CFF0");
const backgroundGrass = new Background(0, canvas.height/1.2,canvas.width, canvas.height, "green");
backgroundSky.drawBackground();
backgroundGrass.drawBackground();

class Lens {
    constructor(x, y, radius, color) {
        this.x = x,
        this.y = y,
        this.radius = radius,
        this.color = color
    }

    drawLens() {
        ctx.lineWidth = 10;
        ctx.strokeStyle = "black";
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
        ctx.stroke();
        ctx.fillStyle = this.color;
        ctx.fill();
    }
}

class Cross {
    constructor(x, y, width, height, color) {
        this.x = x,
        this.y = y,
        this.width = width,
        this.height = height,
        this.color = color
    }

    drawCross() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

addEventListener("mousemove", function(event) { 
    mouseX = event.clientX;
    mouseY = event.clientY;
    const crossX = new Cross(mouseX, 0, 10, canvas.height, "black");
    const crossY = new Cross(0, mouseY, canvas.width, 10, "black");
    const lens = new Lens(mouseX, mouseY, 250, "transparent");
    backgroundSky.drawBackground(); // ⚠️
    backgroundGrass.drawBackground(); // ⚠️
    crossX.drawCross();
    crossY.drawCross();
    lens.drawLens();
});
* {
    margin: 0;
    overflow:hidden;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <canvas></canvas>
        <script src="index.js" async defer></script>
    </body>
</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接