CSS3动画详解

您所在的位置:网站首页 css动画和js动画的区别 CSS3动画详解

CSS3动画详解

#CSS3动画详解 | 来源: 网络整理| 查看: 265

CSS3动画详解

2013-08-24

CSS3动画

有人认为CSS动画是做了js的事情,较真起来也算,只是已经抢占许多年了,早些年要实现鼠标滑过链接变色的基本效果,需要动用Java Applet,后来只需给HTML元素加事件onclick=changecolor(),再之后正如你所知,只要写:hover、:focus这样的伪类即可,同样的,现在有了CSS3动画。

CSS3动画的优势: 写起来非常方便,不会js也没问题 有些动画js也不能很好的胜任,比如让一个元素在二维、三维空间旋转 运行效果流畅,让浏览器去优化性能 浏览器从底层优化动画序列,例如当tab不可见的时候,降低更新的频率提高整体性能 劣势: CSS3动画应用的范围还是有限 兼容性:对于增强体验的Feature来说,可以无视 可以做动画效果的属性

理论上来说,任何单独的CSS属性都可以做动画的效果,比如:

width:10px 到 100px padding:0px 到 20px color:#F00 到 #00F top:0px 到 10px border-radius:3px 到 8px transform:rotate(0deg) 到 ratate(45deg)

你也可以给red、blue这样的赋值的颜色属性加transition或animation,它会被自动转化为对应的RGB值。

不可以做动画效果的属性

看下面这些例子:

#container p { display: none; transition: all 3s ease; } #container:hover p { display: block; } /**********************/ #container p { height: 0px; transition: all 3s ease; } #container:hover p { height: auto; }

属性从无到有或到不确定值,动画效果不会生效,因为浏览器不知道如何去做,对于元素从无到有,你可以选择opacity属性来处理。

CSS3 Transition

Transition是被用到最多的也是最简单的CSS3动画类型。如果要做一个10px宽的蓝色元素在3s后变成一个100px宽的红色元素的效果,Transition可以平滑实现,你只需要声明起始和终止这两个状态。

Transition的触发也很简单,可以用:hover、:focus这样的伪类来触发,也可以通过改变元素的样式来触发。

transition的属性 transition-property

transition-property用来声明transition会被应用到的属性。

#container p.one { transition-property: color; } #container p.two { transition-property: width; } #container p.three { transition-property: color, width; }

如果你想应用到所有属性,那可以简单写作all,也可以通过none来关闭transition。

transition-duration

transition-duration用来声明动画持续的时长,可以是s也可以是ms

#container p.one { transition-duration: 3s; } #container p.two { transition-duration: 3000ms; } transition-timing-function

transition-timing-function声明了动画的缓动类型,有下面几个选项:

ease:默认项,动画效果慢慢开始然后加速,到中点后再减速最后缓慢到达终点 ease-in-out:与ease类似,加减速更柔和一些 ease-in:开始比较慢,但是加速和停止曲线比较陡峭 ease-out:开始较快,然后缓慢停止 linear:线性平均速率,通常在color和opacity属性的变化上

最后,还有cubic-bezier函数,可以自己创造更多更优美的缓动类型。

transition-delay

transition-delay声明了动画延迟开始的时间,很容易理解

#container p.one { transition-delay: 0.5s; } #container p.two { transition-delay: 500ms; } transition简写

上面介绍了transition的属性,他们也可以合并成一项,省去了许多拼写,当然也别忘记浏览器前缀:

#container p {     transition-property: all;     transition-duration: 3s;     transition-timing-function: ease-in-out;     transition-delay: 0.5s; } #element { /* starting state styles */ color: #F00; -webkit-transition: all 3s ease-in-out 0.5s; transition: all 3s ease-in-out 0.5s; } #element:hover { /* ending state styles */ color: #00F; } transition的高级用法 不同的transition效果

看这样的例子:

p#animate { color: #ff6; transition: all 3s ease-in-out 0.5s; } p#animate:hover { color: #0f0; transform: scale(4); }

在这个例子中,当鼠标hover,元素在0.5s之后在3s内放大四倍,鼠标移开,需要同样的时间回到原来的状态。如果想要不同的效果,可以这样写:

p#animate { color: #ff6; transition: all 0.5s ease-in-out; } p#animate:hover { color: #0f0; transform: scale(4); transition: all 3s ease-in-out 0.5s; } 多个transition

需要给多个transition指定不同的效果时,all属性解决不了,可以这样写:

p#animate { width: 10em; background-color: #F00; border-radius: 5px; transition-property: width, border-radius, background-color; transition-duration: 1s, 2s; transition-timing-function: ease, ease-out, linear; } p#animate:hover { width: 20em; background-color: #00F; border-radius: 50%; }

注意其中的transition-duration只写了两个,那么第三个transition-property属性background-color就用循环到第一个,也就是说他的transition-duration值是1s。

transition示例 #transition1 {     width:350px;     background-color:#1abc9c;     transition-propety:width,background-color;     transition-duration:.5s, 1s; } #transition1:hover {     width:450px;     background-color:#8e44ad;     transition-duration:.5s, 3s; } CSS3 Animation Animation和Transition的不同 和transition一样都可以定义开始和结束状态,但是animation还可以指定更确定的中间状态 animation可以像transition一样被触发,也可以自动运行 animation可以无限循环的运行下去,也可以指定运行的次数 animation可以在顺序运行也可以反向运行 animatino写起来稍麻烦些,但是依然比js简单许多 定义keyframes @keyframes colorchange { 0% { background-color: #00F; /* from: blue */ } 25% { background-color: #F00; /* red */ } 50% { background-color: #0F0; /* green */ } 75% { background-color: #F0F; /* purple */ } 100% { background-color: #00F; /* to: blue */ } } @-webkit-keyframes colorchange { 0% { background-color: #00F; /* from: blue */ } 25% { background-color: #F00; /* red */ } 50% { background-color: #0F0; /* green */ } 75% { background-color: #F0F; /* purple */ } 100% { background-color: #00F; /* to: blue */ } }

在这个例子中,只是定义了background-color这一个属性,如有需要,可以换做其他。对于0%这个也可以用from关键字来替代,同样的可以用to来代替100%,过渡状态,你可以定义任何百分比,类似12.5%这样的也可以,不过就不用给自己找麻烦了吧。浏览器的prefix也不能少。

应用到元素

将animation应用到元素的属性写法,和transition差不太多,顺序都一致,就不在一个个参数重复说明,直接看代码吧:

#myelement { animation-name: colorchange; /**这里引用了前面定义的动画**/ animation-duration: 5s; animation-timing-function: linear; animation-delay: 1s; animation-iteration-count: infinite; animation-direction: alternate; } /****简写****/ #myelement { -webkit-animation: colorchange 5s linear 1s infinite alternate; animation: colorchange 5s linear 1s infinite alternate; }

animation-iteration-count用来指定动画循环的次数,无限循环用infinite。

animation-direction有四个值:

normal:默认,从0%执行到100% reverse:动画从100%执行到0% alternate:动画在0%到100%之间往复执行 alternate-reverse与alternate一致,不过是从100%开始 Animation示例 Animate color CSS3 Transform

有了transition和animation之后,就可以做出些漂亮的动画效果,如果再搭配transform这一CSS3动画利器,就更出彩了。

CSS3 2D Transform

运用CSS3 2D Transform的技术,可以更自由轻松的来修饰HTML元素。CSS3 2D Transform的基本方法有下面这些:

translate() rotate() scale() skew() matrix() Translate

使用translate()方法,可以将HTML元素在x-y轴平面上做位移,且不会影响到其他元素。

div{ -webkit-transform: translate(20px,20px); -moz-transform: translate(20px,20px); -o-transform: translate(20px,20px); transform: translate(20px,20px); }

效果如下:

Normal Div transform:tranlated(40px, 40px) Rotate

rotate()方法可以将元素按照时钟方向旋转,参数可以是0deg到360deg,也是在x-y轴平面,示例如下:

Normal Div transform:rotate(-30deg) Scale

和名字的一样,scale()方法用来放大一个元素,依然是在x-y轴平面,看示例:

Normal Div transform:scale(1.5,1.3) Skew

skew()方法可以将元素按照指定参数进行扭曲,你需要指定x、y轴的扭曲角度,看示例:

Normal Div transform:skew(30deg,0) Matrix

matrix()方法是以上所有2D效果的方法的总和,写法如下:

div{ transform: matrix(a,b,c,d,tx,ty); }

本质上scale、skew、rotate、translate的效果都是通过matrix实现的,tx、ty表示位移量,关于matrix方法更详细的介绍可以参考这里:理解CSS3 transform中的Matrix(矩阵)

CSS3 3D Transform

了解了2D Transform之后,3D Transform的概念也不会太难,他给HTML元素在x-y平面加上了z轴,我们一个个来看看:

translate3d(tx,ty,tz):他定义了一个3D的位移方法,增加了z轴的偏移量 translateZ(tz):这个方法只在Z轴偏移,与translateX()和translateY()相似 scale3d(sx,sy,sz):在原有的scale方法上增加了z轴的参数 scaleZ(sz):同理,只放大z轴,与scaleX()和scaleY()类似 rotate3d(rx,ry,rz):将元素以给定参数的某一个轴方向旋转 rotateX(angle),rotateY(angle)和rotateZ(angle):只按照某一个轴旋转,rotate3d(1,0,0,30deg)相当于rotateX(30deg),其他类推。

来看看例子:

width:100%; height:100%; transform: translateZ(-200px); width:100%; height:100%; transform: translateZ(100px); width:100%; height:100%; transform: rotateX(45deg); width:100%; height:100%; transform: rotateY(45deg); width:100%; height:100%; transform: rotateZ(45deg);

任何有3D变换的元素,不论最后只是做了2D的变换,或者什么都没做translate3d(0,0,0),都会触发浏览器去计算。不过,以后会更新优化也不一定。

Perspective

激活元素的3D空间,需要perspective属性,写法有两种:

transform: perspective( 600px ); /**或者**/ perspective: 600px;

这两种不同写法,当应用元素只有一个时候,并没有区别,当有多个元素的时候,我们看看效果:

#pers-red .item{ background: red; transform: perspective( 400px ) rotateY(45deg); }                   #pers-blue { perspective: 400px; } #pers-blue .item{ background: blue; transform: rotateY( 45deg ); }                  

上面这两种写法,都触发了元素的3D行为,函数型的写法transform:perspective(400px)适用于单个元素,会对每一个元素做3D视图的变换,而perspective:400px的写法,需写在父元素上,然后以父元素的视角,对多个子元素进行3D变换,多个子元素共享同一个3D空间,可以自己打开console修改感受一下。

perspective的参数值,决定了3D效果的强烈程度,可以想象为距离多远去观察元素。值越大,观察距离就越远,同样的旋转值,看起来效果就弱一些;值越小,距离越近,3D效果就更强烈。

perspective-orgin

通常,对一个元素进行3D变换的时候,变换点都是元素的中心点,如果你想以其他的位置为变换点,那就可以用这个属性来做调整:

perspective-orgin: 20% 70%;

这个是默认值的perspective-orign:50% 50%:

Nature Nature Nature

这个是perspective-orgin: 0% 50%;

Nature Nature Nature transform-style

这个参数用来共享父元素的3D空间,这样说起来有些抽象,下面第一个翻卡片的例子中会讲到。

backface-visibility

backface-visibility 属性可用于隐藏内容的背面。默认情况下,背面可见,这意味着即使在翻转后,变换的内容仍然可见。但当 backface-visibility 设置为 hidden 时,旋转后内容将隐藏,因为旋转后正面将不再可见。该功能可帮助你模拟多面的对象,例如下例中使用的卡片。通过将 backface-visibility 设置为 hidden,可以确保只有正面可见。

CSS3 动画实例

下面例子中的代码,为了方便查看都没有写浏览器前缀,也没有加入其他的修饰属性,所以实际应用时,不要忘记哦,当然也可以直接console查看。

CSS3 翻纸牌

做一个翻纸牌的效果,结构很简单:

1 2

.cardflip是整个3D效果的容器,#card1是翻转效果的元素,.front和.back是翻转的两面。添加样式:

#cardflip { width: 200px; height: 260px; position: relative; perspective: 800px; } #card1 { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; transition: transform 1s; }

首先给#cardflip添加perspective属性,这样才能触发3D变换,之后#card1就在父元素的3D空间中了,用了absolute来定位子元素,设置宽高都是100%,这样就可以让transform-origin在元素的中心点,这个后面再讨论。

transform-style有两个值,一个是默认的flat一个是preserve-3d,由于perspective的3D空间,只能作用于直接的子元素,那么.front和.back也需要#cardflip的3D空间的话,就需要给#card1添加这个属性,

#card1 div{ position: absolute; width: 100%; height: 100%; backface-visibility: hidden; }

只有#card1 div元素共享了外层元素的3D空间之后,3D变换的属性才能生效,这时候的backface-visibility才有效,设置为hidden。

#card1 .front { background: red; } #card1 .back { background: blue; transform: rotateY( 180deg ); } #card1.flipped { transform: rotateY( 180deg ); }

因为设置了backface-visibility,而.back默认就是以Y轴旋转了180度,空间想象一下,.back就转到背面去了,所以hidden属性生效,就看不到.back了。

当#card1添加了.flipped的样式,#card1以Y轴旋转了180度,这时候.front转到了背面,而.back从背面转到了前面,所以就完成了切换。这一段需要仔细的想一想。好了,看看下面的实例,点击即可翻转:

1 2

我们再给这个翻转加一些偏移的效果,看起来会不那么生硬。这就用到了transform-origin,这个参数:

#card1 { transform-origin: left center; } #card1.flipped { transform: translateX( 100% ) rotateY( 180deg ); }

默认的transform-origin是center center,我们改成left center之后,就不再以元素的x方向的中心为轴旋转,而是以元素的左边为Y轴旋转,所以还需要给整个#card1加一个位移量translate,值是100%,就是元素本身的宽度。

可以在console里面去掉#card1.flipped的translate帮助理解。

1 2

这里有一点需要注意,当元素在z轴上有了位移,或者朝向负角度旋转,会导致元素在页面上无法被鼠标点击到,想像一下3D空间,这个元素已经位于整个页面平面的里面,所以无法触及了。

CSS3 立方体

做完了反转卡片的效果,肯定还想做更炫的,来试试做一个立方体吧:

1 2 3 4 5 6 #cube-con { width: 200px; height: 200px; position: relative; perspective: 1000px; } #cube { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; } #cube figure { width: 196px; height: 196px; display: block; position: absolute; border: 2px solid black; }

这一部分和上一个例子没有太大的差别,应该都能理解每一个属性的含义了。

#cube .front { transform: rotateY( 0deg ) translateZ( 100px ); } #cube .back { transform: rotateX( 180deg ) translateZ( 100px ); } #cube .right { transform: rotateY( 90deg ) translateZ( 100px ); } #cube .left { transform: rotateY( -90deg ) translateZ( 100px ); } #cube .top { transform: rotateX( 90deg ) translateZ( 100px ); } #cube .bottom { transform: rotateX( -90deg ) translateZ( 100px ); }

立方体的每一个面,经过rotate旋转之后,就放置在了他该被放置的地方,但是这时候会发现,这些层叠加在一起,还没有成为一个立方体,这时候需要给Z轴一个位移,想象一下我们的视角点在#cube正中间,拉伸z轴之后,.right、left等面就会有一定的角度,参考画画时候的透视,因为刚好在中心点,所以位移量就是宽度的一半。分步过程可以看这里。

因为z轴拉伸之后,原来的对象会被放大一些,这样就会模糊掉,为了去掉这个影响,我们需要把立方体再推回原来的视角平面,于是:

#cube { transform: translateZ( -100px ); }

完成了立方体,想让某个面旋转到前方,只需转动整个立方体,不用去调整每个面:

#cube.show-front { transform: translateZ( -100px ) rotateY( 0deg ); } #cube.show-back { transform: translateZ( -100px ) rotateX( -180deg ); } #cube.show-right { transform: translateZ( -100px ) rotateY( -90deg ); } #cube.show-left { transform: translateZ( -100px ) rotateY( 90deg ); } #cube.show-top { transform: translateZ( -100px ) rotateX( -90deg ); } #cube.show-bottom { transform: translateZ( -100px ) rotateX( 90deg ); } /**还有过渡效果**/ #cube { transition: transform 1s; } 1 2 3 4 5 6 3D 旋转跑马灯

做幻灯片展示的方法有很多,我们用CSS3的3D技术来试试看:

1 2 3 4 5 6 7 8 9 .container { width: 210px; height: 140px; position: relative; perspective: 1000px; } #carousel { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; } #carousel figure { display: block; position: absolute; width: 186px; height: 116px; left: 10px; top: 10px; border: 2px solid black; }

上面这一段,没什么特别要说明的,基本的结构样式,以及之前重点说明过的perspective和preserve-3d。现在有9个卡片,要环绕成一圈,那么每个的角度就是40deg (360/90)。

#carousel figure:nth-child(1) { transform: rotateY( 0deg ); } #carousel figure:nth-child(2) { transform: rotateY( 40deg ); } #carousel figure:nth-child(3) { transform: rotateY( 80deg ); } #carousel figure:nth-child(4) { transform: rotateY( 120deg ); } #carousel figure:nth-child(5) { transform: rotateY( 160deg ); } #carousel figure:nth-child(6) { transform: rotateY( 200deg ); } #carousel figure:nth-child(7) { transform: rotateY( 240deg ); } #carousel figure:nth-child(8) { transform: rotateY( 280deg ); } #carousel figure:nth-child(9) { transform: rotateY( 320deg ); }

好了,和立方体的例子到同样的步骤了,现在所有的卡片做了Y轴旋转,但因为观察的视角点没有变,所以看起来还是平面,如下这样:

caro

立方体的位移很好计算,只要是宽度、高度、或者深度的一半就可以了,这个旋转的跑马灯应该怎么计算呢?

caro-cmpu

从旋转跑马灯的上方观察,每个卡片的宽度是210px,角度是40deg,要计算到中心点的距离,根据旁边的三角形可得:

r = 105 / tan(20deg) = 288px

所以:

#carousel figure:nth-child(1) {transform:rotateY( 0deg) translateZ(288px);} #carousel figure:nth-child(2) {transform:rotateY( 40deg) translateZ(288px);} #carousel figure:nth-child(3) {transform:rotateY( 80deg) translateZ(288px);} #carousel figure:nth-child(4) {transform:rotateY(120deg) translateZ(288px);} #carousel figure:nth-child(5) {transform:rotateY(160deg) translateZ(288px);} #carousel figure:nth-child(6) {transform:rotateY(200deg) translateZ(288px);} #carousel figure:nth-child(7) {transform:rotateY(240deg) translateZ(288px);} #carousel figure:nth-child(8) {transform:rotateY(280deg) translateZ(288px);} #carousel figure:nth-child(9) {transform:rotateY(320deg) translateZ(288px);}

知道了计算方法,如果要改变卡片的个数,或者宽度,只要按照那个公式再计算就好:

var tz = Math.round( ( panelSize / 2 ) / Math.tan( ( ( Math.PI * 2 ) / numberOfPanels ) / 2 ) ); // or simplified to var tz = Math.round( ( panelSize / 2 ) / Math.tan( Math.PI / numberOfPanels ) );

计算好卡片的位置之后,然后旋转#carousel就可以了,当然这个要用js来控制了:

#carousel{ transform: translateZ( -288px ) rotateY( -160deg ); }

js代码如下:

$(function(){ $('#car-pre').click(function(){ var deg = $('#carousel').attr('data-deg') || 0; deg = parseInt(deg)+40; var value = 'translateZ(-288px) rotateY('+deg+'deg)'; $('#carousel') .attr('data-deg',deg) .css({ '-webkit-transform':value ,'-moz-transform':value ,'-o-transform':value ,'transform':value }); }); $('#car-next').click(function(){ var deg = $('#carousel').attr('data-deg') || 0; deg = parseInt(deg)-40; var value = 'translateZ(-288px) rotateY('+deg+'deg)'; $('#carousel') .attr('data-deg',deg) .css({ '-webkit-transform':value ,'-moz-transform':value ,'-o-transform':value ,'transform':value }); }); 123456789 结语

终于完成了这篇,梳理的过程对我自己很有提高,希望对你也能有些帮助,有兴趣可以关注我,期待下以后的博客~



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3