Javascript Canvas一项闪烁

时间:2016-09-07 11:10:19

标签: javascript canvas flicker

我试图让对象在Canvas中相互移动,当它们相遇并重叠时,一个应该消失而另一个应该掉下来。现在我得到了动画,但其中一个项目是闪烁的。

<!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>

已经尝试了两天,但似乎无法正确修复它。提前谢谢。

3 个答案:

答案 0 :(得分:1)

你的动画方法已经过时(即使用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>

答案 1 :(得分:1)

每秒渲染太多帧会强制浏览器显示帧。每次绘图功能返回浏览器时,您都希望将框架呈现给页面。

需要将动画同步到显示器刷新率,对于大多数设备,该刷新率为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>

答案 2 :(得分:-1)

两个绘制函数中ctx.clearReact的前2个参数应为0:

ctx.clearRect(0,0,600,400);

这意味着你清除所有画布。