我使用HTML画布绘制多个正方形。我有2个函数:1)绘制一个正方形,2)在循环内绘制多个正方形。
现在我想使用 requestAnimationFrame 为这些方块设置动画,一次绘制这些方块。我怎样才能做到这一点。这是jsFiddle
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
function rect(x, y, w, h) {
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.stroke();
}
function drawRect(number, size) {
for (var i = 0; i <= number; i++) {
rect(i * size, i * size, (i * size) * 2, (i * size) * 2);
}
}
drawRect(10, 5);
答案 0 :(得分:1)
我提供了一个帧限制器和补间,以显示不同的动画方式。帧限制器具有示例中的步骤,并且补间具有在给定时间内完成所需的步骤。
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
//requestAnim shim layer by Paul Irish
//http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( /* function */ callback, /* DOMElement */ element) {
window.setTimeout(callback, 1000 / 60);
};
})();
function rect(x, y, w, h, color) {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.rect(x, y, w, h);
ctx.stroke();
}
function drawRect(i, size, color) {
//for (var i = 0; i <= number; i++) {
rect(i * size, i * size, (i * size) * 2, (i * size) * 2, color);
//}
}
var i = 0;
var incr = 1;
var i_max = 10;
var size = 5;
var fps = 10;
var delay = 1000 / fps;
var lastFrame = 0;
var animationTime = 5000
var tweenStep = i_max / ((animationTime/1000) * 60);
var j = 0;
function animateRect() {
// draw at 60fps
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawRect(i, size, "#0000FF");
// This is a frame limiter.
var currentFrame = Date.now();
if ((currentFrame - lastFrame) >= delay) {
i += incr;
if (i >= i_max) i = i_max - 2, incr = -1;
if (i < 0) i = 1, incr = 1;
lastFrame = currentFrame;
}
// this is a tween. The step is calculated for the desired time.
drawRect(j, size, "#FF0000");
j += tweenStep;
if (j >= i_max) tweenStep *= -1,j=i_max-1;
if (j < 0) tweenStep *= -1, j=0;
requestAnimFrame(animateRect);
//draw rectangle one by one here...
}
animateRect();
//drawRect(10, 5);
<canvas id="canvas" width="600" height="600"></canvas>
答案 1 :(得分:0)
您可以执行类似
的操作var numRects = 10;
var size = 5;
var i = 1; // which rectangle we're drawing
var delay = 1000/60; // num miliseconds between frames
var before = new Date().getTime(), // last draw time in ms
now; // current time in ms
function animateRect() {
// get the current time to find if we should draw
now = new Date().getTime();
// if sufficient time passed since last draw, draw a rect
if ( now - before > delay && i <= numRects) {
rect(i * size, i * size, (i * size) * 2, (i * size) * 2);
i++;
before = now;
}
requestAnimFrame(animateRect);
}
修改强>
正如Blindman67在下面指出的那样,requestAnimFrame
将动画开始后的当前时间戳传递给回调。以下是如何利用它:
var numRects = 10;
var size = 5;
var i = 1; // which rectangle we're drawing
var delay = 1000/60; // num miliseconds between frames
var before; // last draw time in ms
function animateRect(now) {
if ( !before ) before = now;
// if sufficient time passed since last draw, draw a rect
if ( now - before > delay && i <= numRects) {
rect(i * size, i * size, (i * size) * 2, (i * size) * 2);
i++;
before = now;
}
requestAnimFrame(animateRect);
}
但是,这需要修改OP正在使用的垫片,以便将当前时间戳传递给setTimeout
中的回调:
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( /* function */ callback, /* DOMElement */ element) {
window.setTimeout(callback, 1000 / 60, new Date.now());
};
})();