【问题标题】:How to switch from 'SetInterval' to 'request animation frame' [closed]如何从“SetInterval”切换到“请求动画帧”[关闭]
【发布时间】:2013-03-25 14:24:28
【问题描述】:

我创建了一个简单的画布动画,听说使用“请求动画帧”比使用“设置间隔”更好,但不知道该怎么做?

现在是这样的:

http://jsfiddle.net/rC7zJ/
var width = 48;
var height = 87;
var speed = 100; //ms
var frames = 1; // Total frames - 1, as frame start from 0 not 
var currentFrame = 0;

canvas = document.getElementById("CanvasAnimate");
ctx = canvas.getContext("2d");
imageTadPole = new Image()
imageTadPole.src = 'https://dl.dropbox.com/u/19418366/tadpole.png';

function draw(){
    ctx.clearRect(0, 0, width, height);
    ctx.drawImage(imageTadPole, width * currentFrame, 0, width, height, 0, 0, width, height);

    if (currentFrame == frames) {
        currentFrame = 0;
    } else {
        currentFrame++;
    }
}

setInterval(draw, speed); 

任何帮助将不胜感激!

【问题讨论】:

标签: javascript html animation canvas


【解决方案1】:

总是从 Paul Irish 的 requestAnimationFrame 跨浏览器 shim 开始

    window.requestAnimFrame = (function(callback) {
      return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
      function(callback) {
        window.setTimeout(callback, 1000 / 60);
      };
    })();

然后只需编写一个动画函数:

  1. 更新驱动动画的变量(位置、速度、颜色变化等)
  2. 使用画布上下文绘制当前帧
  3. 通过重新调用 requestAnimFrame 使动画在下一帧保持活跃

这是示例骨架代码:

    function animate() {

      // update animation variables
      X+=20;
      Velocity +=10;

      // clear the canvas and draw the current frame
      // based on the variables you just updated
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.rect(x,y,75,50);

      // request new frame to keep the animation going
      requestAnimFrame( animate );
    }

以下是如何降低动画的速度(如 FPS——但不是):

// set a countdown "throttle" that will slow animate() down by 4X
var notEveryTime=3;

function animate() {

  // if notEveryTime hasn't counted down to 0
  // then just don't animate yet
  if(--notEveryTime>0){ return; };

  // update animation variables
  X+=20;
  Velocity +=10;

  // clear the canvas and draw the current frame
  // based on the variables you just updated
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.rect(x,y,75,50);

  // request new frame to keep the animation going
  requestAnimFrame( animate );

  // reset notEveryTime
  notEveryTime=3;

}

并且阅读 Anreas 的好建议:http://paulirish.com/2011/requestanimationframe-for-smart-animating/

【讨论】:

  • 谢谢!但我想如何控制 fps :/? jsfiddle.net/rC7zJ,现在就像闪电一样:/
  • 我在答案中添加了一个标准的“节流阀”,您可以设置它来管理动画速度。请注意,requestAnimation 帧不使用特定的 FPS——它只会尽可能快/高效地进行动画处理。如果您需要更具体的时间安排,请务必阅读这篇关于结合 requestAnimationFrame 和 setTimeout 的精彩文章:creativejs.com/resources/requestanimationframe
  • 谢谢!不胜感激! :) 现在可以了!
【解决方案2】:

如 Marke 所说,但如果您想控制 FPS,请将您的 requestAnimationFrame 调用包装在 setTimeOur 函数中,如下所示:

var fps = 15;
function draw() {
    setTimeout(function() {
        requestAnimationFrame(draw);
        // Drawing code goes here
    }, 1000 / fps);
}

使用 requestAnimationFrame 是个好主意,即使您正在修复帧速率,因为它

  1. 将在页面处于非活动状态时提供 CPU 节流 a
  2. 为您提供 requestAnimationFrame 提供的幕后优化。

Request Animation Frame 的一个不错的页面可以找到here

【讨论】:

  • 感谢该页面!它真的帮助了我! :)
  • 轻笑...伟大的思想都一样。 :)
猜你喜欢
  • 2012-12-27
  • 2012-05-23
  • 2015-08-28
  • 2013-05-09
  • 1970-01-01
  • 2010-10-26
  • 2021-10-10
  • 2015-06-17
  • 2015-04-23
相关资源
最近更新 更多