如何在 JavaScript 中保存动画后的对象位置?

How to save object position after animation in JavaScript?

我正在尝试为游戏中的对象制作动画,在该游戏中,按下用户按钮时球应该向上、向右、向左和向下移动。我试图通过在球上使用 .animate() 函数来实现这一点。但是在每个动画事件之后,球都会重置到它的初始位置并且不会继续从它的 "new" 位置移动。有什么办法可以做到这一点?

为了简单起见,以下是我的浓缩代码片段:

/* Animation */

var item = document.getElementById('item');
var anim;
function myMoveLeft(){
 anim=item.animate([
  // keyframes
  { transform: 'translateX(0px)' }, 
  { transform: 'translateX(-60px)' }
], {
     duration: 1000,
     iterations: 1
  });


}

function myMoveDown(){
 anim=item.animate([
  // keyframes
  { transform: 'translateY(0px)' }, 
  { transform: 'translateY(60px)' }
], {
     duration: 1000,
     iterations: 1
  });

  // anim.onfinish(()=>{console.log("onfinish ran")})

}

item.addEventListener('animationend', () => {
  console.log('Animation ended');
});
button{
  display:inline-block;
  height:40px;
  width:80px;
}
#myContainer {
  width: 400px;
  height: 400px;
  position: relative;
  background: lightgray ;
}

#item {
  background: orange;
  position: absolute;
  right:30px;
  top:30px;
  height: 30px;
  width: 30px;
  border-radius:50%;
}
<p>
  <button onclick="myMoveLeft()">Left</button> 
<button  onclick="myMoveDown()">Down</button> 
</p>

<div id ="myContainer">
  <div id="item"></div>
</div>

如上所示,我已经尝试使用 .onfinish() 和事件侦听器 'animationend' 希望我可以更新新的 'right' 和 'top' 位置,但它不起作用。不确定这是否是正确的方法。

有人可以建议如何将元素保存到新位置并从该新位置进一步设置动画吗?

PS:如果您觉得还有其他更好的方法,我也愿意 suggestions/techniques。

非常感谢!!

  1. 你可以使用fill选项让小球获得最终的变换值,这与css动画中的animation-fill-mode相同。

  2. 为了不在做下一个动画时覆盖变换,可以将x和y值保存为变量,根据当前x和[=16做任何动画=] 状态。 (从 x 到 x-60,而不是从 0 到 -60,等等)

示例:

/* Animation */

var item = document.getElementById('item');
var anim;
var x=0, y=0;
function myMoveLeft(){
 anim=item.animate([
  // keyframes
  { transform: `translate(${x}px, ${y}px)` }, 
  { transform: `translate(${x-60}px, ${y}px)` }
], {
     duration: 1000,
     iterations: 1,
     fill: 'forwards'
  });
  x -= 60;

}

function myMoveDown(){
 anim=item.animate([
  // keyframes
  { transform: `translate(${x}px, ${y}px)` }, 
  { transform: `translate(${x}px, ${y+60}px)` }
], {
     duration: 1000,
     iterations: 1,
     fill: 'forwards'
  });
  y += 60;
  // anim.onfinish(()=>{console.log("onfinish ran")})

}

item.addEventListener('animationend', () => {
  console.log('Animation ended');
});
button{
  display:inline-block;
  height:40px;
  width:80px;
}
#myContainer {
  width: 400px;
  height: 400px;
  position: relative;
  background: lightgray ;
}

#item {
  background: orange;
  position: absolute;
  right:30px;
  top:30px;
  height: 30px;
  width: 30px;
  border-radius:50%;
}
<p>
  <button onclick="myMoveLeft()">Left</button> 
<button  onclick="myMoveDown()">Down</button> 
</p>

<div id ="myContainer">
  <div id="item"></div>
</div>