低帧率的JS和CSS动画

Low frame rate on JS and CSS animations

本文关键字:CSS 动画 JS 帧率      更新时间:2023-09-26

所以,正如你在这个JSFiddle中看到的,我在原生JavaScript中做一个弹跳动画,这是一个浮动的云。

问题是我想让它上下弹跳仅为10px,但这样做会使它看起来像是在低帧率,我希望它更平滑。

我发现将px的数量从10增加到20增加了它的平滑度,我想是因为它是一个更高的距离,它运行得更快。我已经想不出它应该是什么了。

elem.style.top = elem.offsetTop - 10 + "px";

上面的代码是用于实现结果的代码,因为应用的"left"属性是在一个类中,而不是元素本身,因此需要使用'offsetTop'。

编辑

使用变换,我可以使它更平滑:

elem.style.webkitTransform = 'translateY(-10px)';

但是问题仍然存在,我想知道如何在原生JavaScript中做到这一点。

HTML

<div id='cloud' class='style'></div>
CSS

#cloud{
    position: absolute;
    width: 50px;
    height: 50px;
    background: green;
    -webkit-transition: all 1s ease-in-out;
       -moz-transition: all 1s ease-in-out;
         -o-transition: all 1s ease-in-out;
        -ms-transition: all 1s ease-in-out;
}
.style{
    left: 150px;
    top: 50px;
}

JS

var bounce = true;
var cloud = document.getElementById('cloud');
var interval = setInterval(animate(cloud), 1000);
function animate(elem) {
    return function () {
        if (bounce) {
            elem.style.top = elem.offsetTop - 10 + "px";
            bounce = false;
        } else {
            elem.style.top = elem.offsetTop + 10 + "px";
            bounce = true;
        }
    }
}

您可以设置一个较大的数字作为偏移量的变化(200而不是10),设置一个较长的转换持续时间(20s而不是1s),并使用较短的setInterval间隔(400而不是1000)来中断转换。您可以使用这三个值的不同值,以获得最佳结果。

参见:http://jsfiddle.net/Lfed8wbh/4/

#cloud {
    position: absolute;
    width: 50px;
    height: 50px;
    background: green;
    -webkit-transition: top 20s ease-out;
    -moz-transition: top 20s ease-out;
    -o-transition: top 20s ease-out;
    -ms-transition: top 20s ease-out;
}
.style {
    left: 150px;
    top: 50px;
}

.

var bounce = true;
var cloud = document.getElementById('cloud');
var top = cloud.offsetTop;
var interval = setInterval(animate(cloud), 400);
function animate(elem) {
    return function () {
        if (bounce) {
            elem.style.top = elem.offsetTop - 200 + "px";
            bounce = false;
        } else {
            elem.style.top = elem.offsetTop + 200 + "px";
            bounce = true;
        }
    }
}

还没有完全测试过,但是你可以试试这个

发布我的评论作为一个解决方案,因为它可能会有所帮助:

片段:

window.requestAnimFrame = (function() {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
    window.setTimeout(callback, 1000 / 60);
  };
})();
var isGoingDown = true;
var cloud = document.getElementById('cloud');
var max = 60; // max position you want to reach to (in px), has to be higher than min
var min = 50; // min position you want to react to (in px), has to be lower than max
var increment = 1; // speed, with 1 being normal, 2 being twice the speed, 0.5 being half and so on ... has to be within the range of (max - min)
cloud.style.top = '50px'; // initially apply the style on the element so it is easily get later
requestAnimFrame(loop);
function loop() {
  requestAnimFrame(loop);
  if (parseFloat(cloud.style.top) >= max) {
    isGoingDown = false;
  } else if (parseFloat(cloud.style.top) <= min) {
    isGoingDown = true;
  }
  if (isGoingDown) {
    cloud.style.top = (parseFloat(cloud.style.top) + increment) + 'px';
  } else {
    cloud.style.top = (parseFloat(cloud.style.top) - increment) + 'px';
  }
}
#cloud {
  position: absolute;
  width: 50px;
  height: 50px;
  background: green;
}
.style {
  left: 150px;
  top: 50px;
}
<div id="cloud" class="style"></div>

包含在代码片段本身中的注释。