【问题标题】:code trying to make object jump using requestanimationframe not working尝试使用 requestanimationframe 进行对象跳转的代码不起作用
【发布时间】:2019-01-19 05:36:43
【问题描述】:

我正在尝试使用 requestanimationframe 使对象跳转。 finalposition 变量保存对象应出现在页面底部上方的像素数。

根据我的代码,对象应该平滑地移动到最大高度,然后平滑地向下移动两个事件,耗时=500ms ..但是当我运行代码时,对象立即出现在最大高度,然后在 500ms 内平滑地向下移动...我如何让这两个事件在 500 毫秒内顺利进行?

let time = {
  start: null,
  total: 500
};
const moveup = now => {
  if (!time.start) time.start = now;
  time.elapsed = now - time.start;
  let progress = time.elapsed / time.total;
  let position = progress * finalPosition;
  obj.style.bottom = position + 'px';
  if (progress < 1) requestAnimationFrame(moveup);

};           

const movedown = now => {
  if (!time.start) time.start = now;
  time.elapsed = now - time.start;
  let progress = time.elapsed / time.total;
  let position = finalPosition*(1-progress);
  obj.style.bottom = position + 'px';
  if (progress < 1) requestAnimationFrame(movedown);

};       
function jump(){
    requestAnimationFrame(moveup);
    time.start=0;
    requestAnimationFrame(movedown);
} 
document.addEventListener('keydown',jump,false)

【问题讨论】:

    标签: javascript addeventlistener requestanimationframe


    【解决方案1】:

    这里有几个问题。

    除非您的代码不完整,否则您的代码中的任何地方都没有 finalPosition。

    更重要的是跳转函数没有正确等待事件,整个函数一次运行,也就是说它在运行movedown之前没有等待moveup,而是它们同时运行。

    大概您只观察到movedown 的原因是这两种情况都发生在每一帧上,但movedown 是在向上移动之后发生的。

    看看下面的sn-p你就知道了,我在这里所做的是重新排列你现有的一些代码。我已将第一个 movedown 调用移至 moveup 循环的末尾,并在 movedown 的末尾重置时间。

    let finalPosition = 100;
    let time = {
      start: null,
      total: 500,
    };
    
    let obj = document.querySelector('.foo');
    const moveup = (now) => {
      if (!time.start) time.start = now;
      time.elapsed = now - time.start;
      let progress = time.elapsed / time.total;
      let position = progress * finalPosition;
      obj.style.bottom = position + 'px';
      if (progress < 1) {
        requestAnimationFrame(moveup);
      } else {
        time.start = 0;
        requestAnimationFrame(movedown);
      }
    };
    
    const movedown = (now) => {
      if (!time.start) time.start = now;
      time.elapsed = now - time.start;
      let progress = time.elapsed / time.total;
      let position = finalPosition*(1-progress);
      obj.style.bottom = position + 'px';
      if (progress < 1) {
        requestAnimationFrame(movedown);
      } else {
        time.start = 0;
      }
    };       
    
    function jump() {
      requestAnimationFrame(moveup);
    }
    
    document.addEventListener('keydown', jump, false);
    .foo {
      position: absolute;
      left: 50%;
      bottom: 0;
      transform: translateX(-50%) translateY(-50%);
    }
    
    .frame {
      height: 150px;
      width: 150px;
      position: absolute;
      top: 50%;
      right: 50%;
      transform: translateX(50%) translateY(-50%);
      background-color: #cdb;
    }
    <div class="frame">
      <div class="foo">?</div>  
    </div>
    <button onclick="jump()">jump</button>

    【讨论】:

    • 我确实有一个finalPosition..我没有将它包含在代码sn-p中...但是为什么javascript会立即执行整个函数..它应该先完成执行moveup然后movedown。 .for example in this link stackoverflow.com/questions/25028853/…这两个语句都将被记录到控制台,而不仅仅是第二个正确
    • @physics123 您误解了 requestAnimationFrame 的作用。代码按顺序执行。 requestAnimationFrame,简而言之,将函数排队等待稍后运行。您的代码同时将这两个函数放入队列中。然后,稍后,当 requestAnimationFrame 触发排队的函数时,您的两个函数都将被执行,并且它们的添加顺序相同。所以你只能看到最后一个函数调用的结果。
    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    相关资源
    最近更新 更多