使用requestAnimationFrame实现div动画

3
我想先水平地给一个
添加动画,然后再垂直地给它添加动画。但使用requestAnimationFrame的问题是它会同时执行这两个动画,使得
以对角线方向移动。
以下是fiddle链接:https://jsfiddle.net/akonchady/z4qmkuyc/22/ 我做错了什么?
另外注意:如果我在第二次调用中加入超时(timeout),则可以按预期工作。

animate('abc', 'marginLeft', 250, 1000);
setTimeout(function() {
  animate('abc', 'marginTop', 250, 1000);
}, 3000);

然而,我希望避免超时。我如何只使用 requestAnimationFrame 来实现这一点?


调用 animate 函数两次是没有帮助的。只需调用一次,并且必须有一个条件来测试 element 的位置。而且坦率地说,+new Date 对于可读性来说并没有帮助... - Rayon
@Rayon 如果我为第二次调用animate设置超时时间,它会按预期工作。 - Adarsh Konchady
我不确定你如何维护时间和距离之间的关系... - Rayon
我需要第二个函数在第一个函数执行后按照相同的顺序执行。我不明白为什么需要使用setTimeout来实现函数正常流程。难道没有更好的方法吗! - Adarsh Konchady
1
是的,第二个函数在第一个函数执行完后立即执行。为什么第二个函数要等待第一个函数呢?语句是按顺序执行的。 - Rayon
显示剩余2条评论
1个回答

3

JavaScript中的大多数函数都是同步的(按顺序执行)。但对于异步函数(不会等待早期的函数完成),使用回调函数来控制执行流程。

要在第一个动画完成后调用send 函数,请使用callback

function animate(id, styleAttr, finalValue, duration, callback) {
  var ele = document.getElementById('abc'),
    startTime = +new Date, //Not sure how readable this is ?
    delta = null,
    req = null;

  (function timeout() {
    elapsedTime = +new Date - startTime;
    if (elapsedTime >= duration) {
      cancelAnimationFrame(req);
      ele.style[styleAttr] = finalValue + 'px';
      if (typeof callback !== 'undefined') {
        callback();
      }
      return;
    } else {
      delta = finalValue / duration;
      ele.style[styleAttr] = delta * elapsedTime + 'px';
    }
    req = requestAnimationFrame(timeout);
  })();
}
animate('abc', 'marginLeft', 250, 1000, function() {
  animate('abc', 'marginTop', 250, 1000);
});
#abc {
  width: 100px;
  height: 100px;
  background-color: red;
}
<div id='abc'>
</div>

演示代码


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