向通过requestAnimationFrame调用的函数添加额外的参数

11

我希望创建一个函数,在HTML5画布上使用requestAnimationFrame和delta time,将图像元素在y时间内滚动x像素。问题是当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将时间戳放入我的“时间戳”参数中)?


从我的有限知识中所能理解的来看,我认为解决方案要么在于使用 .call()/.apply(),要么是通过传递一个包含滚动内容的匿名函数给 rAF。但是,如果我采用其中任何一种方法,我都无法理解如何访问 rAF 的时间戳。 - Danneh
可能是如何在requestAnimationFrame中传递参数?的重复问题。 - Magnus Lind Oxlund
2个回答

12

您的requestAnimationFrame语句的评估结果:

  • scroll(timestamp, distanceToScroll, secondsToScroll),其中timestamp未定义。它会抛出错误或返回undefined。
  • window.requestAnimationFrame在没有参数的情况下执行,因此没有回调函数。

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

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

这个表达式的值是:

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

1
这是一个非常明显的解决方案,但我却没有看到它。谢谢。 - Danneh
requestAnimationFrame(timestamp=>scroll(timestamp, distanceToScroll, secondsToScroll)); 请求动画帧(时间戳=>滚动(时间戳,滚动距离,滚动秒数)); - Garrett
1
但是如果没有匿名函数的引用,你该如何移除requestAnimationFrame呢? - Raba

0

纯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 中处理动画的更好、更推荐的方法,使用它可以让动画更加流畅。 - Muhammad Omer Aslam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接