【问题标题】:How to write an animation with javascript canvas without clearRect function?如何在没有 clearRect 函数的情况下使用 javascript canvas 编写动画?
【发布时间】:2022-12-11 14:06:39
【问题描述】:

我有一个包含画布对象的网页,我应该制作画布描绘的图形的动画。 在同一区域我已经绘制了其他图形,因此我无法使用 drawRect 函数在动画的每个循环中擦除图形。我该如何解决?

我的网页的完整代码:

<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Animazioni con canvas</title>
<link rel="stylesheet" type="text/css" href="stile.css">
<script type="text/javascript" src="codice.js"></script>
</head>
<body>
<canvas id="mycanvas">canvas not supported.</canvas>
<script>
let mycanvas = document.getElementById("mycanvas");
let ctx = mycanvas.getContext("2d");
mycanvas.width = 600;
mycanvas.height = 400;

ctx.fillStyle = "greenyellow";
ctx.fillRect(10,10,100,100);

const step = 5;
let x = 0;

let loop = () => {
  ctx.clearRect(0, 0, mycanvas.width, mycanvas.height);  
  ctx.beginPath();
  ctx.arc(x, 200, 50, 0, 2 * Math.PI);
  ctx.stroke(); 
  x = x + step;
  x === mycanvas.width + 50 && (x = -50)
  requestAnimationFrame(loop)
};

requestAnimationFrame(loop)
</script>
</body>
</html>

我是 html、css 和 javascript 技术的初学者。我尝试了不同的解决方案,在互联网上寻找它们,但我不知道如何进行,所以在这个网站上询问如何解决问题。

【问题讨论】:

  • 您必须清除画布,然后在每一帧中绘制每个图形
  • @Konrad 谢谢你的回答。我知道要在每一帧中绘制图形,必须不断清除画布。但是这个操作在我的代码中很难,因为我在问题中只写了网站的一个页面,在这个页面很容易,但是在其他页面的另一个画布上,我在画布上固定了一个背景,并且包含 for 循环的 javascript 函数,其中包含图形的绘制。每个图形都应该有一个动画。所以,我无法擦除背景和已经绘制的对象。
  • 没有别的办法。你可以使用 webgl 但它更难
  • 你能清除需要重新绘制的区域的较小矩形吗?还有一些方法可以清除路径内的区域。这能解决你的问题吗?

标签: javascript html canvas


【解决方案1】:

这是不必重新绘制所有内容的三种可能方法。哪一个最适合你将取决于你需要用画布做的所有其他事情。在每个示例中,都有一个渐变背景和四个数字。右下图是动画的,每帧都重新绘制,其他的不是。

第一个在this fiddle。它在动画人物周围创建一个剪裁矩形:

context.beginPath();
context.rect(figureCenter - figureSize, figureCenter - figureSize, figureCenter * 2, figureSize * 2);
context.clip();

通过这样做,它可以调用 drawBackground 函数,这将覆盖画布中的所有内容,但只有图形后面的背景部分(在裁剪矩形内)被重绘。然后绘制动画人物。其他图形不必重新绘制。

因此,您可以重绘可能位于要更新区域中的所有内容,而不必担心会在更新区域之外绘制的任何内容。裁剪区域不必是正方形。

第二个例子在this fiddle。它有两个覆盖的画布元素。底部是背景,顶部是人物。这允许它在不擦除背景的情况下清除动画区域周围的矩形。

context.clearRect(figureCenter - figureSize, figureCenter - figureSize, figureCenter * 2, figureSize * 2);

通过使用这样的图层,您可以将动画内容放在一个画布上,将静态内容放在其他画布上。

最后是this fiddle。它使用一个 OffscreenCanvas,所有没有动画的东西都会被绘制到它上面,然后每帧屏幕外画布的内容都会重新绘制到可见画布上:

context.drawImage(offscreenCanvas,0,0);

使用此方法,您可以存储绘制的内容以在以后的帧中重复使用。

这个答案比我预期的要长,但没有一种解决方案适用于所有情况。

【讨论】:

    猜你喜欢
    • 2011-12-25
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多