贝塞尔曲线,法国数学家Pierre Bézier制造。
一种绘制曲线的方法,配有详细的计算公式,按照这样的公式绘制出来的曲线是为贝塞尔曲线。
其在计算机图形中的应用相当广泛,几乎有曲线的地方,就少不了它的身影,如在Photoshop,Flash,CorelDRAW中的使用。
常见贝塞尔曲线示例图:
一阶贝塞尔曲线(线段)
二阶贝塞尔曲线(抛物线)
三阶贝塞尔曲线
其在CSS动画中的使用,简单的说,就是在动画的运动过程中,控制速率的变化。
CSS动画中使用的是三阶曲线,如下图所示,三阶曲线共有P0,P1,P2,P3四个节点,其中P0是起点、P3是终点,P1和P2是控制点。同时CSS中使用的曲线,有些特殊,它固定了起点P0(0,0)和终点P3(1,1),仅有控制点可以移动。移动控制点可以改变曲线的曲率(弯曲的程度),通过曲率的变化反映出速率的变化,应用于动画之中。
之后我们来看下曲率对应速率变化的规律。X轴和Y轴,我们理解为时间轴和距离变化轴,那么单位时间内,距离变化的多少,反应出来的就是速度的快慢。
下图中,X轴的切分是均等的,同时虚线矩形内,x1对应的y1、x2对应的y2,也是相等的,那么认为起点到终点是匀速变化的。
下图中,X轴的切分是均等的,同时虚线矩形内,x1对应的y1 大于 x2对应的y2,那么认为起点到终点的运动过程中,速度是先快后慢的。
这两种曲线反应到具体的动画之中的效果如下。
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 表示的是距离,所以表示出来就是运动距离超出边界或者运动距离反向变小,然后再继续运动到终点,想象出来了吗,是的,这是回弹效果。
峰值表示速度达到最大或最小,很短暂的停留后,再降速或加速到达终点。因为仅有两个控制点,所以会有一个或者两个峰值,表示有一个或者两个速度转折到过程。可以利用峰值,更好的实现动画来表现自己要传达的引导意识。
2)视差
鉴于更好的理解,上文都是以运动距离属性,来形象的表达动画。贝塞尔曲线表示的是速率,那么基本上可以连续变化的属性,都可以应用,而不仅仅是距离,比如颜色,透明度,尺寸,缩放,翻转等等。如果再加上不同的动画延迟时间,不同的动画运动持续时间,就会产生酷炫的视差效果。
3)案例
刀子磨好了,可以上手试试咯,先看下最终效果吧
仔细看几遍就会发现,其实五个点的动画是一样的,仅仅是作用了不同的延迟时间,就产生了很高大上的视觉效果。那我们现在拆分出单个点的动画,再来观察,看下图:
可以观察到以下几个细节:
1. 圆点起初是不可见的,动画的最后是渐隐的,可以用opacity实现。
2. 圆点的运动轨迹是圆周运动,可以用rotate实现。
3. 在速度上,可以分为几个阶段,先由快到慢,然后匀速,然后慢到快再到慢,然后匀速,最后再由快到慢。
OK,可以下手写代码了,我们依照速度的变化规律,把整个动画划分为多个阶段,为每个阶段写上当前的终点样式,包括旋转角度、透明度值。现在动画已经可以运行了,只是不够酷,因为CSS中贝塞尔曲线的默认值,即是 linear: cubic-bezier(0.0, 0.0, 1.0, 1.0),[匀速],所以动画的每个阶段都是匀速变化的。
现在我们为每个阶段加上,已经调出的贝塞尔曲线取值,再看下效果,是不是和最终效果一样了。
最终代码如下,大家可以借助文章最后给出的工具,自己多多试试,然后在代码里改成自己的贝塞尔曲线,看看效果吧。
<style> .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; } } </style> <div class="loading" > <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> <div class="dot"></div> </div>
备注:以下是两个可以即时调试曲线的页面应用
http://cubic-bezier.com/
http://www.css3beziercurve.net/本文作者:EKS 转载请注明来自: 携程设计委员会