CSS动画中的贝塞尔

介绍篇:

贝塞尔曲线,法国数学家Pierre Bézier制造。

一种绘制曲线的方法,配有详细的计算公式,按照这样的公式绘制出来的曲线是为贝塞尔曲线。

其在计算机图形中的应用相当广泛,几乎有曲线的地方,就少不了它的身影,如在Photoshop,Flash,CorelDRAW中的使用。

常见贝塞尔曲线示例图:

一阶贝塞尔曲线(线段)

 

bezier-01

 

二阶贝塞尔曲线(抛物线)

 

bezier-02

 

三阶贝塞尔曲线

 

bezier-03

 

其在CSS动画中的使用,简单的说,就是在动画的运动过程中,控制速率的变化。

 

bezier-04

 

进阶篇:

CSS动画中使用的是三阶曲线,如下图所示,三阶曲线共有P0,P1,P2,P3四个节点,其中P0是起点、P3是终点,P1和P2是控制点。同时CSS中使用的曲线,有些特殊,它固定了起点P0(0,0)和终点P3(1,1),仅有控制点可以移动。移动控制点可以改变曲线的曲率(弯曲的程度),通过曲率的变化反映出速率的变化,应用于动画之中。

 

bezier-01

 

之后我们来看下曲率对应速率变化的规律。X轴和Y轴,我们理解为时间轴和距离变化轴,那么单位时间内,距离变化的多少,反应出来的就是速度的快慢。

下图中,X轴的切分是均等的,同时虚线矩形内,x1对应的y1、x2对应的y2,也是相等的,那么认为起点到终点是匀速变化的。

 

bezier-02

 

下图中,X轴的切分是均等的,同时虚线矩形内,x1对应的y1 大于 x2对应的y2,那么认为起点到终点的运动过程中,速度是先快后慢的。

 

bezier-03

 

这两种曲线反应到具体的动画之中的效果如下。

 

bezier-04

 

CSS动画中,使用贝塞尔曲线作为值的属性有两个,transition-timing-function,animation-timing-function,格式为cubic-bezier(P1x,P1y,P2x,P2y),实际应用中的代码实例 transition: all 3.0s cubic-bezier(0.75, 0.25, 0.25, 0.75)。

可能你大多看到的是,ease,linear,ease-in-out 这样的属性值,其实它们也是贝塞尔曲线值,只不过是官方预定义的,以简化明了的名称,替代了复杂的数值书写方式。

以下是一些预定义名称对应的曲线值:

ease: cubic-bezier(0.25, 0.1, 0.25, 1.0)

linear: cubic-bezier(0.0, 0.0, 1.0, 1.0)

ease-in: cubic-bezier(0.42, 0, 1.0, 1.0)

ease-out: cubic-bezier(0, 0, 0.58, 1.0)

ease-in-out: cubic-bezier(0.42, 0, 0.58, 1.0)

深入篇:

1)边界和峰值

前面提到过,CSS中的曲线是固定了起点P0(0,0)和终点P3(1,1)的,那么可直观的认为 X 和 Y 的取值范围是0 – 1。但实际使用中,仅 Y 的取值是允许超出范围的。

如果 X 的取值超出范围,浏览器会认为属性值非法,而无法正常运行动画。如果 Y 取值超出范围,因为 Y 表示的是距离,所以表示出来就是运动距离超出边界或者运动距离反向变小,然后再继续运动到终点,想象出来了吗,是的,这是回弹效果。

峰值表示速度达到最大或最小,很短暂的停留后,再降速或加速到达终点。因为仅有两个控制点,所以会有一个或者两个峰值,表示有一个或者两个速度转折到过程。可以利用峰值,更好的实现动画来表现自己要传达的引导意识。

 

bezier-06

 

2)视差

鉴于更好的理解,上文都是以运动距离属性,来形象的表达动画。贝塞尔曲线表示的是速率,那么基本上可以连续变化的属性,都可以应用,而不仅仅是距离,比如颜色,透明度,尺寸,缩放,翻转等等。如果再加上不同的动画延迟时间,不同的动画运动持续时间,就会产生酷炫的视差效果。

3)案例

刀子磨好了,可以上手试试咯,先看下最终效果吧

 

bezier-07

 

仔细看几遍就会发现,其实五个点的动画是一样的,仅仅是作用了不同的延迟时间,就产生了很高大上的视觉效果。那我们现在拆分出单个点的动画,再来观察,看下图:

 

bezier-08

 

可以观察到以下几个细节:

1. 圆点起初是不可见的,动画的最后是渐隐的,可以用opacity实现。

2. 圆点的运动轨迹是圆周运动,可以用rotate实现。

3. 在速度上,可以分为几个阶段,先由快到慢,然后匀速,然后慢到快再到慢,然后匀速,最后再由快到慢。

OK,可以下手写代码了,我们依照速度的变化规律,把整个动画划分为多个阶段,为每个阶段写上当前的终点样式,包括旋转角度、透明度值。现在动画已经可以运行了,只是不够酷,因为CSS中贝塞尔曲线的默认值,即是 linear: cubic-bezier(0.0, 0.0, 1.0, 1.0),[匀速],所以动画的每个阶段都是匀速变化的。

 

bezier-09

 

现在我们为每个阶段加上,已经调出的贝塞尔曲线取值,再看下效果,是不是和最终效果一样了。

 

bezier-07

 

最终代码如下,大家可以借助文章最后给出的工具,自己多多试试,然后在代码里改成自己的贝塞尔曲线,看看效果吧。

    .loading { position : relative; display : inline-block; }
    .loading .dot { position: absolute; opacity : 0; width: 64px; height: 64px; transform: rotate(225deg); animation-name: loading; animation-iteration-count: infinite; animation-duration: 5.28s; }
    .loading .dot:after { content : ""; position : absolute; width : 6px; height : 6px; border-radius : 50%; background : #000; }
    .loading .dot:nth-child(2) { animation-delay : .23s; }
    .loading .dot:nth-child(3) { animation-delay : .46s; }
    .loading .dot:nth-child(4) { animation-delay : .69s; }
    .loading .dot:nth-child(5) { animation-delay : .92s; }
    @keyframes loading {
        0% { transform : rotate(225deg); opacity : 1; animation-timing-function : cubic-bezier(0, 0, 0.58, 1.0); }
        8% { transform : rotate(345deg); animation-timing-function : cubic-bezier(0.0, 0.0, 1.0, 1.0); }
        30% { transform : rotate(455deg); animation-timing-function : cubic-bezier(0.42, 0, 0.58, 1.0); }
        40% { transform : rotate(690deg); animation-timing-function : cubic-bezier(0.0, 0.0, 1.0, 1.0); }
        60% { transform : rotate(815deg); opacity : 1; animation-timing-function : cubic-bezier(0, 0, 0.58, 1.0); }
        75% { transform : rotate(965deg); animation-timing-function : cubic-bezier(0, 0, 0.58, 1.0); }
        76% { opacity : 0; }
        100% { opacity : 0; }
    }

备注:以下是两个可以即时调试曲线的页面应用

http://cubic-bezier.com/

http://www.css3beziercurve.net/

 

本文文字及图片出自 ued.ctrip.com

余下全文(1/3)
分享这篇文章:

请关注我们:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注