一个非常简单的方法是在同一屏幕位置上有两个canvas元素,并设置所需显示的缓冲的可见性。在隐藏的画布上绘制,完成后翻转即可。
一些代码:
CSS:
A very simple method is to have two canvas-elements at the same screen location and set visibility for the buffer that you need to show. Draw on the hidden and flip when you are done.
Some code:
CSS:
canvas { border: 2px solid #000; position:absolute; top:0;left:0;
visibility: hidden; }
JS中的翻转操作:
Buffers[1-DrawingBuffer].style.visibility='hidden';
Buffers[DrawingBuffer].style.visibility='visible';
DrawingBuffer=1-DrawingBuffer;
在这段代码中,数组 'Buffers[]' 包含了两个canvas对象。因此当你想要开始绘制时,仍然需要获取上下文(context):var context = Buffers[DrawingBuffer].getContext('2d');
<noscript>
,并在Javascript中创建我的画布元素。您通常会想要在Javascript中检查canvas支持,那么为什么要在HTML中放置canvas回退消息呢? - Sheahttps://web.dev/canvas-performance/
为了方便起见,我已经包括了一份最小的示例,展示了文章中描述的有效双缓冲技术。// canvas element in DOM
var canvas1 = document.getElementById('canvas1');
var context1 = canvas1.getContext('2d');
// buffer canvas
var canvas2 = document.createElement('canvas');
canvas2.width = 150;
canvas2.height = 150;
var context2 = canvas2.getContext('2d');
// create something on the canvas
context2.beginPath();
context2.moveTo(10,10);
context2.lineTo(10,30);
context2.stroke();
//render the buffered canvas onto the original canvas element
context1.drawImage(canvas2, 0, 0);
我测试过的所有浏览器都通过不在代码绘制帧完成之前不重新绘制画布来为您处理此缓冲区。请参见WHATWG邮件列表:http://www.mail-archive.com/whatwg@lists.whatwg.org/msg19969.html
var canvas2 = document.createElement("canvas");
而不将其附加到DOM中。display:none;
迷恋不已,
我觉得这样做更加干净,并更准确地模仿了双缓冲的思想,而不仅仅是拥有一个尴尬的不可见画布。var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
function draw_ball(ball) {
ctx.clearRect(0, 0, 400, 400);
ctx.fillStyle = "#FF0000";
ctx.beginPath();
ctx.arc(ball.x, ball.y, 30, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
}
var deltat = 1;
var ball = {};
ball.y = 0;
ball.x = 200;
ball.vy = 0;
ball.vx = 10;
ball.ay = 9.8;
ball.ax = 0.1;
function compute_position() {
if (ball.y > 370 && ball.vy > 0) {
ball.vy = -ball.vy * 84 / 86;
}
if (ball.x < 30) {
ball.vx = -ball.vx;
ball.ax = -ball.ax;
} else if (ball.x > 370) {
ball.vx = -ball.vx;
ball.ax = -ball.ax;
}
ball.ax = ball.ax / 2;
ball.vx = ball.vx * 185 / 186;
ball.y = ball.y + ball.vy * deltat + ball.ay * deltat * deltat / 2
ball.x = ball.x + ball.vx * deltat + ball.ax * deltat * deltat / 2
ball.vy = ball.vy + ball.ay * deltat
ball.vx = ball.vx + ball.ax * deltat
draw_ball(ball);
}
setInterval(compute_position, 40);
<!DOCTYPE html>
<html>
<head><title>Basketball</title></head>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
</body></html>
在Web浏览器中不存在闪烁问题!它们已经使用双缓冲技术进行渲染。JavaScript引擎会在显示之前完成所有渲染。此外,上下文保存和恢复仅堆栈转换矩阵数据等内容,而不是画布内容本身。 因此,您不需要或不想使用双缓冲技术!
你需要两个画布:(注意CSS的z-index和position:absolute)
<canvas id="layer1" width="760" height="600" style=" position:absolute; top:0;left:0;
visibility: visible; z-index: 0; solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<canvas id="layer2" width="760" height="600" style="position:absolute; top:0;left:0;
visibility: visible; z-index: 1; solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
您可以注意到第一个画布是可见的,而第二个则被隐藏了。这样做的目的是在隐藏的画布上绘制,随后我们将隐藏可见的画布并使隐藏的画布变为可见。当它被隐藏时 '清除隐藏画布'
<script type="text/javascript">
var buff=new Array(2);
buff[0]=document.getElementById("layer1");
buff[1]=document.getElementById("layer2");
ctx[0]=buff[0].getContext("2d");
ctx[1]=buff[1].getContext("2d");
var current=0;
// draw the canvas (ctx[ current ]);
buff[1- current ].style.visibility='hidden';
buff[ current ].style.visibility='visible';
ctx[1-current].clearRect(0,0,760,600);
current =1-current;
与其自己动手写,使用现有的库来创建干净、无闪烁的JavaScript动画可能会更好:
这里有一个受欢迎的库:http://processingjs.org
explorercanvas
时,IE在某些情况下会闪烁,但这当然不是HTML5,而只是由VML模拟的canvas
元素。我从未见过其他浏览器这样做。 - cryo