从 setInterval 方法移动到带有 sprite 的 requestAnimationFrame
Moving from setInterval method to requestAnimationFrame with sprite
我正在尝试使用方法 'requestAnimationFrame' 并借助我在 Internet 上可以找到的帮助。我可以移动一个元素,但是当我想用精灵来做的时候,我迷路了。
例如,下面的代码在 'setInterval' 下可以正常工作,但我无法让它在 'requestAnimationFrame' 下正常工作。
<!DOCTYPE html>
<html>
<head>
<title>Animating Sprites in HTML5 Canvas</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no">
<style>
.demo {background: #aaaaaa;}
#myCanvas{background: #cccccc}
</style>
</head>
<body class="demo">
<canvas id="myCanvas" width="800" height="100"></canvas>
<script>
(function() {
// Canvas
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
// Set the fill style for the drawing context.
ctx.fillStyle = '#3399ff';
// VARIABLES
var width = 48; // Width CANVAS
var height = 60; // Height CANVAS
var xFrame = 0; // Frame x coordinate
var yFrame = 0; // Frame y coordinate
var dxFrame = 0; // Frame dx position in canvas
var dyFrame = 0; // Frame dy position in canvas
// SPRITE used
image = new Image()
image.src = 'myRunner2.png';
//
var requestID;
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
// FUNCTION DRAWING MOVE (xFrame = 0 & yFrame = 1)
var drawMove = function(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(image, width * xFrame, height * yFrame, width, height, dxFrame, dyFrame, width, height);
if (xFrame == 7) {
xFrame = 0;
} else {
xFrame++
dxFrame+=2;
}
//window.requestAnimFrame(eMove);
}
// ANIMATION in 3 moves: Idle + Move + Tired
var intA;
function eMove() {
// Runner in motion (8 frames)
yFrame = 1;
xFrame = 0;
clearInterval(intA);
intA = setInterval(drawMove, 100);
}
eMove();
}());
</script>
</body>
</html>
我正在寻求有关此问题的帮助,部分代码会很好,但工作方式或寻找方向也会很好。如何使用'requestAnimationFrame'?
方法操作精灵
最终,我的目标是在一个方向上移动精灵,在另一个方向上移动背景。我可以单独使用 setTimeout/setInterval 方法沿一个方向移动精灵,也可以使用 'requestAnimationFrame' 沿另一个方向移动背景,但也可以单独移动。
希望您能理解我的问题。
谢谢,
JLuc01
为了使 requestAnimationFrame 正常工作,它需要一个准确的计时器来更新进度。然后动画也将取决于这个变量。当然,还必须设置总持续时间(以衡量进度)。这是一段通用代码:
var initial = update = new Date().getTime(), progress = 0, duration = 2000;
requestAnimationFrame(frameSequence);
function frameSequence() {
update = new Date().getTime();
var elapsed = update-initial;
progress = Math.max(elapsed/duration, 1);
someFunction(); // do calculations and implement them based on progress
if (progress < 1) requestAnimationFrame(frameSequence);
}
还有一个实例(相关代码在底部)
http://codepen.io/Shikkediel/pen/vEzqoX?editors=001
编辑 - 一些评论升级为更新:
requestAnimationFrame 调用只是一个真正用于替换超时的基本循环。它可以像使用 requestAnimationFrame(drawMove)
而不是 clearInterval(intA); intA = setInterval(drawMove, 100)
一样简单。尽管如此,它可能会在 8/60 秒内完成整个过程(我看到有 8 帧,60 是常见的显示刷新率)——因此需要一个计时器。
这将优化并确保工作:setInterval(requestAnimationFrame(drawMove), 100)
。它不会像超时那样在显示器上强制显示一个帧(产生性能问题和闪烁),而是让它等待第一个合适的实例,当有一个新的屏幕绘制时。但根本不使用超时是一个更好的方法。
我正在尝试使用方法 'requestAnimationFrame' 并借助我在 Internet 上可以找到的帮助。我可以移动一个元素,但是当我想用精灵来做的时候,我迷路了。
例如,下面的代码在 'setInterval' 下可以正常工作,但我无法让它在 'requestAnimationFrame' 下正常工作。
<!DOCTYPE html>
<html>
<head>
<title>Animating Sprites in HTML5 Canvas</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no">
<style>
.demo {background: #aaaaaa;}
#myCanvas{background: #cccccc}
</style>
</head>
<body class="demo">
<canvas id="myCanvas" width="800" height="100"></canvas>
<script>
(function() {
// Canvas
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
// Set the fill style for the drawing context.
ctx.fillStyle = '#3399ff';
// VARIABLES
var width = 48; // Width CANVAS
var height = 60; // Height CANVAS
var xFrame = 0; // Frame x coordinate
var yFrame = 0; // Frame y coordinate
var dxFrame = 0; // Frame dx position in canvas
var dyFrame = 0; // Frame dy position in canvas
// SPRITE used
image = new Image()
image.src = 'myRunner2.png';
//
var requestID;
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
// FUNCTION DRAWING MOVE (xFrame = 0 & yFrame = 1)
var drawMove = function(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(image, width * xFrame, height * yFrame, width, height, dxFrame, dyFrame, width, height);
if (xFrame == 7) {
xFrame = 0;
} else {
xFrame++
dxFrame+=2;
}
//window.requestAnimFrame(eMove);
}
// ANIMATION in 3 moves: Idle + Move + Tired
var intA;
function eMove() {
// Runner in motion (8 frames)
yFrame = 1;
xFrame = 0;
clearInterval(intA);
intA = setInterval(drawMove, 100);
}
eMove();
}());
</script>
</body>
</html>
我正在寻求有关此问题的帮助,部分代码会很好,但工作方式或寻找方向也会很好。如何使用'requestAnimationFrame'?
方法操作精灵最终,我的目标是在一个方向上移动精灵,在另一个方向上移动背景。我可以单独使用 setTimeout/setInterval 方法沿一个方向移动精灵,也可以使用 'requestAnimationFrame' 沿另一个方向移动背景,但也可以单独移动。
希望您能理解我的问题。 谢谢,
JLuc01
为了使 requestAnimationFrame 正常工作,它需要一个准确的计时器来更新进度。然后动画也将取决于这个变量。当然,还必须设置总持续时间(以衡量进度)。这是一段通用代码:
var initial = update = new Date().getTime(), progress = 0, duration = 2000;
requestAnimationFrame(frameSequence);
function frameSequence() {
update = new Date().getTime();
var elapsed = update-initial;
progress = Math.max(elapsed/duration, 1);
someFunction(); // do calculations and implement them based on progress
if (progress < 1) requestAnimationFrame(frameSequence);
}
还有一个实例(相关代码在底部)
http://codepen.io/Shikkediel/pen/vEzqoX?editors=001
编辑 - 一些评论升级为更新:
requestAnimationFrame 调用只是一个真正用于替换超时的基本循环。它可以像使用 requestAnimationFrame(drawMove)
而不是 clearInterval(intA); intA = setInterval(drawMove, 100)
一样简单。尽管如此,它可能会在 8/60 秒内完成整个过程(我看到有 8 帧,60 是常见的显示刷新率)——因此需要一个计时器。
这将优化并确保工作:setInterval(requestAnimationFrame(drawMove), 100)
。它不会像超时那样在显示器上强制显示一个帧(产生性能问题和闪烁),而是让它等待第一个合适的实例,当有一个新的屏幕绘制时。但根本不使用超时是一个更好的方法。