如何用js自己实现Animate运动函数

js运动是我们学习js必不可少的研究部分,首先我们要知道js的运动其实仅仅是不断改变元素的某个属性值而已,比如不断改变一个绝对定位div的left值,那么你看到的效果就是这个div不断的向右边运动,那么运动的原理就是这样。

我们知道从a这一点到b这一点我们的运动方式有很多,

1.比如匀速运动到这一点

2.比如先快后慢,

3.必须先慢后快等等

所以我们的运动算法也有很多,那么下面我就图解一下如何写我们自己的运动算法

先看匀速算法

于是我们可以用js写出这段代码

        /** 运动算法
         * t:动画已经消耗的时间
         * b:小球初始位置
         * c:小球的需要移动额距离
         * 动画持续的总时间
         * */   
        var tween = {
            linear: function(t, b, c, d){
                return c * t / d + b;
            }
        }    

然后我们看看非匀速运动

我们用代码写出来

var tween = {
       strongEaseOut:function( t, b, c, d){
            return t * t *c / (d *d) + b;
       },
 }

我们现在只是介绍两种不同的运动算法,当然运动算法还要很多,我们不意义例举,我们接着看如何写改变属性的js

首先我们定义一个运动类

var Animate = function ( dom ) {
            this.dom = dom;
            this.startTime = 0;
            this.startPos = 0;
            this.endPos = 0;
            this.propertyName = null;
            this.easing = null;
            this.duration = null;
 }

主要是初始化一些数据,然后我们在Animate的原型上定义一个start方法,该方法表示运动开始

Animate.prototype.start = function ( propertyName,endPos,duration,easing ){
      this.startTime = +new Date;//记录现在的开始时间
      this.startPos = this.dom.getBoundingClientRect()[ propertyName ];//记录开始的位置
      this.propertyName = propertyName;//需要改变的属性(传)
      this.endPos = endPos;//得到目标位置(传)
      this.duration = duration;//得到需要的时间(传)
      this.easing = tween[ easing ]//选择哪种运动的算法(传)
          var self = this;
          var timeId = setInterval(function(){
              //如果self返回false,则取消定时器
              if( self.step()=== false ) {
                  clearInterval( timeId )
              }
          },19)
 }

  上面的setInterval每隔19毫秒就会执行一次,每次都是执行step方法,step方法就是每次需要计算更新小球的位置

Animate.prototype.step = function(){
        //目前的时间
        var t = +new Date;
        //如果时间超过开始时间和需要时间之和,则矫正目前的位置为目标位置
        if( t >= this.startTime + this.duration ) {
                this.update( this.endPos )
                return false;//返回false为了取消定时器
        }
        //计算小球的位置
        var pos = this.easing( t - this.startTime, this.startPos, this.endPos-this.startPos ,this.duration)
        //更新div的属性
        this.update( pos )
}    

  那么update方法也仅仅就是更新div的属性而已

//更新当前位置
 Animate.prototype.update = function( pos ){
       this.dom.style[ this.propertyName ] = pos + 'px'
 }

  接下来我们看看我们在html里面如何执行,html代码

<div style="position: absolute;background: blue;width: 100px;height: 100px;left: 0;" id="div"></div>

  然后是执行代码

var div = document.getElementById('div')
var animate = new Animate( div )
animate.start('left',500,5000,'linear')

  到现在我们整个运动就结束了

 完整的代码地址在我的github上https://github.com/jiangzhenfei/Animate/blob/master/index.html

posted @ 2018-05-31 11:19  非常007  阅读(9695)  评论(1编辑  收藏  举报