如何为连续动画添加缓动?

时间:2018-04-18 12:10:55

标签: javascript animation math

我有以下JSFiddle,其中使用requestAnimationFrame,元素沿着x轴不断地反弹到容器的边缘; https://jsfiddle.net/anhd08so/

基本上,在每个帧上,我将定义的速度(vx)添加到位置(x)。然后我检查新位置是否超出范围,如果是,我设置为最小值,并反转vx以使其朝向另一个方向。

var x = 50;
var vx = 5;

var step = function(){
  x = x + vx;

  if(x < 0) {
    x = 1;
    vx = Math.abs(vx);
  } else if(x > 400) {
    x = 400;
    vx = -Math.abs(vx);
  }

  el.css("left", x);
  requestAnimationFrame(step);
};

这是有效的,但方向的改变确实是突然的,而且不现实。我想添加缓动,以便元素在接近边缘时逐渐减慢,并在另一个方向再次加速。

我尝试用vx = vx - vx * 0.3取代Math.abs之类的东西来做这件事,虽然它确实减慢速度,但当它走向另一条路时,它再也不会获得相等的反向速度。< / p>

这当然是CSS转换/关键帧的一块蛋糕,但我的用例需要在代码中逐帧定义运动。

如何为此动作添加缓动,以便元素更改方向看起来更逼真?

2 个答案:

答案 0 :(得分:0)

更新#1

您在https://jsfiddle.net/anhd08so/64/

请注意,使用translateX代替left。如果你想拥有更流畅的动画,最好使用变换。否则,当您更改left或类似内容时,浏览器可能会因重新呈现而变慢。

您可以使用一些自定义立方贝塞尔动画来代替ease-in-out

查看代码。问你是否有任何问题。

&#13;
&#13;
var el = document.querySelector('p');

function toggleDirection() {
	var style = window.getComputedStyle(el, null).getPropertyValue("transform");
  var matrix = new WebKitCSSMatrix(style);
  
  if (matrix.e === 50) {
  	el.classList.add('p--right');
  } else {
  	el.classList.remove('p--right');
  } 
}

el.addEventListener("transitionend", toggleDirection);

window.onload = toggleDirection();
&#13;
div {
  position: absolute;
  width: 400px;
  height: 200px;
  top: 100px;
  left: 100px;
  background: #eee;
}

p {
  position: absolute;
  top: 50px;
  /* left: 50px; */
  transform: translateX(50px);
  width: 2px;
  height: 100px;
  margin: 0;
  background: #111;
  
  transition: transform 2s ease-in-out;
  
  will-change: transform;
}

.p--right {
  transform: translateX(350px);
}
&#13;
<div>
  <p></p>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我认为你要找的是这样的: 在步骤函数之外声明修饰符:

EntityManager

然后在步骤开始时,你只需计算修饰符:

var modifier = 1;

所以你正在做的,基本上是从中点计算出距离(400/2 = 200),然后调整速度。

像这样: https://jsfiddle.net/anhd08so/71/