JavaScript基于时间的动画算法

minmie 3年前

• 前言
• 基于帧的动画算法（Frame-based）
• 基于时间的动画算法（Time-based）
• 改良基于时间的动画算法
• 总结

基于帧的动画算法（Frame-based）

function moveDiv(div, fps) { var left = 0; var param = 1;

`function loop () {          update();          draw();      }        function update() {          left += param * 2;          if (left > 300) {              left = 300;              param = -1;          } else if (left  0) {              left = 0;              param = 1;          }      }        function draw() {          div.style.left = left + "px";      }        setInterval(loop, 1000 / fps);  }  moveDiv(document.getElementById("div1"), 60);`
`    function moveDiv(div, fps) {          var left = 0;          var param = 1;             function loop () {              update();              draw();          }             function update() {              left += param * 2;              if (left > 300) {                  left = 300;                  param = -1;              } else if (left  0) {                  left = 0;                  param = 1;              }          }             function draw() {              div.style.left = left + "px";          }             setInterval(loop, 1000 / fps);      }      moveDiv(document.getElementById("div1"), 60);`
</div> </div>

基于时间的动画算法（Time-based）

function moveDivTimeBased(div, fps) { var left = 0; var current = +new Date; var previous = +new Date; var param = 1;

`function loop() {          var current = +new Date;          var dt = current - previous; // 计算时间差          previous = current;          update(dt);          draw()      }        function update(dt) {          left += param * (dt * 0.12); // 根据时间差更新位置          if (left > 300) {              left = 300;              param = -1;          } else if (left  0) {              left = 0;              param = 1;          }      }                function draw() {          div.style.left = left + "px";      }        setInterval(loop, 1000 / fps);  }`
`    function moveDivTimeBased(div, fps) {          var left = 0;          var current = +new Date;          var previous = +new Date;          var param = 1;             function loop() {              var current = +new Date;              var dt = current - previous; // 计算时间差              previous = current;              update(dt);              draw()          }             function update(dt) {              left += param * (dt * 0.12); // 根据时间差更新位置              if (left > 300) {                  left = 300;                  param = -1;              } else if (left  0) {                  left = 0;                  param = 1;              }          }                     function draw() {              div.style.left = left + "px";          }             setInterval(loop, 1000 / fps);      }`
</div> </div>

`function update(dt) {            left += param * (dt * 0.12); // 根据时间差更新位置            if (left > 300) {                left = 300;                param = -1;            } else if (left  0) {                left = 0;                param = 1;            }        }`
`      function update(dt) {            left += param * (dt * 0.12); // 根据时间差更新位置            if (left > 300) {                left = 300;                param = -1;            } else if (left  0) {                left = 0;                param = 1;            }        }`
</div>

改良基于时间的动画算法

`function moveDivTimeBasedImprove(div, fps) {          var left = 0;          var current = +new Date;          var previous = +new Date;          var dt = 1000 / 60;          var acc = 0;          var param = 1;            function loop() {              var current = +new Date;              var passed = current - previous;              previous = current;              acc += passed; // 累积过去的时间              while(acc >= dt) { // 当时间大于我们的固定的时间片的时候可以进行更新                  update(dt); // 分片更新时间                  acc -= dt;              }              draw();          }            // update 和 draw 函数不变          setInterval(loop, 1000 / fps);      }`
`    function moveDivTimeBasedImprove(div, fps) {          var left = 0;          var current = +new Date;          var previous = +new Date;          var dt = 1000 / 60;          var acc = 0;          var param = 1;             function loop() {              var current = +new Date;              var passed = current - previous;              previous = current;              acc += passed; // 累积过去的时间              while(acc >= dt) { // 当时间大于我们的固定的时间片的时候可以进行更新                  update(dt); // 分片更新时间                  acc -= dt;              }              draw();          }             // update 和 draw 函数不变          setInterval(loop, 1000 / fps);      }`
</div>

1. 固定的时间片足够小，更新的时候可以减少边缘损失的时间。
2. 不同帧率，不管你是60，30，还是10fps，也是根据固定时间片来执行update函数，所以即使有损失，不同帧率之间的损失是一样的。那么我们三个方块就可以达到同步移动的效果的了！

</div>