超详细教程:纯CSS3写一个摇头晃脑的小哥

1.制做背景

1.1做为一个刚刚打算要入行的准前端,并无什么基础,暂时是按照网上的前辈们的指导,循序渐进地学习中。首先就要学习CSS3的使用。前期,作过几个比较简单的网站首页的仿制,如今想要试试动画效果的制做。若是有什么写得不对的地方,欢迎批评指正:我要进步!
1.2没有什么美术基础,不会设计,因此找到了一个挺有兴趣的案例,就想要拿来试试看。到如今为止,都没有看过原做的代码。没能彻底实现人家的效果,之后有机会再详细修改。也没能作到像素级还原,因此我作的小哥跟人家的长得不太同样……
来源(我作的是案例1): 连接描述
这是我在GitHub上的完整代码:连接描述
图片描述css

2.静态效果

2.1 背景部分
2.1.1 首先是图中那个圆背景,这个比较好实现。
图片描述
为了定位在屏幕中央,而且与顶部有必定距离,首先设置了以下样式:html

<body>
    <div class="container">
    </div>
</body>
body{
    margin:50px 0 0 0;
}
.container{
    margin-left:auto;
    margin-right: auto;
}

下面是具体内容:
html代码以下:前端

<div class="bg-circle">
    <div class="bg"></div>
</div>

css代码以下:html5

.bg{    
    height: 30px;
    width: 300px;
    background-color: #699;
}        
.bg-circle{    
    margin-left:auto;
    margin-right:auto;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    overflow: hidden;
}

通常说来,css部分能够是一个单独的文件,引入它的时候只须要在<head></head>里面写这样一句就能够:css3

<link rel="stylesheet" href="shakehead.css">

我是把这个html页和css页放在了同级目录中,因此路径href里面直接写文件名便可。在上面的代码中:git

margin-left:auto;margin-right:auto;能够确保水平方向的居中显示。
border-radius: 50%;能够把正方形变成一个正圆。
overflow: hidden;能够确保子元素不会超出这个元素所给出的区域。

另外,由于.bg-circle设置了overflow: hidden;因此.bg的宽高只要大于300px,就根本看不出来区别的(捂脸……)。github

2.1.2 左右各有一块影子,考虑到都不能超出那个圆形的边框,因此要做为.bg-circle的子标签才行:
html代码以下:浏览器

<div class="bg-circle">
    <div class="bg"></div>
    <div class="shadow-left"></div>
    <div class="shadow-right"></div>
</div>

css代码以下:socket

.shadow-left{
    position: absolute;
    z-index: 59;
    width: 240px;
    height: 100px;
    background-color: #476b6b;
    opacity: .8;
    transform: rotate(45deg);
}
.shadow-right{
    position: absolute;
    width: 320px;
    height: 100px;
    background-color: #e0ebeb;
    opacity: .7;
    transform: rotate(-35deg);
}

细心的话,应该已经发现,左侧那个影子,有点盖住了小伙儿的身子,还盖住了一个字母,因此它要比别的层要高。就必需要设置z-index属性,具体的值,能够根据你要叠压的层的数据来写,大它1点也是大,姐也是上面那个,嘿嘿!可是,想要设置z-index,就必需要设position:relative, absolute或者fixed均可以。
另外,若是只是简单的倾斜,transform: rotate(Xdeg);就能够作到了,可是有时候还要考虑这个倾斜掉的元素的定位,因此严谨一点的话,还能够设置transform-origin这个属性。这个的应用网上有挺多的,相信通常人均可以看懂。最主要就是记住:第一个值是水平(X),第二个值是竖直(Y);默认的中心是50%,50%,左上角是0,0,右下角是100%,100%。
可是由于这两个阴影是过了一下子才出来的,因此如今的代码写完,是看不到它们的。为了调试,能够暂时定位成最终位置:
图片描述工具

.shadow-left{
    left:-100px;bottom:-10px;
}
.shadow-right{
    right: -100px;bottom:10px;
};

或者右键-检查,在Elements区域,选中要看的标签,也能够显示它在哪里。
图片描述
2.2 人物头部
2.2.1 人物的头部,组成结构应该算是全图中最复杂的了。从目的上,我要作一个纯CSS3的网页,就想尽最不靠切图来完成;从效果上,几乎每个部分都要有动做,切一我的头出来也没有什么用,若是是切各个部分出来,说实话我不太会用PS,有那功夫还不如我用CSS写;另外,听说用CSS写的网页快一些,嘿嘿!
放眼望去,头部的全部部分,是的,全部部分,都是圆角不一样的矩形元素。因此咱们要作的就是调整好每一个元素的高宽、合适的圆角,作好各层的叠压关系,最后布局在合适的位置,就算完成了。
2.2.2 首先,在动画中,头部做为一个总体,有一个动做,因此必需有一个包裹在外面的层存在,这里就是.head这个标签。
html代码以下:

<div class="head"></div>

另外,在定位的时候,有一个包裹层,也有利于里面的眉毛眼睛鼻子等的定位,我以为仍是挺方便的。
css代码以下:

.head{
    position: absolute;
    top: 20px;
    left: 50%;
}

绝对定位有助于把这个头定位在我要的地方,也就是top,left能够在此基础上进行设置。
在作水平居中显示的时候,通常都是left:50%;margin-left:-a px;(a为要水平居中的元素的宽度的一半)组合出现的(或者全用right侧也能够)。可是由于我这里.head只是一个包裹层,并无设置宽高的必要,因此我只用了left: 50%;这一句。打开浏览器自带的检查工具,能够看到,.head在中轴线的右侧一点点,而且没有面积。
2.2.3 在图中,最显眼的就是那张大脸,也是最好写的部分:
图片描述
html代码以下:

<div class="head">
    <div class="face"></div>    
</div>

只须要让“脸”--.face做为.head的子元素而存在就能够了。
css代码以下:

.face{
    position: absolute;
    top:75px;
    left: 50%;
    margin-left: -60px;
    width: 120px;
    height: 170px;
    border-radius: 30px;
    background-color:  #fff7e5;
}

由于.face是头部的最底层,因此能够不设置z-index属性。
在给.face作居中定位的时候,就用到了这一对好朋友:

left: 50%;
margin-left: -60px;

其中,60px恰好是width: 120px;的一半。
为了作出这个小伙儿圆润的下巴,我设置了border-radius: 30px;实际上是四个角都圆了,反正上面那两个角也看不到,被头发盖住了(就像我有个朋友由于有刘海,因此不用认真画眉毛,搞得咱们露出额头天天花时间让眉毛对称的人内心很气同样)。可是,若是你强迫症比我重的话,能够只设置border-bottom-left-radius和border-bottom-right-radius的值,也是同样的。可是听说这样的话,你就写了两行代码,从代码优化的角度来说,后者并非最优的选择哦!
2.2.4 而后,我想到了要加上头发,我以为也是挺好写的,可是理想老是很丰满……毕竟,头发是一个拱门的形状,作出主体以后,还要露出额头来,并且头顶有一搓呆毛,额头中央要耷拉下来一小丛,并且严格意义上来说,还有耳朵前面的小鬓角个人天……在实际制做的时候,我选择把鬓角留给耳朵,毕竟它们位置关系比较近,这种时候就不要管它是否是头发了不是嘛,嘿嘿。
2.2.4.1 首先肯定html结构。
html代码以下:

<div class="head">
    <div class="face"></div>
    <div class="hair">
    <div class="forehead"></div>
    <div class="rub-up"></div>
    <div class="rub-down"></div>
    </div>
</div>

结合刚才的结构分析,我在头发这层标签里面,又设置了额头(.forehead)、呆毛(.rub-up)和刘海(.rub-down)(英语差很少忘没了,多数都是百度到的,若是用词有不对的地方,欢迎指正,谢谢你们!)。
2.2.4.2 先是头发的主体部分。
图片描述
css代码以下:

.hair{
    position: absolute;
    z-index: 9;
    top:160px;
    left: 50%;
    margin-left: -70px;
    width: 140px;
    background-color: #ffd11a;
}

头发要放在眉毛和眼睛的下层,因此z-index的值要比一下子写的眉眼的小就能够。可是考虑到,进行动画的时候,耳朵其实是从头发的后面冒出来的,因此要给它们留出余地,所以我在这里给.hair的z-index设置为9。
这里要提早说一下动画的问题:
在最终效果里面,头发的部分是从底部向上进行显示的,因此不能上来就给出高度和圆角,一并都写在动画效果的最终状态里面了,会在后面提到;宽度倒是没有变化的,因此在这里能够先写好。由于没有高度,因此咱们如今看不到头发。可是它没有高度,后面的呆毛和刘海就无法显示了,因此我先给.hair加上如下代码:

{
    height: 100px;
    top:60px;
    border-radius: 40px 40px 0 0;
}

2.2.4.3 而后是额头。
图片描述
css代码以下:

.forehead{
    position: absolute;
    bottom:0;
    left: 50%;
    margin-left: -55px;
    width: 110px;
    height: 65px;
    border-radius: 25px 25px 0 0;
    background-color: #fff7e5;
}

用一个跟脸的背景色相同的层盖在头发所示的层之上,并设置顶部的两个圆角,就造成了一个拱形的头发效果。这里面用到了简写的方法:跟margin和padding的简写用“上-右-下-左”的顺序不一样,border-radius是“左上-右上-右下-左下”(ps:多的我就不说了,网上都能找到,我只说我用到的是个什么就好了哈)。
2.2.4.4 头顶的呆毛和刘海。
图片描述
css代码以下:

.rub-up{
    position: absolute;
    top: -10px;
    left: 50%;
    margin-left: -40px;
    width: 80px;
    border-top-right-radius: 15px;
    background-color: #ffd11a;
}        
.rub-down{
    position: absolute;
    top: 25px;
    left: 50%;
    margin-left: -20px; 
    width: 40px;
    border-bottom-left-radius:20px;
    background-color:  #ffd11a;
}
.hair,.rub-up,.rub-down{
    background-color:  #ffd11a;    
}

头发上方的呆毛只须要右上角的圆角,因此只写border-top-right-radius: 15px;这一个就能够。须要注意的是,跟中文说话顺序不一样,这里要先说“上/下”,再说“左/右”。一样的,刘海只要左下的圆角,因而用到了border-bottom-left-radius:20px。
这两撮头发都是经过改变高度和定位来实现动画效果的,这里为了说明最终的结果,我把下面这些代码先加进来:

.rub-up{
    height: 30px;
    transform:rotate(0deg);
}
.rub-down{
    height: 30px;
}

最后,给三部分的头发用同一个颜色,因而看起来浑然一体,很是像那么回事儿啦!这里就用到了CSS多个类写在一块儿的写法:多个类名之间用一个“,”隔开就能够了(必定必定要用英文逗号哦!)。其实还能够给每个须要用到头发颜色的标签都写一个共同的类名,
好比这样:

<div class="hair hair-color">
    <div class="forehead"></div>
    <div class="rub-up hair-color"></div>
    <div class="rub-down hair-color"></div>
</div>

而后给这个类单独设置颜色:

.hair-color{
    background-color:  #ffd11a;    
}

这样的话,后面若是还要用这个背景色,只需添加这个类便可。我以为在代码优化的前提下,若是能保证使用方便而且尽可能地语义化,更有利于整个代码的编写和后期的修改和维护。
2.2.5 按照从上到下的顺序,接下来咱们要分别说一说眉毛、眼睛、耳朵和嘴。为何不提鼻子呢?我想你已经猜到了,后面我再说这个,嘿嘿!
2.2.5.1 首先肯定html结构。
html代码以下:

<div class="eyebrows">
    <div class="brow-left"></div>
    <div class="brow-right"></div>
</div>
<div class="eyes">
    <div class="eye-left"></div>
    <div class="eye-right"></div>
</div>
<div class="sockets">
    <div class="socket-left"></div>
    <div class="socket-right"></div>
</div>
<div class="earsandtemples">
    <div class="ear-left"></div>
    <div class="ear-right"></div>
    <div class="temple-left"></div>
    <div class="temple-right"></div>
</div>
<div class="mouth"></div>

上面这些div(.eyebrows、.eyes、.sockets、.earsandtemples及.mouth)都是.head的子元素,也就是.face还有.hair的同辈元素。前面说过,由于位置相近,我把耳朵和鬃角写在了一块儿。其实原本眼睛和黑眼圈我也是想要写在一块儿的,你猜我这什么拆开了?对,由于动画中,眼睛是一眨一眨的,并且是一块儿眨的。我当时的想法是,给眼睛所在的包裹层写那个动做,写上以后,好的,黑眼圈也眨了起来……不信邪的话,能够试试看,效果棒棒……可是如今写这个文章的时候我突然想到,若是我给每一只眼睛单独写动画,写一样的,也是能够的啊,我为何那么一根筋(捂脸……)我以为,这也说明,要想实现相同的效果,其实有不少种方法的,这也正是写代码的乐趣不是吗?
2.2.5.2 样式呢,咱们先从眉毛开始:就是两个矩形的div,右边的那个稍做倾斜就OK啦。
图片描述
css代码以下:

.eyebrows{
    position: absolute;
    z-index: 59;
    top:-50px;/*-----动画结束的最终效果是top:120px;*/
    left: 50%;
    margin-left: -45px;
    width: 90px;
}
.brow-left,.brow-right{
    width: 30px;
    height: 8px;
    background-color: #ffd11a;
}
.brow-left{
    float: left;
}
.brow-right{
    float:right;
    transform: rotate(10deg);
}

由于刚刚.hair的z-index: 9;其中就有额头这个部分,因此眉毛若是想显示出来,就至少要是9,少一点都不行,多一些不要紧。因此我这里设的59也是能够的。两条眉毛被包裹在一个.eyebrows里面,只要这个父元素被绝对定位好了,写清楚宽度,里面两个眉毛就一左一右进行浮动便可,我以为是很方便。不知道还有没有更好的方法了(一脸求知)。由于两条眉毛大小相同、颜色一致,因此样式写在了一块儿。
看起来在右边(应该是小伙儿本人的左边)的那条眉毛要倾斜一下,只须要transform: rotate(Xdeg);就好了,并且默认的旋转中心是该元素的正中心,恰好是我要的,我就没有特地去写transform-origin这个样式。
2.2.5.3 下面该说到眼睛和黑眼圈了(说它是眼眶也是能够……)。
图片描述
css代码以下:

.eyes{
    position: absolute;
    z-index: 69;
    bottom: -162px;
    left: 50%;
    margin-left: -35px;
    width: 70px;
}
.eye-left,.eye-right{
    width: 14px;
    border-radius: 7px;
    background-color:  #264c73;
    /*------动画结束的最终效果要加上:*/
        height: 22px;
}
.eye-left{
    float: left;
}
.eye-right{
    margin-left: 56px;
}        
.sockets{
    position: absolute;
    z-index: 59;
    top:155px;
    left: 50%;
    margin-left: -38px;
    width: 76px;
}
.socket-left{
    float: left;
}
.socket-right{
    float: right;
}
.socket-left,.socket-right{
    height: 10px;
    width: 20px;
    border-radius: 0 0 10px 10px;
    /*------动画结束的最终效果要加上:*/
        background-color: #cc6600;
        opacity: 0.1;
}

眼睛在眼眶之上,因此z-index这个属性上,眼眶(59)仍是要比头发(59)高(至少也要相等),可是眼睛(69)要比眼眶高。
看到这里,咱们已经屡次用到了border-radius这个属性。我感受它能够实现很是多种的形状,很神奇!好比这里的眼睛,看起来上下两头是半圆、中间是长方形,但实际上只要让border-radius的值等于宽度的一半就能够了。看到这儿,若是最开始的正圆没有弄懂怎么回事的朋友也能懂了吧?只要让被圆角的元素宽高一致就能够了!若是宽高不一致,就会像这里的眼睛一个效果啦~
因而,半圆形的眼眶也是很好写的吧?只设置底部两个的圆角border-radius: 0 0 10px 10px便可。
可是!我并无给眼眶设置初始颜色,因此如今这样是看不到它们的,为了展现效果,这里我先加上。由于在动画效果里,它们是淡出的,因此我直接写在了动画里面,否则的话,嗯,有兴趣的朋友能够本身试试看……
2.2.5.3 鬓角和耳朵的部分,前面提到过,要注意叠压关系。
图片描述
css代码以下:

.earsandtemples{
    position: absolute;
    z-index:1;    
    top:160px;
    left: 50%;
    margin-left:-70px;
    width: 140px;
}
.ear-left,.ear-right{    
    position: absolute;
    width: 10px;
    background-color: #fff7e5;
}
.ear-left{
    border-bottom-left-radius:10px; 
}
.ear-right{
    border-bottom-right-radius: 10px;
}
.temple-left,.temple-right{
    position: absolute;
    width: 5px;    
    /*------动画结束的最终效果要加上:*/
        height: 20px;
        bottom:-20px;
        opacity: 1;
}
.temple-left{
    left: 10px;
}
.temple-right{
    right: 10px;
}

而且把这两个鬓角类名也加在前面设置头发颜色的地方:

.hair,.rub-up,.rub-down,.temple-left,.temple-right{
    background-color:  #ffd11a;    
}

这里面有点意思的是,它们都是从大概太阳穴那个位置的头发里面冒出来的,因此先设一个position: absolute;就能够,具体的位置写在动画里面,经过改变top、bottom、left或者right,来让它们实现最终的效果。
2.2.5.3 嘴的写法和黑眼圈是同样的。
图片描述
css代码以下:

.mouth{
    position: absolute;
    top: 195px;
    left: 50%;
    margin-left: -25px;
    width: 50px;
    border-radius: 0 0 25px 25px;
    background-color: #fff;
    /*------动画结束的最终效果要加上:*/
        height: 20px;
}

我写盖在脸上的那层额头的时候,到耳朵的上方就结束了,因此在嘴这里,z-index能够不写了。
2.2.6 如今,头部就只差那个占了半张脸的阴影,以及跟它一块儿出现的鼻子了。我把它们写在了一块儿。是的,仍是由于位置相近,因此我把鼻子写在这里啦!朋友,你猜对了吗?
图片描述
html代码以下:

<div class="shadowandnose">
    <div class="shadow"></div>
    <div class="nose"></div>
</div>

这里面,.shadowandnose一样是.head的子元素。
css代码以下:

.shadowandnose{
    position: absolute;
    z-index: 79;
    top:75px;    
    left: 50%;
    margin-left: -60px;
    width: 120px;
}
.shadow{
    width: 60px;
    height: 170px;
    border-radius: 30px;
    /*------动画结束的最终效果要加上:*/
        opacity: .1;
        background-color: #555;
}
.nose{
    position: absolute;
    left: 50%;
    top:50%;
    margin-top:-5px;
    height: 30px;
    border-top-left-radius: 15px;
    background-color:  #fff7e5;
    /*------动画结束的最终效果要加上:*/
        width: 15px;
        margin-left: -15px;
}

.shadowandnose的z-index只要大于等于69便可,这里,我设置的是79。另外,由于.nose这个标签是写在.shadow以后的,默认就会在它的上层,能够不写z-index属性。反之,若是把这两个标签的先后顺序换一下,就必需要写了,有兴趣的朋友能够试一下。
另外呢,头顶的部分是要超出圆形边框的,因此整个头部所在的div,也就是.head,不能是被包裹在.bg-circle里的,且其z-index要高于.bg-circle。因此我把它们设为了同辈元素,而且由于前面.bg-circle的z-index:0,因而.head即便不设置z-index,也能够显示在其上方了。
到这里,小伙子的头部就基本完成了,其中有少许的代码须要写出动做以后才能有完整的体现,可是我也全都先写出来啦!
2.3 人物身子
2.3.1 相比上面说到的头部,人物身子的部分比较简单些。先来讲说那件黑T-shirt。
图片描述
html代码以下:

<div class="bg-circle">
    <div class="bg"></div>
    <div class="shirt"></div>    
    <div class="shadow-left"></div>
    <div class="shadow-right"></div>
</div>

由于它跟那两片阴影有些叠压的关系,因此我把它也做为了.bg-circle的子元素来写。
css代码以下:

.shirt{    
    position: absolute;
    z-index: 39;
    bottom: -10px; 
    left: 50%;  
    margin-left: -90px;
    width: 180px;
    background-color: black;
}

在这里,我要让黑T-shirt在浅阴影之上,在深阴影之下。在写浅阴影的时候,我没有给z-index的值,因此黑T-shirt只要z-index大于0便可;深阴影我当时写的z-index: 59,因此黑T-shirt小于59就好了。可是要考虑到黑T-shirt上面还有几个字,不能把z-index设过高,因此这里我设的z-index: 39。
2.3.2 这几个T-shirt上面的字母,由于动画中是一个一个出现的,因此我把它们每个单独写出来。
图片描述
html代码以下:

<div class="bg-circle">
    <div class="bg"></div>
    <div class="shirt"></div>            
    <div class="logo">
        <div class="i">I</div>
        <div class="love">♥</div>
        <div class="c">C</div>
        <div class="s1">S</div>
        <div class="s2">S</div>
    </div>
    <div class="shadow-left"></div>
    <div class="shadow-right"></div>
</div>

到此,.bg-circle的结构就完整了!
css代码以下:

.logo{
    display: flex;
    justify-content: space-around;
    position: absolute;
    z-index: 49;
    left:50%;
    bottom:-35px;
    margin-left:-60px; 
    width: 120px;
    height: 105px;
    color: #fff;
    font-size: 22px;
    font-weight: bold;
}
.love{
    color:red;
}
.i,.love,.c,.s1,.s2{
    margin-top:100px;
    /*------动画结束的最终效果要加上:*/
        margin-top:25px;
}

为了更方便地让这几个字母保持等间距,我用了display: flex;属性,并设置justify-content: space-around;属性,使每一个元素两侧的间隔相等,而且在两端都留有空间。其实若是我修改一下,把justify-content设为space-between,效果也是差很少的。
那个当心心是我从案例的网页里复制过来的,我不知道怎么输入它(/ω\)。
这几个字母在黑T-shirt的上面,又要能被深色的阴影盖住,因此这里我设的z-index: 49。
2.4 那两个晃动的音符就更好写了。若是不考虑动画效果,只要让它们出现、而且位于整个中央的部分之上,就能够了。
图片描述
html代码以下:

<div class="notes">
    <div class="note2"><img src="note2.png"></div>
    <div class="note1"><img src="note1.png"></div>
</div>

和头部.head一个道理,要想显示在圆形区域.bg-circle之上,就要跟它是同辈元素,而且由于.bg-circle{z-index:0;}的设置,这里能够不写.notes的z-index。
css代码以下:

.notes{
    position: absolute;
    left: 50%;
    margin-left:-170px;
    width: 340px;
}
.note2{
    float: left;
    margin-left: 30px;
    opacity: 0;
}
.note1{
    float: right;
    margin-right: 30px;
    opacity: 0;
}

别的应该都不用我说,可是可能有人会问,上来就设成opacity: 0要干什么?说实话,我本身写完这个也小半个月了,我都懵了(◎_◎;)。我回去试了一下,发现原来是这么回事儿:由于这两个音符的动画是有延迟值的,不是上来就开始晃悠的,要等脸上的动做作完,因而它们在stand by的时候,就要隐身才行,等到要它们出场了,再在动画效果里给它们显示出来。
为了说明问题,我随便取了它们运动中的一个值加上去,能看出来它们在哪就行。代码以下:

.note1,.note2{
    transform: rotate(0deg);
    opacity: .7;
    margin-top:-150px;
}

2.5 到这里,并无完。不知道你还记不记得,有四个黄色的环依次出现,只出场那么一次?
图片描述
html代码以下:

<div class="rounds">
    <div class="round1"></div>
    <div class="round2"></div>
    <div class="round3"></div>
    <div class="round4"></div>
</div>

.rounds也是.bg-circle它们的同辈元素,这样,才能不被.bg-circle的over-flow:hidden影响,且位于头发、音符之下。
css代码以下:

.round1,.round2,.round3,.round4{
    position: absolute;
    top:76px;
    left: 50%;
    margin-left: -124px;
    border-radius: 50%;
    background-color: transparent;
}

若是只按上面这样写,它们是隐形的。我仍是取它们动画中的一个过程值让一个圈出来现身说法一下:

.round1{
    border:1px solid #ffd11a;
    width: 240px;
    height: 240px;
    transform: scale(1.2);
}

可能只是我的习惯吧,我写了一个包裹层.rounds,可是实际上并无给它设置样式。我试着把它删掉,于结果上毫无影响。如今看来,只有在我想把各部份内容折叠起来的时候,包裹层确实是有用的。我如今理解得也很少,之后有新想法了再来补充修改吧。
还有一点是挺有意思的。若是把如今的样式写在.rounds里,而不是分别给这几个.roundX定义,会产生很是神奇的效果,我以为这些尝试也有助于新手理解css效果的实现,有兴趣的朋友不妨动手试一试。
代码是看不会的,只能是动手敲会的。我以为,作别的事也是同样。(职业病,可能晚期了,大概是治很差了吧……)

3.实现动画

3.1 参照案例,记录每个部位的动画效果和出现顺序
我当时用了一个比较笨的方法,用一个小本儿,一遍一遍地刷新页面,看最早出来的是哪一个动做,而后是啥,每一个动做是什么效果,有没有同时出现的别的动做。可是毕竟是靠估计出来的时间差还有各类角度,因此没能高度还原,就整个差很少意思,就成了。否则我可能要用出更土的招儿,好比弄个计时器什么的(/ω\)。
下面是我记录的时间轴,或者说进程图?
开始
-->[蓝背景大圆(出现-变大-正常,0.8s)+黑T(出现-变大-正常,1s)]+脸(变大-正常,0.5s,迟1s)
-->[头发主体(由下向上,0.8s,迟1.5s)+鬓角(0.4s,迟2.3s)]
-->顶毛(0.6s,迟2.3s)
-->耳朵(0.4s,迟2.9s)
-->刘海(0.4s,迟3.3s)
-->{[眼睛出现(0.5s,迟3.7s)]+眼窝(0.3s,迟3.7s)+[眉毛出现(0.4s,迟3.7s),右边眉毛(3s,迟2.5s)]}
-->嘴(0.5s,迟4.2s)
-->字母(1s,迟4s+)
-->[两侧阴影(5.7s,延迟写在动画里了)+四个圈(1s+,迟5s+)+脸的侧影(0.5s,迟4.7s)+鼻子(0.5s,迟4.7s)+摇头(1s,迟5.2s)+眨眼(5s,迟5.2s)]
-->音符(2s,迟5s+)。
其实这个部分是最耗时的,我感受。当时记录就很费劲,如今写起来又是一笔烂帐……可是写下来或者记下来,造成相似计划书或者时间轴的东西,老是比看一点儿作一点儿要好些的。
3.2 制做动画
3.2.1 基本操做:
作好规划以后,写动画效果实际上是最简单的啦!首先,咱们以那个圆背景为例:

.bg-circle{    
    /*这部分代码前面写过了,此处略过*/
    animation: bigger .8s forwards linear;
}
@keyframes bigger{
    0%{height: 200px;width: 200px;margin-top: 40px;}
    75%{transform: scale(1.0,1.0);}
    100%{transform: scale(0.8,0.8);margin-top: 0;}
}

在要写入动画效果的元素的样式里面,加入一句animation:...;就能够了(我这里用到的是简写的方法,也能够每一个动画效果单独写出来,这个在网上能够找到不少,我不系统地列举了)。
其中:
第一个属性(bigger)是我要调用的动画的名字,即animation-name;
第二个属性(.8s,或者写成0.8s)是完成这个动画所需的时间,若是是要屡次播放的,这个时间就是每个周期的时间,即animation-duration;
第三个属性(forwards)是说完成这个动画以后,该元素以什么样式存在,即animation-fill-mode。forwards是设置动画完成时,保持住最终这个姿态,别动。这个属性还有不少值,我还没用过别的,不敢多说;
第四个属性(linear)是设定这个动做的速度曲线,即animation-timing-function,是挺好用的一个属性。我这里设的linear是从头至尾一个速度。后面我还用过ease,慢-快-慢的效果,很天然。这个属性也有不少值,多试试,之后更好上手。
由于我本身用的是Chrome浏览器,暂时就没有进行浏览器兼容的练习(之后若是遇到了,我再单独写)。因此直接用@keyframes bigger{...}来定义动画就能够了。
在@keyframes youranimation{...}里面,听说最好是必定要设置from/0%和to/100%,这两种写法我是没什么研究,哪一种写法我测试的时候都没什么问题。其余的过程值,能够随便设置,不用拘泥于50%、75%之类的,我设过88%来调试,也行的。可是若是没有太大的必要,效果要是差得很少,也不用非得难为本身去用animation-duration乘以88%来计算每一个动做的时间吧。
3.2.2 简化代码:
3.2.2.1 有的时候,一个元素要设定两个动做,好比眼睛:开场的时候,要变大再回到正常大小,而后等脸上的东西全出现了,随着摇头的动做,眼睛还要眨起来。并且,咱们还须要让这个动做等一下子再开始,也就是常说的延迟。这时候,动做效果能够这样写:

.eye-left,.eye-right{
    /*这部分代码前面写过了,此处略过*/
    animation:openeyes 0.5s 3.7s forwards,wink 5s 5.2s infinite;
}
@keyframes openeyes{
    0%{}
    75%{height: 33px;width: 21px;opacity: 0.4;border-radius: 0;}
    100%{height: 22px;}
}
@keyframes wink{
    0%,90%{height:22px;}
    95%{height: 0;}
    100%{height:22px;}
}

对于同一个元素,要设置两个动做的时候,必定要写在同一个animation里面,用“,”隔开。若是写了两个animation:...;后面一个会覆盖前面的,就至关因而只写了一条。
另外,每一组简写的animation:...;里面,都有两个时间值,不用担忧,浏览器本身懂的,第一个是动画的周期长短,第二个是延迟时间,即animation-delay。一开始,我担忧会不会形成什么误会,还坚持分开写来着。后来发现网上有例子,就是简写的方式,我就把个人代码都改为这样了。毕竟,看在代码优化的份上,能省一行是一行!
3.2.2.2 在@keyframes youranimation{...}里面,也能够用简写的方式。若是这个动做里面,有几个时间点是同一个效果,就能够写在一块儿,好比上面这段,写wink这个眨眼的动做时,我直接把0%,90%写成了同一个效果,至关于用整个动画过程的90%的时间,来看成延迟来完成。
再好比我在写呆毛的动画的时候:

@keyframes upper{
    0%,90%,100%{transform-origin: 80% 100%;}
    0%{height: 0;top:5px;transform:rotate(-5deg);}
    90%{height: 30px;transform:rotate(10deg);}
    100%{height: 30px;transform:rotate(0deg);}
}

在个人代码里,这个用法是比较常见的。
3.2.2.3 还有一种状况,当多个元素同时调用一个预设动画的时候,咱们只须要做一些微调,就可让这多个元素产生不同的效果。好比那四个由中心向外扩张的环,还记得吗?

.round2{
    animation:rd2 .8s 5.6s forwards;
}
.round3{
    animation:rd2 .8s 5.7s forwards;
}
.round4{
    animation:rd2 .8s 5.8s forwards;
}
@keyframes rd2{
    0%{border:2px solid #ffd11a;width: 240px;height: 240px;}
    90%{border:1px solid #ffd11a;width: 240px;height: 240px;transform: scale(1.3);}
    100%{opacity:0;}
}

我这里改得还比较少,只是让每个环的延迟不同,就作到了如今的效果。有机会我还会试试其余的变化,这东西挺有意思!

4.结语

当初打算要照着人家的案例作练习的时候呢,我内心是拒绝的……毕竟我历来没有让css动起来的经验。可是想到当初第一次接触flex的时候也是这么想的。虽然不能说本身如今有多么精通,可是我通过几回的使用,至少知道flex能干什么、若是不会了要去哪里找答案。这个过程我以为是很重要的。因此这一次,我也给本身加油,告诉本身能作获得!制作的过程当中呢,遇到不少问题,尤为是定位的问题。我以前没经历过这么复杂的定位关系,其实从这一点也能看出来我基础有多渣……可是我老是问本身:别人能行,由于啥?是由于他是天才?仍是由于他作个梦就能会?若是都不是,那人家也是一点点儿学的,我也能够。我可能慢一些,也可能没人家一点就通,但我老是能学会的,总比看到了困难就止步不前要好。因此,每次遇到不明白的地方,就上网查教程,看有没有人提问,看别人的回答。实在看不懂,就慢点儿看;再看不懂,就把人家代码全写上去,一句一句的删掉,看是哪句话起了做用,有没有几句话是要一块儿发挥做用的。在这个过程当中,我发现借助浏览器自带的检查工具,是很是有效的。当时全写完了以后,我缓了好一阵儿,以为本身至关有才了!像是翻过一座大山似的!缓了没多久,次日吧,就开始学Jquery了,看了一本书,写了一个大转盘的案例。而后才想起来,这些东西不能写完就算了,得作总结啊,否则之后确定就忘没了!这也就一两个星期的事儿吧,我今天再回头来写这篇文章的时候,我有这么几个想法:我当时怎么想的?这东西哪里难了,有什么?这些代码的顺序为何这么奇怪?我感受,这说明我确实是在进步的,也说明不做记录的话,真的会慢慢忘掉原觉得不会忘的东西。忘了怎么发现的了,是说css代码应该按照必定的顺序书写,位置、大小、文字、背景及其余。我写这篇文章的时候,才发现当时我真是,想起什么写什么啊,并无所谓顺序可言。并且,还有不少冗余的代码,并无做用,多是某次不成功的调试留下的痕迹。在此次整理中,我一并都进行了修改。以前是看到别的技术大牛写本身的经验之谈的时候,写到说要抽时间作这样的总结。为名,能够提升本身的关注度;为己,也是进一步内化所学知识的过程。必需要能沉下心来,积淀本身的思想。内视,也是一种修行。我在这样的启发下,咬着牙、强迫本身也这样作一次。说实话,一想到要开始写这篇文章,我头都疼。为了逃避,我甚至开始给本身找别的事作,让本身好像没时间同样。可是后来我仍是正视本身,不要跑,跑得过初一又跑不过十五。想一想也是,骗本身干什么呢?当我真正开始作这件事的时候,又时时刻刻体会到其重要性,以及它带给个人好处。最直接、也最残忍的一面,就是把本身以前的不足和缺陷,一五一十地摔在眼前:这就是你觉得的你很好,这就是所谓的你作完了?!可是值得庆幸的是,我是第一个看到这些不足的人,不是很好吗?总好过沾沾本身喜地把成果给别人看,而后被批评得一无可取强。

相关文章
相关标签/搜索