我总是在动画和间隔/ fps的想法上挣扎。我理解代码在这个片段中是如何工作的,但我只是不明白我如何减慢动画速度,同时仍然保持画布刷新率为60 fps。
$(document).ready(function(){
startAnimating(60);
});
//Global Variables
var fpsInterval;
var then;
var shift = 0;
var frameWidth = 107;
var frameHeight = 140;
var canvasX = 0;
var canvasY = 0;
var myImage = new Image();
var totalFrames = 8;
var currentFrame = 0;
//Loading image
myImage.src = "https://i.imgur.com/N3shTgD.png";
myImage.addEventListener("load", loadImage, false);
//Function to begin animation with set fps
function startAnimating(fps)
{
fpsInterval = 1000/fps;
then = Date.now();
animate();
}
function animate() {
var now = Date.now();
var elapsed = now - then;
if (elapsed > fpsInterval)
{
then = now - (elapsed % fpsInterval);
var cvs = $("canvas").get(0);
var ctx = cvs.getContext("2d");
//clear background
ctx.clearRect(0, 0, cvs.width, cvs.height);
//draw each frame and place in middle of canvas
/*
drawImage(
"Image object",
"X coordinate next sprite in png (Location of sprite?)",
"Y coorinate next sprite in png",
"Width of sprite in png (How big is sprite?)",
"Height of sprite in png"
"X coordinate on canvas (Where to draw it?)"
"Y coordinate on canvas"
"Sprite width to use (How you want it to look?)"
"Sprite height to use"
)
*/
//(sprite.png,0,0,300,300,0,0,300,300)
ctx.drawImage(myImage, shift, 0, frameWidth, frameHeight, canvasX, canvasY, frameWidth, frameHeight);
shift += frameWidth + 1;
}
if (currentFrame == totalFrames) {
shift = 0;
currentFrame = 0;
}
currentFrame++;
requestAnimationFrame(animate);
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- What code do we need? -->
<script src ="exercise_three.js"></script>
</head>
<body>
<canvas width="300" height="300" style="border: solid black 1px">
Sorry, no canvas support!
</canvas>
</body>
</html>
https://jsfiddle.net/r7dd2mt7/2/ RequestAnimationFrame()
我非常感谢帮助理解它是如何运作的。
答案 0 :(得分:1)
60 FPS表示帧每1000/60毫秒更改一次(约为16.7毫秒)。因此,如果您只有8个帧(如您的示例中所示),则整个循环将花费133.3 ms。当然太快了。您可以通过两种方式减慢速度:
//Global Variables
var fpsInterval;
var then;
var shift = 0;
var frameWidth = 397;
var frameHeight = 300;
var canvasX = 0;
var canvasY = 0;
var myImage = new Image();
var totalFrames = 45;
var currentFrame = 0;
//Loading image
myImage.onload = function() {
startAnimating(60);
};
myImage.src = "https://i.imgur.com/u6uPigf.png";
//Function to begin animation with set fps
function startAnimating(fps) {
fpsInterval = 1000/fps;
then = Date.now();
animate();
}
function animate() {
var now = Date.now();
var elapsed = now - then;
if (elapsed > fpsInterval) {
then = now - (elapsed % fpsInterval);
var cvs = $("canvas").get(0);
var ctx = cvs.getContext("2d");
//clear background
ctx.clearRect(0, 0, cvs.width, cvs.height);
//draw each frame and place in middle of canvas
/*
drawImage(
"Image object",
"X coordinate next sprite in png (Location of sprite?)",
"Y coorinate next sprite in png",
"Width of sprite in png (How big is sprite?)",
"Height of sprite in png"
"X coordinate on canvas (Where to draw it?)"
"Y coordinate on canvas"
"Sprite width to use (How you want it to look?)"
"Sprite height to use"
)
*/
ctx.drawImage(myImage, shift, 0, frameWidth, frameHeight, canvasX, canvasY, frameWidth, frameHeight);
shift += frameWidth + 1;
currentFrame++;
if (currentFrame == totalFrames) {
shift = 0;
currentFrame = 0;
}
}
requestAnimationFrame(animate);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas width="300" height="300" style="border: solid black 1px">
Sorry, no canvas support!
</canvas>
//Global Variables
var fpsInterval;
var then;
var shift = 0;
var frameWidth = 107;
var frameHeight = 140;
var canvasX = 0;
var canvasY = 0;
var myImage = new Image();
var totalFrames = 8;
var currentFrame = 0;
//Loading image
myImage.onload = function() {
startAnimating(10);
}
myImage.src = "https://i.imgur.com/N3shTgD.png";
//Function to begin animation with set fps
function startAnimating(fps) {
fpsInterval = 1000/fps;
then = Date.now();
animate();
}
function animate() {
var now = Date.now();
var elapsed = now - then;
if (elapsed > fpsInterval) {
then = now - (elapsed % fpsInterval);
var cvs = $("canvas").get(0);
var ctx = cvs.getContext("2d");
//clear background
ctx.clearRect(0, 0, cvs.width, cvs.height);
//draw each frame and place in middle of canvas
/*
drawImage(
"Image object",
"X coordinate next sprite in png (Location of sprite?)",
"Y coorinate next sprite in png",
"Width of sprite in png (How big is sprite?)",
"Height of sprite in png"
"X coordinate on canvas (Where to draw it?)"
"Y coordinate on canvas"
"Sprite width to use (How you want it to look?)"
"Sprite height to use"
)
*/
ctx.drawImage(myImage, shift, 0, frameWidth, frameHeight, canvasX, canvasY, frameWidth, frameHeight);
shift += frameWidth + 1;
currentFrame++;
if (currentFrame == totalFrames) {
shift = 0;
currentFrame = 0;
}
}
requestAnimationFrame(animate);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas width="300" height="300" style="border: solid black 1px">
Sorry, no canvas support!
</canvas>
答案 1 :(得分:0)
有一种选择很简单。您可以通过添加超时来简化动画,而不是更改所有精灵。有效地跳过油漆框架,以便按照您的步调进行绘制,而不是浏览器的框架绘画速度。
在样本中,我删除了所有残骸并添加了一个步速变量。将其设置为您希望每个步骤采用的ms(每1/2秒500步)。注意setTimeout()调用。
为了好玩,我还用setInterval运行你的动画,因为我很好奇。
检查一下:
//Global Variables
var shift = 0;
var frameWidth = 107;
var frameHeight = 140;
var myImage = new Image();
var totalFrames = 8;
var currentFrame = 0;
var left = document.getElementById('left');
var leftCtx = left.getContext("2d");
var right = document.getElementById('right');
var rightCtx = right.getContext("2d");
// in ms, so 500 == 1 step every 1/2 second
var pace = 250;
myImage.src = "https://i.imgur.com/N3shTgD.png";
setInterval(rightStep, pace);
requestAnimationFrame(leftStep);
function leftStep() {
leftCtx.clearRect(0, 0, left.width, left.height);
leftCtx.drawImage(myImage, shift, 0, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);
shift += frameWidth + 1;
if(shift === (frameWidth * 8) + 8) {
shift = 0;
}
setTimeout(stepLeftAgain, pace);
}
function stepLeftAgain(){
requestAnimationFrame(leftStep);
}
function rightStep() {
rightCtx.clearRect(0, 0, right.width, right.height);
rightCtx.drawImage(myImage, shift, 0, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);
shift += frameWidth + 1;
if(shift === (frameWidth * 8) + 8) {
shift = 0;
}
}
&#13;
<html>
<head>
</head>
<body>
<canvas id="left" width="300" height="300" style="border: solid black 1px"></canvas>
<canvas id="right" width="300" height="300" style="border: solid black 1px"></canvas>
</body>
</html>
&#13;