首页 > 解决方案 > 尝试使用 requestanimationframe 进行对象跳转的代码不起作用

问题描述

我试图使用 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)

标签: javascriptaddeventlistenerrequestanimationframe

解决方案


这里有几个问题。

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

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

据推测,您仅观察到的原因movedown是两者都发生在每一帧上,但是movedown在向上移动之后发生。

看看下面的代码片段,你就会知道,我在这里所做的是重新排列你现有的一些代码。我已将第一次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>


推荐阅读