创建自定义的jQuery补间动画运动函数及其实现的数学原理


发布者 newghost  发布时间 1429888963890
关键字 大话编程  分享 
jQuery动画可以用animte函数实现,该方法通过CSS样式将元素从一个状态改变为另一个状态。

animte函数

CSS属性值是逐渐改变的,这样就可以创建动画效果。只有数字值可创建动画,比如:

$("#content").animate({height:"100px"});
直接在在页按F12,然后在console中复制上面代码即可执行。

该函数的接口是:

$(selector).animate(styles,options)
$(selector).animate(styles,speed,easing,callback)
对于第一种接口 options 可能的值:
  • speed - 设置动画的速度
  • easing - 规定要使用的 easing 函数
  • callback - 规定动画完成之后要执行的函数
  • step - 规定动画的每一步完成之后要执行的函数
  • queue - 布尔值。指示是否在效果队列中放置动画。如果为 false,则动画将立即开始
  • specialEasing - 来自 styles 参数的一个或多个 CSS 属性的映射,以及它们的对应 easing 函数

如:

$("#content").animate({height:"100px"}, "linear");

easing函数


在jQuery 1.4.2中,默认提供了提供了两种动画补间效果, 线性和摆动运动曲线:
但我们需要使用复杂一些的运动效果,比如让元件按照双曲线或抛物线运动趋势改变时,这两个函数就显得明显不够了。
不过这实现起来并不复杂,只需要按照相应的数学公式,添加自定义的easing补间动画效果函数即可。
比如,现在要让网页上的元件按照 y = x^4 的曲线运动,运行趋势为先缓后急。

jQuery1.4的linear和swing的动画实现代码是这样的,最新版的jQuery做了改进,只使用了一个参数p,但不容易看出各个参数的作用,因此这里使用了一个比较原始版本。

jQuery.extend({
    ……
    easing: {
        linear: function( p, n, firstNum, diff ) {
            return firstNum + diff * p;
        },
        swing: function( p, n, firstNum, diff ) {
            return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
        }
    },
    ……
});

要实现这个运动趋势,首先需要定义一些参数。

t:time, b: begin, c: change, d: duration

t: current_time  当前时间
b: start_value   初始位置值(比如x轴运行时)
c: end_value     change in position (单位时间内的改变值)
d: total_time    持续时间

对应jQuery中就是这样的

jQuery.easing.method(
    null†,
    current_time,
    start_value,
    end_value,
    total_time)

第一个参数不是必要的,只是为了兼容jQuery,jQuery自带的两个函数linear和swing没有用到最后一个参数。

我们再来看一看 y = x^4 的位置与时间相关的几何曲线:



x 轴代表时间t (单位缩放为1)
y 轴代表距离

加上修正系数c和b,速度和初始位置: y = c*x^4 + b;
因为 x = t/d,即当前时间除以持续时间,最大值为 1
则公式变为: y = c*(t/d)^4 + b; 
套到jQuery中最终公式为则可变成函数:

jQuery.easing['easeInQuint'] = function(p, t, b, c, d) {
    return c * Math.pow (t/d, 4) + b;
};

//应用: 将当前页面按照easeInQuint运动趋势滚动到项部

$('html, body').animate({
    scrollTop: 0
}, {
    duration : 500
  , easing   : 'easeInQuint'
})


上面的动画其实不太明显,下面这个动画就比较复杂了,可以将最顶部的导航栏实现类似弹簧移动的效果,直接粘到console中即可运行(按F12打开)


jQuery.easing['easeOutBounce'] = function (x, t, b, c, d) {
    if ((t/=d) < (1/2.75)) {
        return c*(7.5625*t*t) + b;
    } else if (t < (2/2.75)) {
        return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    } else if (t < (2.5/2.75)) {
        return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    } else {
        return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    }
}

$('.navbar.navbar-inverse').animate({
    top: 200
}, {
    duration : 1000
  , easing   : 'easeOutBounce'
})

有一个jQuery插件把很多常用的动画效果补间公式都实现了,可以查看: http://gsgd.co.uk/sandbox/jquery/easing/

更详细的英文讲解,可参考此文[Flash AS3版]: http://www.robertpenner.com/easing/penner_chapter7_tweening.pdf