向requestAnimationFrame返回的函数添加其他参数

时间:2014-02-27 06:47:00

标签: javascript html5-canvas requestanimationframe

我希望使用requestAnimationFrame和delta time创建一个在HTML5画布上滚动图像元素x像素的函数。我无法弄清楚的是当requestAnimationFrame allready用一个参数(一个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'参数中)?

2 个答案:

答案 0 :(得分:7)

您的requestAnimationFrame语句评估为

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

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

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

评估的内容为:

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

答案 1 :(得分: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'));