现代 CSS

CSS3的Animation制作蝴蝶飞舞

特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)

上周六参加WebReBuild上海站活动时,@点头猪分享的《渐近增强——基于CSS3的浏览器分级策略》,里面有一个使用CSS3Animation制作的蝴蝶飞舞的效果特别吸引人。特决定回来尝试一下,但制作出来的效果总是有不同之处,后来经@点头猪的指点和代码分享,终于整明白了怎么回事。现在特意整理一下与大家一起分享@点头猪的成果。好东西就应该和大家一起分享,这可是我的原则。:)

前面在本站的CSS3教程中,已经在CSS3 Animation中对CSS3的Animation做出详细的介绍,并且在《Animate.css》一文中介绍了Daniel Eden制作的多种动效果。如果您还对CSS3的Animate没有任何了解,我强烈建议您先阅读前面两篇教程,这样对您理解蝴蝶飞舞的制作更容易理解。

下面开始我们就开始介绍@点头猪创作的蝴蝶飞舞效果的过程,大家可以先看一下面这个DEMO

上面DEMO只在Apple SafariGoogle Chrome两个浏览器下有效果。

看过效果后,我们就一起来看@点头猪提供的源代码:

HTML Markup

			<div class="butterfly">
				<div class="butter1">
					<div class="butterfly1"><img src="butterfly1.png" alt="" /></div>
				</div>
				<div class="butter2">
					<div class="butterfly2"><img src="butterfly2.png" alt="" /></div>
				</div>
				<div class="butter3">
					<div class="butterfly3"><img src="butterfly3.png" alt="" /></div>
				</div>
			</div>
		

CSS Code

			html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, em { margin: 0; padding: 0; }
			body { font-size: 12px; line-height: 1.5; font-family: Verdana, Simsun; color:#333; }
			img, fieldset { border: 0; }
			a { color: #0053aa; text-decoration: none; }
			a:hover { text-decoration: underline; }
			h1, h2, h3, h4, h5, h6 { font-family:Simsun, sans-serif; }

			.butterfly { width: 980px; height: 200px; margin: 0 auto; overflow: hidden; background: url(bg.jpg) no-repeat center 0; }
			.butter1, .butter2, .butter3 {
				position: relative;
				-webkit-animation-iteration-count: infinite;
				-webkit-animation-timing-function: linear;
				display: none\9; *display: none;
			}
			.butter1 { -webkit-animation-name: butter1; -webkit-animation-duration: 30s; -webkit-transform: rotateZ(-30deg); }
			.butter2 { -webkit-animation-name: butter2; -webkit-animation-duration: 40s; -webkit-transform: rotateZ(-30deg); }
			.butter3 { -webkit-animation-name: butter3; -webkit-animation-duration: 50s; -webkit-transform: rotateZ(30deg); }
			.butterfly1, .butterfly2, .butterfly3 {
				position: absolute;
				-webkit-animation-name: x-spin;
				-webkit-animation-iteration-count: infinite;
				-webkit-animation-timing-function: ease-linear;
			}
			.butterfly1 { height: 36px; left: 40px; bottom: 60px; -webkit-animation-duration: 0.4s; }
			.butterfly2 { height: 40px; left: 80px; bottom: 10px; -webkit-animation-duration: 0.4s; }
			.butterfly3 { height: 40px; right: 60px; bottom: 10px; -webkit-animation-duration: 0.32s; }

			@-webkit-keyframes x-spin {
				0%		{ -webkit-transform: rotateX(0deg); }
				20%		{ -webkit-transform: rotateX(80deg); }
				40%		{ -webkit-transform: rotateX(130deg); }
				50%		{ -webkit-transform: rotateX(180deg); }
				60%		{ -webkit-transform: rotateX(210deg); }
				80%		{ -webkit-transform: rotateX(270deg); }
				100%	{ -webkit-transform: rotateX(360deg); }
			}
			@-webkit-keyframes butter1 {
				0%		{ opacity: 0; }
				10%		{ left: 160px; bottom: 80px; opacity: 1; }
				20%		{ left: 240px; bottom: 45px; }
				30%		{ left: 400px; bottom: 15px; }
				60%		{ left: 720px; bottom: -5px; }
				70%		{ left: 800px; bottom: 30px; }
				80%		{ left: 840px; bottom: 0px; opacity: 0.6; }
				100%	{ left: 900px; bottom: 40px; opacity: 0; }
			}
			@-webkit-keyframes butter2 {
				0%		{ opacity: 0; }
				10%		{ left: 120px; bottom: 40px; opacity: 1; }
				40%		{ left: 180px; bottom: 20px; }
				50%		{ left: 360px; bottom: 0px; }
				60%		{ left: 600px; bottom: -10px; }
				80%		{ left: 640px; bottom: 20px; opacity: 0.6; }
				100%	{ left: 860px; bottom: 30px; opacity: 0; }
			}
			@-webkit-keyframes butter3 {
				0%		{ opacity: 0; }
				10%		{ right: 160px; bottom: 30px; opacity: 1; }
				20%		{ right: 200px; bottom: 10px; }
				40%		{ right: 400px; bottom: 0px; }
				60%		{ right: 620px; bottom: -10px; }
				70%		{ right: 700px; bottom: 10px; opacity: 0.6; }
				100%	{ right: 840px; bottom: 60px; opacity: 0; }
			}
		

上面中有几个地方是关键的:

  1. 创建动画帧:keyframes
  2. 调用动画名:animation-name
  3. 设置动画持续时长:animation-duration
  4. 设置动画变换频率:animation-timing-function
  5. 设置动画开始时间:animation-delay
  6. 设置动画播放次数:animation-iteration-count

具体调用如下图所示:

而且其中还使用了3D Transforms,大家可以在Intro to CSS 3D transforms了解较为详细的介绍。当然大家也可以点击CSS3 3D Transforms学习相关方面的内容,这里我就不过多介绍。由于@点头猪使用了3D Transforms属性,所以只能在Apple SafariGoogle Chrome两个浏览器下有效果。

今天我在@点头猪的效果上做了一下修改,去掉了3D Transforms属性,能兼容Mozilla Firefox,差别就是在Mozilla Firefox下效果没有在Apple SafariGoogle Chrome浏览器下效果完美,最后结合两种效果,让蝴蝶飞舞Apple SafariGoogle Chrome下完美显示,而在Mozilla Firefox下也能有动画效果。下面我们就一起来看看我修改后的代码。

HTML Markup

			<div id="butterfly">
				<div id="butter1" class="butter">
					<div class="butterFly1 butterFly"><img src="butterfly1.png" alt="" /></div>
				</div>
				<div id="butter2" class="butter">
					<div class="butterFly2 butterFly"><img src="butterfly2.png" alt="" /></div>
				</div>
				<div id="butter3" class="butter">
					<div class="butterFly3 butterFly"><img src="butterfly3.png" alt="" /></div>
				</div>
			</div>
		

HTML结构是一样的,下面简单的介绍一下各个层所起的作用:

  1. div#butterfly这里主要是放置花丛的背景图,而且我们三只蝴蝶都是在这个层里活动;
  2. div.butter主要是用来制作蝴蝶移动效果,在不同的帧设置不同的位置,分别调用不同的动画名“butter1”、“butter2”、“butter3”
  3. div.butterFly主要用来制作蝴蝶翅膀拍打效果,我在这里使用了两处效果,在Apple SafariGoogle Chrome两个浏览器下依然使用了@点头猪的代码效果,而在Mozilla Firefox浏览器下却使用了CSS3scale模仿翅膀拍打效果,只是效果不佳而以。大家就奖就一下吧。

CSS Code

			*{
				margin: 0;
				padding: 0;
			}
			
			body { 
				font: 12px/1.5 Verdana, Simsun; 
				color:#333;
				background-color: #EAF7FD;
			}
			#butterfly {
				background: #EAF7FD url("bg_footer.jpg") no-repeat left bottom;
				width: 947px;
				height: 200px;
				margin: 0 auto;
				overflow: hidden;
			}
			
			@-moz-keyframes butter1 {
				0%		{ opacity: 0; }
				10%		{ left: 160px; bottom: -135px; opacity: 1; }
				20%		{ left: 240px; bottom: -170px; }
				30%		{ left: 400px; bottom: -200px; }
				60%		{ left: 720px; bottom: -220px; }
				70%		{ left: 800px; bottom: -185px; }
				80%		{ left: 840px; bottom: -215px; opacity: 0.6; }
				100%	{ left: 900px; bottom: -170px; opacity: 0; }
			}
			
			@-webkit-keyframes butter1 {
				0%		{ opacity: 0; }
				10%		{ left: 160px; bottom: -135px; opacity: 1; }
				20%		{ left: 240px; bottom: -170px; }
				30%		{ left: 400px; bottom: -200px; }
				60%		{ left: 720px; bottom: -220px; }
				70%		{ left: 800px; bottom: -185px; }
				80%		{ left: 840px; bottom: -215px; opacity: 0.6; }
				100%	{ left: 900px; bottom: -170px; opacity: 0; }
			}
			
			@-moz-keyframes butter2 {
				0%		{ opacity: 0; }
				10%		{ left: 120px; bottom: -170px; opacity: 1; }
				40%		{ left: 180px; bottom: -190px; }
				50%		{ left: 360px; bottom: -210px; }
				60%		{ left: 600px; bottom: -220px; }
				80%		{ left: 640px; bottom: -190px; opacity: 0.6; }
				100%	{ left: 860px; bottom: -180px; opacity: 0; }
			}
			
			@-webkit-keyframes butter2 {
				0%		{ opacity: 0; }
				10%		{ left: 120px; bottom: -170px; opacity: 1; }
				40%		{ left: 180px; bottom: -190px; }
				50%		{ left: 360px; bottom: -210px; }
				60%		{ left: 600px; bottom: -220px; }
				80%		{ left: 640px; bottom: -190px; opacity: 0.6; }
				100%	{ left: 860px; bottom: -180px; opacity: 0; }
			}
			
			@-moz-keyframes butter3 {
				0%		{ opacity: 0; }
				10%		{ left: 780px; bottom: -190px; opacity: 1; }
				20%		{ left: 720px; bottom: -210px; }
				40%		{ left: 540px; bottom: -220px; }
				60%		{ left: 320px; bottom: -230px; }
				70%		{ left: 240px; bottom: -210px; opacity: 0.6; }
				100%	{ left: 100px; bottom: -160px; opacity: 0; }
			}
			
			@-webkit-keyframes butter3 {
				0%		{ opacity: 0; }
				10%		{ left: 780px; bottom: -190px; opacity: 1; }
				20%		{ left: 720px; bottom: -210px; }
				40%		{ left: 540px; bottom: -220px; }
				60%		{ left: 320px; bottom: -230px; }
				70%		{ left: 240px; bottom: -210px; opacity: 0.6; }
				100%	{ left: 100px; bottom: -160px; opacity: 0; }
			}
			
			@-webkit-keyframes x-spin {
				0%		{ -webkit-transform: rotateX(0deg); }
				20%		{ -webkit-transform: rotateX(80deg); }
				40%		{ -webkit-transform: rotateX(130deg); }
				50%		{ -webkit-transform: rotateX(180deg); }
				60%		{ -webkit-transform: rotateX(210deg); }
				80%		{ -webkit-transform: rotateX(270deg); }
				100%	{ -webkit-transform: rotateX(360deg); }
			}
			
			@-moz-keyframes x-spin {
				0%		{ -webkit-transform: scale(1,1); }
				20%		{ -webkit-transform: scale(1,-0.2); }
				40%		{ -webkit-transform: scale(1,1); }
				50%		{ -webkit-transform: scale(1,-0.2); }
				60%		{ -webkit-transform: scale(1,1); }
				80%		{ -webkit-transform: scale(1,0.2); }
				100%	{ -webkit-transform: scale(1,1); }
			}
			
			.butter {
				position: relative;
				-webkit-animation-iteration-count: infinite;
				-webkit-animation-timing-function: linear;
				
				-moz-animation-iteration-count: infinite;
				-moz-animation-timing-function: linear;
			}
			#butter1 { 
				-webkit-animation-name: butter1; 
				-webkit-animation-duration: 30s; 

				-moz-animation-name: butter1; 
				-moz-animation-duration: 30s; 

				bottom: -215px;
				left: 5px;
			}
			#butter2 { 
				-webkit-animation-name: butter2; 
				-webkit-animation-duration: 40s; 

				-moz-animation-name: butter2; 
				-moz-animation-duration: 40s;
				
				bottom: -210px;
				left: 50px;
			}
			#butter3 { 
				-webkit-animation-name: butter3; 
				-webkit-animation-duration: 50s; 

				-moz-animation-name: butter3; 
				-moz-animation-duration: 50s;
				
				bottom: -220px;
				left: 840px;
			}
			
			.butterFly {
				position: absolute;
				-webkit-animation-name: x-spin;
				-webkit-animation-iteration-count: infinite;
				-webkit-animation-timing-function: ease-linear;
			}
			.butterFly1 { height: 36px; left: 40px; bottom: 60px; -webkit-animation-duration: 0.4s; }
			.butterFly2 { height: 40px; left: 80px; bottom: 10px; -webkit-animation-duration: 0.4s; }
			.butterFly3 { height: 40px; left: 60px; bottom: 10px; -webkit-animation-duration: 0.32s; }
		

这个效果中有几个关键之处:

1、蝴蝶定位

			.butter {position: relative;}
			#butter1 {bottom: -215px;left: 5px;		}
			#butter2 {bottom: -210px;left: 50px;}
			#butter3 {bottom: -220px;left: 840px;}		
			.butterFly {position: absolute;}
			.butterFly1 { height: 36px; left: 40px; bottom: 60px; }
			.butterFly2 { height: 40px; left: 80px; bottom: 10px; }
			.butterFly3 { height: 40px; left: 60px; bottom: 10px; }
		

我这里使用了相对定位和绝对定位来布置三只蝴蝶的初始位置,首先在div.butter都进行相对定位,并对每一只蝴蝶定位到自己指定的位置,这里需要注意的是此处不能使用绝对定位,如果使用绝对定位会对里面制作蝴蝶翅膀拍打时有影响;接着在给里面的每只蝴蝶进行绝对定位,因为我们里面的只是为了制作其翅膀拍打的效果。如下面的效果:

2、制作蝴蝶移动效果

				@-moz-keyframes butter1 {
					0%		{ opacity: 0; }
					10%		{ left: 160px; bottom: -135px; opacity: 1; }
					20%		{ left: 240px; bottom: -170px; }
					30%		{ left: 400px; bottom: -200px; }
					60%		{ left: 720px; bottom: -220px; }
					70%		{ left: 800px; bottom: -185px; }
					80%		{ left: 840px; bottom: -215px; opacity: 0.6; }
					100%	{ left: 900px; bottom: -170px; opacity: 0; }
				}
				
				@-webkit-keyframes butter1 {
					0%		{ opacity: 0; }
					10%		{ left: 160px; bottom: -135px; opacity: 1; }
					20%		{ left: 240px; bottom: -170px; }
					30%		{ left: 400px; bottom: -200px; }
					60%		{ left: 720px; bottom: -220px; }
					70%		{ left: 800px; bottom: -185px; }
					80%		{ left: 840px; bottom: -215px; opacity: 0.6; }
					100%	{ left: 900px; bottom: -170px; opacity: 0; }
				}
				
				@-moz-keyframes butter2 {
					0%		{ opacity: 0; }
					10%		{ left: 120px; bottom: -170px; opacity: 1; }
					40%		{ left: 180px; bottom: -190px; }
					50%		{ left: 360px; bottom: -210px; }
					60%		{ left: 600px; bottom: -220px; }
					80%		{ left: 640px; bottom: -190px; opacity: 0.6; }
					100%	{ left: 860px; bottom: -180px; opacity: 0; }
				}
				
				@-webkit-keyframes butter2 {
					0%		{ opacity: 0; }
					10%		{ left: 120px; bottom: -170px; opacity: 1; }
					40%		{ left: 180px; bottom: -190px; }
					50%		{ left: 360px; bottom: -210px; }
					60%		{ left: 600px; bottom: -220px; }
					80%		{ left: 640px; bottom: -190px; opacity: 0.6; }
					100%	{ left: 860px; bottom: -180px; opacity: 0; }
				}
				
				@-moz-keyframes butter3 {
					0%		{ opacity: 0; }
					10%		{ left: 780px; bottom: -190px; opacity: 1; }
					20%		{ left: 720px; bottom: -210px; }
					40%		{ left: 540px; bottom: -220px; }
					60%		{ left: 320px; bottom: -230px; }
					70%		{ left: 240px; bottom: -210px; opacity: 0.6; }
					100%	{ left: 100px; bottom: -160px; opacity: 0; }
				}
				
				@-webkit-keyframes butter3 {
					0%		{ opacity: 0; }
					10%		{ left: 780px; bottom: -190px; opacity: 1; }
					20%		{ left: 720px; bottom: -210px; }
					40%		{ left: 540px; bottom: -220px; }
					60%		{ left: 320px; bottom: -230px; }
					70%		{ left: 240px; bottom: -210px; opacity: 0.6; }
					100%	{ left: 100px; bottom: -160px; opacity: 0; }
				}
		 

这里我们使用Keyframes制作了三个动画效果,分别对应的是三只蝴蝶位置移动的动画,并且分别命名为“butter1”、“butter2”、“butter3”,不过大家要注意我和@点头猪的区别。我使用的是bottom负值,而@点头猪使用的是bottom正值,关键之处是我和他的最初定位的位置就是不一样,我使用这样定位是为了满足Firefox下的移动效果,而@点头猪则使用了最新的3D TransformsrotateX() rotateZ()属性,具体区别我现在也说不上,大家可以自己测试和体验一下,从实践中找出他们的区别之处。

有关于Keyframes创建动画的详细过程可以参考《CSS3 Animation》,或者点击《Animate.css》,Daniel Eden提供了多种效果的源码供大家参考学习。

3、调用动画

			.butter {
				-webkit-animation-iteration-count: infinite;/*设置动画播放次数*/
				-webkit-animation-timing-function: linear;/*设置动画变换频率*/
				
				-moz-animation-iteration-count: infinite;
				-moz-animation-timing-function: linear;
			}
			#butter1 { 
				-webkit-animation-name: butter1; /*调用动画名称*/
				-webkit-animation-duration: 30s; /*设置动画持续时长*/

				-moz-animation-name: butter1; 
				-moz-animation-duration: 30s; 

			}
			#butter2 { 
				-webkit-animation-name: butter2; 
				-webkit-animation-duration: 40s; 

				-moz-animation-name: butter2; 
				-moz-animation-duration: 40s;

			}
			#butter3 { 
				-webkit-animation-name: butter3; 
				-webkit-animation-duration: 50s; 

				-moz-animation-name: butter3; 
				-moz-animation-duration: 50s;
			}
		 

我们前面通过Keyframes创建了三只蝴蝶的飞行动画,那么现在我们需要调用这几个动画到对应的蝴蝶上面。才会有下面的动画效果:

在上面的代码中告诉我们,主要通过animation-iteration-count设置了动画的播放次数、animation-timing-function设置了动画的变换频率(大家还可以通过Cubic-Bezier在线工具制作更佳的动画变换频率)、animation-name调用动画的名称以及animation-duration设置动画的播放时长。这些参数是不可缺少的哟。

4、制作蝴蝶翅膀拍打动画

			@-webkit-keyframes x-spin {
				0%		{ -webkit-transform: rotateX(0deg); }
				20%		{ -webkit-transform: rotateX(80deg); }
				40%		{ -webkit-transform: rotateX(130deg); }
				50%		{ -webkit-transform: rotateX(180deg); }
				60%		{ -webkit-transform: rotateX(210deg); }
				80%		{ -webkit-transform: rotateX(270deg); }
				100%	{ -webkit-transform: rotateX(360deg); }
			}
			
			@-moz-keyframes x-spin {
				0%		{ -webkit-transform: scale(1,1); }
				20%		{ -webkit-transform: scale(1,-0.2); }
				40%		{ -webkit-transform: scale(1,1); }
				50%		{ -webkit-transform: scale(1,-0.2); }
				60%		{ -webkit-transform: scale(1,1); }
				80%		{ -webkit-transform: scale(1,0.2); }
				100%	{ -webkit-transform: scale(1,1); }
			}
		

这一步是关键所在,特别是在@点头猪制作的效果中。这里依旧使用Keyframes创建了一个叫“x-spin”的效果。@点头猪使用了3D TransformsrotateX() 制作了蝴蝶拍打翅膀的效果,这种效果在Apple SafariGoogle Chrome是特别的好,但在Mozilla Firefox却没有任何效果,原因我就不说了,因此我在此处使用了CSS3scale制作蝴蝶翅膀拍打效果,只是效果不是特别很好,我们可以一起来看一下这个scale制作的效果

HTML Markup

			<div class="butterfly"></div>
			<div class="butterfly2"></div>
		

CCC Code

		.butterfly2,	
		.butterfly {
			height:150px;
			width: 150px;
			top: 50px;
			left: 50px;
			position:absolute;
			background: transparent url(butterfly.png) 50% no-repeat;
			-webkit-animation: 0.5s ease 0s flitter infinite;
			-moz-animation: 0.5s ease 0s flitter infinite;
		}

		.butterfly2 {
			left: 200px;
			background: transparent url(butterfly2.png) 50% no-repeat;
			-webkit-animation: 0.5s ease 0s flitter2 infinite;
			-moz-animation: 0.5s ease 0s flitter2 infinite;
		}


		.exampleDiv:hover .butterfly {
			-webkit-animation-play-state:paused;
			-moz-animation-play-state:paused;
			animation-play-state:paused;	
		}

		@-webkit-keyframes flitter {
		0%{-webkit-transform: scale(1,1);}
		100% {-webkit-transform: scale(0.2,1);}
		}


		@-moz-keyframes flitter {
		0%{-moz-transform: scale(1,1);}
		100% {-moz-transform: scale(0.2,1);}
		}

		@-webkit-keyframes flitter2 {
		0%{-webkit-transform: scale(1,1);}
		100% {-webkit-transform: scale(1,0.2);}
		}


		@-moz-keyframes flitter2 {
		0%{-moz-transform: scale(1,1);}
		100% {-moz-transform: scale(1,0.2);}
		}
		

上面的代码就是制作了一个简单的蝴蝶拍打翅膀效果:

那么回到我们这个实例中,也是一样的,我在例子中也是使用了scale。这种制作方法大家感兴趣可以参考Estelle Weyl 写的《A masterclass in CSS animations》。

5、调用蝴蝶拍打翅膀动画

		.butterFly {
			-webkit-animation-name: x-spin;
			-webkit-animation-iteration-count: infinite;
			-webkit-animation-timing-function: ease-linear;
		}
		.butterFly1 {  -webkit-animation-duration: 0.4s; }
		.butterFly2 { -webkit-animation-duration: 0.4s; }
		.butterFly3 { -webkit-animation-duration: 0.32s; }
	

这样我们的效果就出来了:

那么到此为止,蝴蝶飞舞的效果就全部完成了。介绍的比较混乱,不知道大家有没有整清楚。如果还不是很清楚,感兴趣的朋友可以随时找我一起探讨,或者直接在评论中留言,我们尽快给大家回复。最后要非常感谢@点头猪的分享。大家可以直接参阅下面的DEMO。

如需转载烦请注明出处:W3CPLUS

Travis Scott x Jordan 1 Backwards Swoosh Mocha
返回顶部