超詳細教程:純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代碼應該按照必定的順序書寫,位置、大小、文字、背景及其餘。我寫這篇文章的時候,才發現當時我真是,想起什麼寫什麼啊,並無所謂順序可言。並且,還有不少冗餘的代碼,並無做用,多是某次不成功的調試留下的痕跡。在此次整理中,我一併都進行了修改。以前是看到別的技術大牛寫本身的經驗之談的時候,寫到說要抽時間作這樣的總結。爲名,能夠提升本身的關注度;爲己,也是進一步內化所學知識的過程。必需要能沉下心來,積澱本身的思想。內視,也是一種修行。我在這樣的啓發下,咬着牙、強迫本身也這樣作一次。說實話,一想到要開始寫這篇文章,我頭都疼。爲了逃避,我甚至開始給本身找別的事作,讓本身好像沒時間同樣。可是後來我仍是正視本身,不要跑,跑得過初一又跑不過十五。想一想也是,騙本身幹什麼呢?當我真正開始作這件事的時候,又時時刻刻體會到其重要性,以及它帶給個人好處。最直接、也最殘忍的一面,就是把本身以前的不足和缺陷,一五一十地摔在眼前:這就是你覺得的你很好,這就是所謂的你作完了?!可是值得慶幸的是,我是第一個看到這些不足的人,不是很好嗎?總好過沾沾本身喜地把成果給別人看,而後被批評得一無可取強。

相關文章
相關標籤/搜索