【问题标题】:Adding additional arguments to a function called back by requestAnimationFrame向 requestAnimationFrame 回调的函数添加附加参数
【发布时间】:2014-02-27 06:46:59
【问题描述】:

我希望创建一个函数,使用 requestAnimationFrame 和增量时间在 HTML5 画布上滚动图像元素 x 像素超过 y 时间。当 requestAnimationFrame 已经用一个参数(DOMHighResTimeStamp)回调我的函数时,我无法弄清楚如何向我的函数添加更多参数。我很确定以下代码不起作用:

function scroll(timestamp, distanceToScroll, secondsToScroll) {
  //delta = how many milliseconds have passed between this and last draw
  if (!lastDraw) {var lastDraw = timestamp;};
  delta = (0.5 + (timestamp - lastDraw)) << 0; //bitwise hack for rounding integers
  lastDraw = timestamp;

  //speed (pixels per millisecond) = amount of pixels to move / length of animation (in milliseconds)
  speed = distanceToScroll / secondsToScroll;

  //new position = current position + (speed * delta)
  position += (speed * delta);

  context.drawImage(myImage,0,position,50,50/*of 200*/,0,0,100,100);
  requestAnimationFrame(scroll(timestamp, distanceToScroll, secondsToScroll));
};

//later...
scroll(timestamp, 100, 5)
scroll(timestamp, 10, 20)

我的问题是我不知道如何强制 requestAnimationFrame 继续使用我的附加参数调用我的滚动函数,而默认情况下它所做的只是在回调中传递一个参数(时间戳)。那么我该如何添加更多参数(或强制 rAF 将时间戳放入我的 'timestamp' 参数中)?

【问题讨论】:

  • 根据我有限的知识,我认为解决方案在于 .call()/.apply() 或将包含滚动的匿名函数传递给 rAF,但我如果我这样做,我也无法访问 rAF 的时间戳。

标签: javascript html5-canvas requestanimationframe


【解决方案1】:

您的 requestAnimationFrame 语句评估结果

  • scroll(timestamp, distanceToScroll, secondsToScroll),其中时间戳未定义。它会抛出错误或返回 undefined
  • window.requestAnimationFrame 不带参数执行,因此没有回调

传递一个匿名函数调用 scroll 并使用所需的参数应该可以解决问题:

requestAnimationFrame(function(timestamp) {
    scroll(timestamp, distanceToScroll, secondsToScroll));
});

计算结果:

  • window.requestAnimationFrame 使用匿名函数作为回调调用
  • 匿名函数以timestamp作为第一个参数调用
  • scroll 以当前的timestampdistanceToScrollsecondsToScroll 作为参数调用

【讨论】:

  • 如此明显的解决方案,但我看不到。谢谢。
  • requestAnimationFrame(timestamp=>scroll(timestamp, distanceToScroll, secondsToScroll));
  • 但是如果没有对匿名函数的引用,你将如何删除 requestAnimationFrame?
【解决方案2】:

纯 JavaScript

function scrollIntoViewSmooth(elem) {
    var move = elem.offsetTop - (elem.offsetTop - elem.parentElement.scrollTop) * 0.25;

    if (Math.abs(elem.offsetTop - move) <= 2) {
        elem.parentElement.scrollTop = elem.offsetTop;
    } else {
        elem.parentElement.scrollTop = move;
        setTimeout(scrollIntoViewSmooth, 33, elem);
    }
}

示例

scrollIntoViewSmooth(document.getElementById('stuff'));

【讨论】:

  • requestAnimationFrame 是 javascript 并且在处理动画时是更好和推荐的方法,没有什么比这更流畅了
猜你喜欢
  • 2013-12-18
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 2011-09-15
  • 2015-08-27
相关资源
最近更新 更多