博客
电影
宝箱
友链
关于
<
SQL快速运用指南
原生ajax及jQuery封装ajax实例
>
CSS变形matrix与动画cubic-bezier
作者:
Cifer
类别: 技术·CSS
时间:2016-11-16 12:07:27
字数:8291
版权所有,未经允许,请勿转载,谢谢合作~
#### 前言 可能大家张口HTML5,闭口CSS3,不过这些都不是新技术,只是HTML与CSS的新版本而已,只是因为其版本做出巨大的改变,以致于人们带上版本号来凸显出它们该版本的地位。 我们都知道HTML5的标准正式发布是2014年9月,那CSS3的标准正式发布是什么时候呢?在W3C官网<a href="https://www.w3.org/Style/CSS/" title="https://www.w3.org/Style/CSS/" target="_blank" rel="nofollow">https://www.w3.org/Style/CSS/</a> 便可发现CSS3并不是一个一次性发布的版本,而是陆续的发布各个模块。按照前端惯例,早在标准发布之前,各大浏览器厂商就有自己带前缀的css3功能的部分实现,而标准出来,只是统一它们的写法以及驱使一些厂商对其支持而已。其实我们也不用在意这个时间,因为移动端已经给足了CSS发展的空间,而那些不支持的新标准特性的浏览器被淘汰只是迟早的事! 本文主要是[西法](http://www.boatsky.com "太空船博客")简单分析一下css3常用动画属性的原理。 #### 转换(变形) ##### 转换的方式 CSS3支持元素的转换(变形)transform,我们可以理解为像素点的转换,就是经过特定的公式计算,把像素点由位置A变成A‘,不过这种关系并不一定是一对一的。 在写转换之前,得先确认转换中心点 transform-origin: (x, y, z); 如果是2d则无需第z值 取值有left, center, right, length, % 默认值是50% 50% 0 transform转换分两种,从属性来看: 2D转换matrix(a,b,c,d,e,f) 3D转换matrix3d(a,b,c,d, e,f,g,h, i,j,k,l, m,n,o,p) 一眼看上去是不是有点复杂的?其实只要你仔细看看,就会发现,它确实有点复杂~ matrix是一个三阶矩阵,matrix3d是一个四阶矩阵,事实上,2D转换只是3D转换的一种特殊情况。 这时,你一定冒出一个大大的疑惑,matrix3d是4x4矩阵,所以为16个参数,而matrix是3x3矩阵,为什么只有6个参数? a c e b d f 0 0 1 明白了吧,最下面的三个参数是有默认值的,在matrix方法里暂时无法参入三个参数(PS:为了方便修改,所以就没有使用图片来表示矩阵,请假想有一对[ ]是跨过3行把整个内容包起来哈哈) 经过一定的转换关系: a c e x ax + cy + e b d f * y = bx + dy + f 0 0 1 1 0 + 0 + 1 ##### 偏移 translate 我们假设这个转换是偏离中心(0,0)即 x = 0,y = 0 则得到 a c e 0 ax + cy + e e b d f * 0 = bx + dy + f = f 0 0 1 1 0 + 0 + 1 1 与原来只是偏离了(e,f)坐标 即matrix(a,b,c,d,e,f),假设前面的元素都不变的情况下,只改变最后两个参数e,f,则会进行一个x轴移动e,Y轴移动f的位移转换 不过,css3的制作者们为了大家在这种x = 0,y = 0很特殊的情况下更简单的使用,命名了一个很特殊的属性 translate 比如,我们居中对齐的时候,常常会这么写: ```sass .face { position: absolute; top: 50%; left: 50%; width: 200px; height: 200px; transform: translate(-50%,-50%); /*等于transform: matrix(1, 0, 0, 1, -100, -100);*/ } ``` so ```sass transform: martrix(1, 0, 0, 1, e, f); ``` 等于: ```sass transform: translate(e,f); ``` 前者无需带单位(只能是px),后者可以是px,也可以是% ##### 缩放 scale 再看一种情况,设e=f=0,即在原坐标转换,同时设b=c=0 a 0 0 x ax 0 d 0 * y = dy 0 0 1 1 1 坐标由(x,y)变成了(ax,dy),即沿x轴向两边一共缩放a倍,y轴向两边一共缩放d倍,这种特殊的情况,我们又有一个命名,scale(a,d) ```sass transform: martrix(a, 0, 0, d, 0, 0); ``` 等于 ```sass transform: scale(a,d); ``` 前后者单位都是倍数 ##### 旋转 rotate 旋转与上述两种方法有点不同,因为它不再是x轴y轴的垂直变化,而是以逆时钟方向的角度变化 这里设 a = d = cosθ , b = sinθ, c = -sinθ cosθ -sinθ 0 x x*cosθ - y*sinθ sinθ cosθ 0 * y = x*sinθ + y*cosθ 0 0 1 1 0 + 0 + 1 而rotate(x)则是为这种情况命名的,其以逆时钟旋转 ```sass transform: martrix(cosθ, sinθ, -sinθ, cosθ, 0, 0); ``` 等于 ```sass transform: rotate(x); ``` 前者单位是正弦或余弦值,取值[-1,1],后则是角数 ##### 倾斜(拉伸)skew 设b = tanθy c= tanθx 1 tanθx 0 x x + y*tanθx tanθy 1 0 * y = x*tanθy + y 0 0 1 1 1 这种特殊情况用skew命名 ```sass transform: martrix(1, tanθy, tanθx, 1, 0, 0); ``` 等于 ```sass transform: skew(x,y); ``` 前者是正切,后者是度数,分别表示x轴顺时钟倾斜度数,Y轴顺时钟倾斜度数 ##### 2d与3d matrix3d比起matrix比多一个z轴,更复杂一些,不过原理是一样,这里不再展开。 此处简单提下几种特殊情况: translateZ(z)是指沿元素平面垂直方向移动z px,该垂直方向可能是与屏幕平行,也可能不是! skewZ(z) 目前没有这个方法 perspective: none|n; 属性定义 3D 元素距视图的距离,默认none或0,当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身。如果是无限大,与none就接近,如果值越小,则相当于你离元素越近,看到的元素越大。 scaleZ(z), perspective(n)必须在3d上体现出来 perspective-origin: left | right | center | length | percent 设置观察者的位置,默认是(50%, 50%) backface-visibility: visible | hidden; 设置3D元素背部是否可见,默认是visible。 更多参考 <a href="http://www.w3cplus.com/css3/transform-basic-property.html" target="_blank" rel="nofollow">http://www.w3cplus.com/css3/transform-basic-property.html</a> <a href="https://css-tricks.com/almanac/properties/p/perspective-origin/" target="_blank" rel="nofollow">https://css-tricks.com/almanac/properties/p/perspective-origin/</a> rotateX(x)沿x轴逆时钟旋转, rotateY(y)沿y轴逆时钟旋转,rotateZ(z)沿z轴逆时钟旋转(此时与2d rotate(x)是一样的) 看了这么多,是不是觉得matrix用的太麻烦了,只能这么说,所有的转换都是matrix实现的,以上转换能实现的动画,matrix也能实现,matrix能实现的动画,以上转换方法不一定能实现。 相关matrix可参考<a href="http://www.zhangxinxu.com/wordpress/2012/06/css3-transform-matrix-%E7%9F%A9%E9%98%B5/" target="_blank" rel="nofollow">http://www.zhangxinxu.com/wordpress/2012/06/css3-transform-matrix-%E7%9F%A9%E9%98%B5/</a> 同时有一个空页面供测试: http://www.boatsky.com/static/html/demo/animation/matrix.html #### 过渡 过渡transition,指一种样式向别一种样式变化的过程,主要有以下属性: | 属性 | 取值 | 默认 | 描述 | | ------------ | ------------ | ------------ | ------------ | | transition-property | none,all,property(详情见下) | all |过渡属性 | | transition-duration | s | 0 | 花费时间 | | transition-timing-function | cubic-bezier(n,n,n,n) | ease | 过渡效果速度曲线 | | transition-delay | s | 0 | 过渡延时时间s | | transition | | | 以上四种简写 | transition-property 并不是所有属性都可以过渡的,可以过渡的属性参考官网 <a href="https://www.w3.org/TR/css3-transitions/#properties-from-css-" title="https://www.w3.org/TR/css3-transitions/#properties-from-css-" target="_blank" rel="nofollow">https://www.w3.org/TR/css3-transitions/#properties-from-css-</a> transition-timing-function 使用的方法cubic-bezier,是三次贝塞尔曲线的特殊情况 讲到这里就不得不说个小故事: 皮埃尔·贝塞尔(Pierre Bézier,不是德国的那个数学家贝塞尔哦),1910年9月1日——1999年11月25日,法国机械和电气工程师,计算机几何建模创始人之一。并且,他是67岁的时候获巴黎大学数学博士学位,67岁。同时,我当时大学时有个教授72岁,他是50岁才开始学习计算机及英语,上课精神饱满! 这个说回来,三次贝塞尔曲线的公式: B(t) = P0(1 - t)3 + 3P1t(1 - t)2 + 3P2t2(1 - t) + P3t3,t ∈[0,1] P0, P1, P2, P3是平面上的4个点的坐标,使用这4个点坐标,以及t,可以使用三层等比切线获取B(t)这条曲线。 如果你觉得不太形象,可以看看,过程分析<a href="http://blog.csdn.net/cdnight/article/details/48468653" target="_blank" rel="nofollow">http://blog.csdn.net/cdnight/article/details/48468653</a> 以及动态图演示<a href="http://blog.csdn.net/likendsl/article/details/7852658" target="_blank" rel="nofollow">http://blog.csdn.net/likendsl/article/details/7852658</a> ,可以看到,从线性贝塞尔曲线,二次贝塞尔曲线,三次贝塞尔曲线及N次贝塞尔曲线,可以画出各式各样的神奇曲线。 回到cubic-bezier(a, b, c, d),它却只有4个参数,如何确定4个点坐标?我们可以看一下css3 cubic-bezier官网的图形实现<a href="http://cubic-bezier.com/#.63,.1,.28,.9" target="_blank" rel="nofollow">http://cubic-bezier.com/#.63,.1,.28,.9</a> ,显然,cubic-bezier实现的只是三次贝塞尔曲线的特殊情况,即P0(0,0), P3(1,1),我们能自己控制的 P1(a, b), P2(c, d) ,使用这两个值来确定整个时间--位移曲线的变化,而同时,css3在本身就特殊的cubic-bezier,再特殊一些,就可以得到其他速度曲线值了。 | 特殊值 | cubic-bezier | 说明 | | ------------ | ------------ | ------------ | | linear | cubic-bezier(0,0,1,1) | 匀速 | | ease | cubic-bezier(0.25,0.1,0.25,1) | 先加速,后减速,非对称,初始加速远大于结束加速度(负) | | ease-in | cubic-bezier(0.42,0,1,1) | 加速 | | ease-out | cubic-bezier(0,0,0.58,1) |减速 | | ease-in-out | cubic-bezier(0.42,0,0.58,1) | 先加速,后减速,对称,加减对比明显 | 那问一个问题了,能不能用cubic-bezier实现加速度为g的自由落体?使用s=1/2*gt2代入这些特殊的三次贝塞尔曲线?代入是无解的,其实不需要计算,因为真实的自由落体不会经过(1, 1)这个点。 #### 动画 ##### 动画控制 animation animation拥有过渡transtion四个属性,功能也是一样的,只是属性全名不再是transition作为前缀,而是使用animation作为前缀,并且animation-name表示的是动画过渡的内容,而不是过渡的属性transition-property。animation强调的是过渡本身,一般需要主动触发,而animation是强调控制,可自动执行。 | 属性 | 取值 | 默认 | 描述 | | ------------ | ------------ | ------------ | ------------ | | animation-name | @keyframes命名的动画名称 | 需填 |动画名字 | | animation-duration | s | 0 | 花费时间 | | animation-timing-function | cubic-bezier(n,n,n,n) | ease | 动画效果速度曲线 | | animation-delay | s | 0 | 动画延时时间 | | animation-iteration-count | n,infinite | 1 | 执行次数 | | animation-direction | normal,alternate | normal | 轮流反向播放 | |animation-fill-mode | none,forwards,backwards,both | none | 动画外保持状态,分别是默认、最终、开始、都保持 | | animation-play-state | paused,running | | 动画状态 | | animation | | | 以上简写 | ##### 动画过渡内容@keyframes 规则动画各个阶段的内容状态: ```sass @keyframes the_walking_dead { 0% {}/*等于from*/ 40% {} 100% {}/*等于to*/ } ``` #### 实例 ##### css3球自由落体 上述已经表明,该特殊的三次贝塞尔曲线不能实现真实的自由落体,所以本例子是一个模拟的匀加速的自由落体,使用ease-in与ease-out 下降是一个匀加速的,如果球有弹性的,那么球还会上弹,假设两次,第一次上弹是匀减,第一次上弹后再下落是匀加速,第二次上弹同理。 不过每个元素的动画是唯一的,所以这里使用了三个小球,做了三段动画,只有在特定的时间,才会显示特定的小球。 实例请戳 <a href="https://www.boatsky.com/static/demo/animation/free_fall.html" target="_blank">https://www.boatsky.com/static/demo/animation/free_fall.html</a> ##### css3简单的天体运动 天体运动涉及到复杂的物理知识,形状、曲线运动、角度、比例都在时时变化,纯CSS基本无法真实模块出来,所以本例子也是一个不真实的天体运动 太阳与星球自转都是使用背景图移动,为了无痕移动,必须切一张左边与右边可以衔接的背景图 而星球的公转,则是使用两个动画分别在x轴与y轴执行,叠加实现,但一个元素又只能有一个动画,所以,在星球里,还有一个伪元素 同时,因为角度的不同,与远近不同,对星球进行放大缩小 实例请戳 <a href="https://www.boatsky.com/static/demo/animation/free_fall.html" target="_blank">https://www.boatsky.com/static/demo/animation/astronomy.html</a> ##### css3实现简单的立方体 本动画,主要是使用把6个重叠的平面,进行移动、转化,形成一个立方体,为了突显是一个立方体,对外层元素进行x, y, z轴同时进行360度转动 实例请戳 <a href="https://www.boatsky.com/static/demo/animation/cube.html" target="_blank">https://www.boatsky.com/static/demo/animation/cube.html</a> ##### 后记 因为讲述的东西偏多,所以[cifer](https://www.boatsky.com "太空船博客")只能简单表述一下,不过纯粹的css来写复杂动画,在控制上显的疲软。 实例是有限的,想像是无限的。 如果想要更逼真的动画,则需要你对现实生活的观察,使用真实世界物理知识来虚拟你想要的动画。
如果觉得有帮忙,您可以在本页底部留言。
相关推荐:
CSS不定高元素transition动画的解决方案
CSS常用的水平垂直居中方法
sass之scss心得
……
更多
<
SQL快速运用指南
原生ajax及jQuery封装ajax实例
>
全部留言
我要留言
内容:
网名:
邮箱:
个人网站:
发表
全部留言