【问题标题】:Low frame rate on JS and CSS animationsJS 和 CSS 动画的低帧率
【发布时间】:2015-09-06 06:41:23
【问题描述】:

所以,正如您在 JSFiddle 中看到的那样,我正在使用原生 JavaScript 制作弹跳动画,它旨在成为一个浮动的云。

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

我发现将 px 数量从 10 增加到 20 会增加它的平滑度,我想是因为它的距离更长并且运行速度更快。我有点想不通它可能是什么。

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

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

编辑

使用 transfom 我能够使其更平滑:

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;
        }
    }
}

【问题讨论】:

  • 为什么不使用css转场(codepen.io/dodozhang21/pen/siKtp)或JS存在框架(jqueryui.com/resources/demos/effect/easing.html)?
  • 回答第二个,因为我想自己学习如何做,我不会重新发明轮子,但我想知道我能造出一个。第一个,我从来没有使用过 SCSS,我想用 JS 事件来解决这个问题(我正在练习 JS)。我尝试过使用转换,效果很好(尽管我更喜欢上面所说的 JS),但是当我移动鼠标时它会重置,不知道为什么。
  • 按照@fixmycode 的建议,在 CSS 和 JS 之间进行选择。这是一个使用 rAF 的纯 JS 示例:jsfiddle.net/Lfed8wbh/5
  • @Ted:看看这个带有注释 cmets 的 updated fiddle
  • @Ted: 并在 requestAnimationFrame API 上阅读 this

标签: javascript css css-transitions frame-rate


【解决方案1】:

您可以将更大的数字设置为偏移量的变化(200 而不是 10),为过渡设置更长的持续时间(20 秒而不是 1 秒),并使用更短的 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;
        }
    }
}

尚未完全测试,但您可以尝试一下。

【讨论】:

    【解决方案2】:

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

    片段:

    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;
    }
    &lt;div id="cloud" class="style"&gt;&lt;/div&gt;

    注释包含在 sn-p 本身中。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 2011-03-01
      相关资源
      最近更新 更多