JQuery animate.easing

JQuery animate.easing

意昂扬的杨意昂扬的杨

JQuery动画能实现各种效果,相比css动画、原生JS动画解决了兼容性问题;一般的动画用起来比较简单,通过更改`$.animate.easing`这个对象能够实现出更复杂、更炫酷的效果。

网上关于easing的插件很多,但很少有解释清楚easing的原理,在这里自己简单测试了一下,有兴趣的同学可以参考一下,自己定义一些动画效果。

  • 先看这么一段简单的代码以及效果:
$('#ball').animate({
  left: 200
},3000,'linear')



可以看到小球匀速运动,那么 linear 究竟做了什么

console.log($.easing.linear)
//function (e){return e}

可以看到 linear 是一个函数,形参只有一个,那么实参也是一个吗?这是JQuery内部的事,我们直接去验证得到结果。

//在元素调用 animate 时传入 linear ,运动过程必然会调用linear,把这个函数加个 log 看看输出几个参数。
$.easing.linear = function (e){
  console.log(arguments)
  return e
}

$('#ball').animate({
  left: 200
},3000,'linear')



输出了实参的数组,而且一直在变化,最终得到:

[object Arguments] {
  0: 1,
  1: 3000,
  2: 0,
  3: 1,
  4: 3000
}
  • 很容易看出:
  1. 第一个参数为当前进程;
  2. 第二个参数为当前时间;
  3. 第三个参数为初始进程;
  4. 第四个参数为总进程;
  5. 第五个参数为总时间。


  • linear 是匀速运动,比较简单,只用了第一个参数实现
console.log($.easing.linear)
//function (e){return e}

从上边测试中 linear 第一个参数由0至1不断变化,可以看出 linear return出来的就是进程,也就是例子中表现出的移动距离; linear return 的值是多少,进程就到达多少,通过 return 值改变的快慢来控制速度。


function (e){return e}可以理解为把整个进程从时间上平均分了 n 份,每增加一份,也就是每过了这一段时间(JQuery设定的是13ms),用这个函数决定实际的进程,前边例子是距离。因为 linear 每时每刻输出等于输入,所以是匀速的。(有点难理解,我自己的想法仅供参考(\*\^__^*),表象就是这样 )


也可以理解为坐标轴上的时间-距离曲线。


  • 为了看清楚一些,我在 linear 基础上稍作修改
//当时间(也可以说进程)消耗)0.8之前,我让他匀速运动;过了0.8,直接跳到 left:200。
$.easing.x = function (e){
  if(e<0.8){
    return(1*e)
  }else{
    return(1)
  }
}
$('#ball').animate({
  left: 200
},3000,'x')

上边都是一个方向的运动,如果我们两个方向都有运动,通过设定时间-距离函数,就可以得到各种效果了。


  • 试着做一个防平抛运动

我们的小球被从左向右抛,同时小球自身往下边掉;


$.easing.x = function (pro){
 return pro
}
//垂直距离是与时间的平方成正比,所以垂直方向做加速运动
$.easing.y = function (pro,t){
  return (t/500)*(t/500)
}
$('#ball').animate({
  left: [400,'x'],
  top: [200,'y']
},500)



  • 圆形轨迹

左右的运动比较简单


$.easing.x = function (pro){
 if(pro<=0.5){
//先匀速向右运动到400px
      return 2*pro
    }else{
//再匀速向左运动到0px
    return 2-2*pro
  }
}


上下运动利用勾股定理计算,注意 pro 的取值

如图在进程的前一半,top 取值为正值,途中三角形水平方向的直角边为`pro*4-1`的绝对值,因为 pro=1时,top取值为200,即半径,而小球实际运动为4个半径。(感觉解释不清楚了……)


如果……如果理解了前一半,后一半就简单了。


$.easing.y = function (pro){
  if(pro<=0.5){
      return Math.sqrt(1-(pro*4-1)*(pro*4-1))
    }else{
    return -1*Math.sqrt(1-((pro-0.5)*4-1)*((pro-0.5)*4-1))
  }
}


$('#ball').animate({
  left: [400,'x'],
  top: [200,'y']
},5000)


文章被以下专栏收录
还没有评论
推荐阅读