Javascript Canvas一项闪烁

Javascript Canvas one item flickering

本文关键字:一项 闪烁 Canvas Javascript      更新时间:2023-09-26

我试图使两个对象在画布中彼此移动,当它们相遇并重叠时,一个应该消失,另一个应该下降。现在我让动画来做这个,但是其中一个项目在闪烁。

<!DOCTYPE html>
<html>
<head>
<style>
canvas{border:#666 3px solid;}
</style>
</head>
<body onload="draw(530,15); draw1(1,15);">
<canvas id="canvas" width="600" height="400"></canvas>
<script>
function draw(x,y){
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.save();
    ctx.clearRect(x, y, 600, 400);
    ctx.fillStyle = "rgba(0,200,0,1)";
    ctx.fillRect (x, y, 70, 50);
    ctx.restore(); 
    x -= 0.5;
	if(x==300)
	{
    return;
	};
    var loopTimer = setTimeout('draw('+x+','+y+')',5);
	};
	
	function draw1(w,e){
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.save();
    ctx.clearRect(w-1,e-2,600,400);
    ctx.fillStyle = "rgba(0,200,0,1)";
    ctx.fillRect (w, e, 70, 50);
    ctx.restore(); 
    w += 1;
	if(w==265)
	{
	w -= 1;
	e +=2;
	};
    var loopTimer = setTimeout('draw1('+w+','+e+')',10);
};
</script>
</body>  
</html>

我试了两天了,但似乎不能把它修好。

你每秒渲染太多帧,迫使浏览器呈现帧。每次draw函数返回时,浏览器都会假定您想要将该框架呈现给页面。

动画需要与显示刷新率同步,大多数设备的刷新率是60FPS。要做到这一点,你需要一个渲染循环来处理所有的动画。你通过requestAnimationFrame (RAF)调用这个函数,它确保动画与显示硬件和浏览器呈现保持同步。

<!DOCTYPE html>
<html>
<head>
<style>
canvas{border:#666 3px solid;}
</style>
</head>
<!-- dont need this <body onload="draw(530,15); draw1(1,15);">-->
<body>
<canvas id="canvas" width="600" height="400"></canvas>
<script>
var canvas,ctx,x,y,w,e;
var canvas,ctx,x,y,w,e;
function draw() {
    ctx.fillStyle = "rgba(0,200,0,1)";
    ctx.fillRect(x, y, 70, 50);
};
function draw1(w, e) {
    ctx.fillStyle = "rgba(0,200,0,1)";
    ctx.fillRect(w, e, 70, 50);
};
function update(time){  // high precision time passed by RAF when it calls this function
    ctx.clearRect(0,0,canvas.width,canvas.height); // clear all of the canvas
    if(w + 70 >= x){
        e += 2;        
    }else{
        x -= 0.75;
        w += 1;
    };
    draw(x,y);
    draw1(w,e);
    requestAnimationFrame(update)
    // at this point the function exits and the browser presents
    // the canvas bitmap for display
}
function start(){ // set up
    x = 530;
    y = 15;
    w = 1;
    e = 15;
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    requestAnimationFrame(update)
}
window.addEventListener("load",start);
</script>
</body>  
</html>

你的动画方法是非常过时的(即使用setTimeout)。相反,您应该使用requestAnimationFrame,如下所示。这将提供平滑,无闪烁的动画。

<!DOCTYPE html>
<html>
<head>
<style>
canvas{border:#666 3px solid;}
</style>
</head>
<body onload="requestAnimationFrame(animate);">
<canvas id="canvas" width="600" height="400"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
  
var x = 530, y = 15;  
function animate(){
  requestID = requestAnimationFrame(animate);
  ctx.clearRect(x, y, 600, 400);
  ctx.fillStyle = "rgba(0,200,0,1)";
  ctx.fillRect (x, y, 70, 50);
  x -= 0.5;
  if(x==300)
  {
    cancelAnimationFrame(requestID)
  };
}
</script>
</body>  
</html>

ctx的前两个参数。两个绘制函数中的cleareact都应该为0:

ctx。