Javascript 在requestAnimationFrame中使用clearRect不会显示动画
我试图在HTML5画布上制作一个简单的javascript动画。现在,我的画布是分层的,这样当我收到鼠标事件时,背景层不会改变,但带有化身的顶层会移动。如果我使用requestAnimationFrame而不清除屏幕,我会看到我的可爱的小玩家在屏幕上以多个帧的形式移动,并带有角色的长尾。但是,如果我尝试在每个动画帧后执行clearRect,那么我的角色将永远不会出现,我不确定是什么原因导致了这种情况 我使用这些链接作为代码的基础:Javascript 在requestAnimationFrame中使用clearRect不会显示动画,javascript,image,html,animation,Javascript,Image,Html,Animation,我试图在HTML5画布上制作一个简单的javascript动画。现在,我的画布是分层的,这样当我收到鼠标事件时,背景层不会改变,但带有化身的顶层会移动。如果我使用requestAnimationFrame而不清除屏幕,我会看到我的可爱的小玩家在屏幕上以多个帧的形式移动,并带有角色的长尾。但是,如果我尝试在每个动画帧后执行clearRect,那么我的角色将永远不会出现,我不确定是什么原因导致了这种情况 我使用这些链接作为代码的基础: http://www.html5canvastutorials.
http://www.html5canvastutorials.com/advanced/html5-canvas-start-and-stop-an-animation/ 很多例子都是为绘制的形状设置动画,而我使用的是图像,不确定这是否重要,也不确定我是否应该使用画布变换函数而不是clearRect,但我认为这不应该有什么不同。另外,为了可读性,我删除了一堆代码,所以括号可能是关闭的,但代码是正常工作的,我只是为了可读性而做的,所以你可以从一个方向看到动画。我的代码看起来像:
// what is this function for? See here - http://stackoverflow.com/questions/10237471/please-explain-this-requestanimationframe-idiom
window.requestAnimFrame = function(callback){
// add in this parentheses - http://stackoverflow.com/questions/5605588/how-to-use- requestanimationframe
return ( window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
}
);
}();
function stopAnimatingPlayer(currentAvatarAnimating, destinationCellX, destinationCellY) {
gIsAnimating = false;
//Did this final draw because I wasn't sure if the avatar would end on the exact pixel position, so this should snap him back into place
drawAvatar(currentAvatarAnimating, destinationCellX, destinationCellY, false,0,0);
}
function movePlayer(lastTime, playerPixelX, playerPixelY, destinationCellX, destinationCellY) {
if (gIsAnimating) {
// the canvas is already globally held as gAvatarCanvasElement & gAvatarDrawingContext;
// update
var date = new Date();
var time = date.getTime();
var timeDiff = time - lastTime;
var linearSpeed = 100;
// pixels / second
var linearDistEachFrame = linearSpeed * timeDiff / 1000;
var horizontal = false;
var newX, newY;
// gets the new coordinate of the player
if (gTowerCurrentPlayer == 1) {
//fill in later - just trying to get one horizontal animation working
} else if (destinationCellY == gPlayer1Cell.y) { // we're moving horizontally
var currentX = playerPixelX;
var diffX = destinationCellX - gPlayer1Cell.x;
horizontal = true;
if (diffX > 0) { // player is moving right - just get one direction going for now
if (currentX < getPixelFromRow(destinationCellX)) {
newX = currentX + linearDistEachFrame;
} else {
stopAnimatingPlayer(gTowerCurrentPlayer, destinationCellX, destinationCellY);
}
} //fill in rest later - get one direction working
lastTime = time;
// clear - this is where the problem is
gAvatarDrawingContext.clearRect(playerPixelX, playerPixelY, kPieceWidth, kPieceHeight);
//gAvatarDrawingContext.clearRect(0,0, gAvatarCanvasElement.width, gAvatarCanvasElement.height);
if (horizontal) {
drawAvatar(gTowerCurrentPlayer, 0, 0, true, newX, playerPixelY);
// request new frame
requestAnimFrame(function(){
movePlayer(lastTime, newX, playerPixelY, destinationCellX, destinationCellY);
});
}
}
}
function animatePlayer(playerPixelX, playerPixelY, destinationCellX, destinationCellY) {
gIsAnimating = true; // global var here
var date = new Date();
var time = date.getTime();
movePlayer(time, playerPixelX, playerPixelY, destinationCellX, destinationCellY);
}
//此函数的作用是什么?看这里-http://stackoverflow.com/questions/10237471/please-explain-this-requestanimationframe-idiom
window.requestAnimFrame=函数(回调){
//在括号内加上-http://stackoverflow.com/questions/5605588/how-to-use- 请求动画帧
返回(window.requestAnimationFrame)||
window.webkitRequestAnimationFrame||
window.mozRequestAnimationFrame||
window.oRequestAnimationFrame||
window.msRequestAnimationFrame||
函数(回调){
设置超时(回调,1000/60);
}
);
}();
函数stopAnimatingPlayer(当前虚拟角色、目标cellx、目标celly){
设置动画=假;
//这是最后一次抽签,因为我不确定头像是否会在精确的像素位置结束,所以这应该会让他回到正确的位置
drawAvatar(CurrentAvatar,destinationCellX,destinationCellY,false,0,0);
}
函数movePlayer(lastTime、playerPixelX、playerPixelY、destinationCellX、destinationCellY){
如果(设置动画){
//画布已作为gAvatarCanvasElement&gAvatarDrawingContext全球持有;
//更新
变量日期=新日期();
var time=date.getTime();
var timeDiff=时间-上次时间;
变量线性速度=100;
//像素/秒
var LINEARDISEACHFRAME=线性速度*时间差/1000;
var水平=假;
var newX,newY;
//获取播放器的新坐标
如果(gTowerCurrentPlayer==1){
//稍后填写-只是尝试让一个水平动画工作
}否则如果(destinationCellY==gPlayer1Cell.y){//我们是水平移动的
var currentX=playerPixelX;
var diffX=destinationCellX-gPlayer1Cell.x;
水平=真;
如果(diffX>0){//player正在向右移动-现在只需向一个方向移动即可
if(currentX
如果有人能提供任何帮助,我会非常感激,我只是不明白为什么这不起作用。我不需要超级华而不实的动画,这就是为什么我没有使用kineticjs或其他任何库的原因
谢谢。当你清除画布时,它会擦除画布上的所有内容,因此如果你在绘制后调用它,你会得到一个空白画布,这就是你所描述的。相反,你应该等到下一帧,然后在绘制之前而不是之后清除画布,以便绘制的图像显示一段时间。要解决你的问题,只需将清除命令向上移动,以便在每个帧的绘图命令之前立即执行该命令。我不确定可以向上移动清除命令的位置。我基本上将其移动到递归函数的顶部,它仍然会清除。如果删除
if(水平)命令,它是否正常工作{
清除旧位置后的条件?不幸的是,它仍然以相同的方式工作。我在drawAvatar函数之前放置了一个console.log调用,因此我知道它每帧都被调用。