下為純CSS制作,閒話不說,上個效果圖先:
玻璃瓶質感、四葉草漂浮於水面,蕩起漣漪、搖擺上升的氣泡…很美的意境,然而你也許會說你喜歡瓶子不喜歡四葉草,那可以把四葉草給none掉,不喜歡植物的話,那你喜不喜歡動物呢:
應該看得懂這只萌物是什麼生物吧..沒錯,水母 一只…眾生皆平等,不能只有植物沒有動物哈…
然而你也許不喜歡藍色的水,那我寫幾套多彩的玻璃瓶:
如果你感興趣的話,可以通過這個鏈接,下載我的源代碼:《四葉草、水母與玻璃瓶》
為方便下載,提供本人網盤帳號密碼,請不要弄亂裡面的頁面,以方便其它人下載,謝謝。
帳號:287019674@qq.com
密碼:123456
下面是對代碼的分析:
四葉草的代碼結構如下:
1 2 3 4 5 6 7 8 9
<div class="clover"> <div class="leaves"> <i class="leave angleN"></i> <i class="leave angleS"></i> <i class="leave angleW"></i> <i class="leave angleE"></i> </div> <i class="branch"></i> </div>
一個leaves掛著葉子,葉瓣用四個I標簽表示,一個branch代表葉莖
每 個葉瓣都是一個leave,然後用angle控制它們的旋轉,然而一個leave的話是畫不出一個心形的,所以我用多了一個leave:after畫另 外一半,兩個表現出來的形狀是一樣的,一個頭圓下方的形狀,圓可以用border-radius圓角來做,然後通過以左下角為原點,旋轉90度,來讓它們 錯開重疊成一個心形,如果你覺得抽象的話,可以參考下圖:
我把leave:after的顏色調深一些,就可以看出它們是怎麼一個重疊關系了…因為葉瓣與葉瓣之間存在之間隙,所以我旋轉的原點有稍作偏移,而且在心形的底部如果太尖感覺有點怪,所以也做了一個小圓角處理,到此葉瓣主體就繪制完成。
葉莖的話就是一個border做了一個大弧度圓角跟小弧度圓角的處理,如圖:
如果border處於圓角狀態,並且臨近的border不顯示,那麼該border會向不顯示的border拉一條錐形弧線, 這形狀恰巧符合葉莖的形狀,大弧度何以勾勒葉莖的基本形狀,小弧度可以用來收尾,這樣會比直角收尾柔和很多,到此四葉草制作完畢。
玻璃瓶的代碼結構如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
<div class="bottle"> <div class="bottle_top"> <div class="bottle_mouth"></div> <div class="highlight"></div> </div> <div class="bottle_neck"> <div class="highlight"></div> </div> <div class="bottle_main"> <div class="bottle_inner"></div> <div class="highlight"></div> </div> </div>
一 個bottle,分為瓶頂bottle_top、瓶頸bottle_neck、瓶身bottle_main三部分,每個都包含有一個掛高光的無意義的標 簽,而bottle_top裡面有一個瓶口bottle_mouth,bottle_main裡面有一個玻璃瓶內部bottle_inner。
bottle 作為最外的容器,其實並無多大意義,用來只是定位。bottle:after用來畫瓶子底部黑色的陰影,bottle:before用來畫瓶子底部由於水的顏色產生的彩色陰影,兩者分開,這樣如果裡面不裝水了,那麼只要隱藏bottle:before即可。下圖是一個空瓶子的效果:
其實瓶頂、瓶頸、瓶身三者的基本結構一致,所以這裡合並在一起,後面細節的時候再分開。
bottle_top我設定了寬高之後,取了它的左右邊框,然後對它的bottle_top:after、bottle_top:before進行操作,after做頂部向上的面,before做底部向下的面,然後border做邊框輪廓:
1 2 3
border:2px solid rgba(255,255,255,0.5); border-bottom:2px solid rgba(255,255,255,0.6); border-top:1px solid rgba(255,255,255,0.4);
一個總的border,然後底部,也就是向前的border-bottom我把透明度設置為0.6比正常的深,然後後面的我把它的寬度調成了1px,從而增強透視效果,因為同樣的物體,靠近眼睛的會比遠離眼睛的大些清晰些。瓶頸瓶身同理,做了同樣的設置,然而對於bottle_neck的偽類的 border-top我不是設置它的寬度為1px,而是直接border-top:none; 因為它被前面的玻璃實體擋住了,理應是存在的但顯得,但是該部位的交叉線條比較多,所以直接隱藏掉,讓線條清爽明朗些。最後將三個主體的元素通過定位,玻璃瓶框架基本就打好了。
因為瓶子是透明的,所以瓶口這個地方需要顯示出來,它串連著瓶頂跟瓶頸兩個部份,瓶口頂部需要重點刻畫,而瓶口底部剛好在瓶頸底部交匯,由於厚度折射什麼 的一大堆元素影響,看不是很清楚,所以我給次要化刪了。如果你看了我的代碼,會發現bottle_mouth我是沒有用box-shadow來做‘面’, 而是用背景色,這裡需要注意的是,投影形成的是一個圈的顏色,當然可以用偏移等方式讓他變成一個弧形,但是如果我僅僅需要左右方向的投影,上下為透明的 話,就不行了,如圖:
我現在需要的是拉一個水平方向自左向右的白色-透明-透明-白色的漸變,如果用box-shadow的話,在箭頭方向會產生一塊很明顯的白色-透明的區域,如果采用投影向上偏移的話,那麼下面就會出現同樣的不符合要求的區域,所以這個點上,應該采用背景色漸變比較合理。
bottle_inner沒有像bottle_top那樣一個圓柱形的設計,只是通過與瓶身bottle_main間隔一段距離產生厚度感,還有圓角:
1
-moz-border-radius:10px 10px 20px 20px/10px;
這樣做出來的圓角底部會扁些逼真些,而與前面制作最大的不同在於這裡:
邊框不是白色的,而是
1
border:1px solid rgba(0,0,0,0.01);
再配合投影
1
-moz-box-shadow:0px 0px 2px rgba(255,255,255,0.5) inset,0px 0px 8px rgba(255,255,255,0.6) inset,0px 0px 5px rgba(255,255,255,0.5);
因為最邊緣的玻璃切面跟視線成90度,透明度很高,而 弧度與視線大的區域,透明度會很低,所以白色會重一些,再慢慢過渡到透明。這個我是搜一些玻璃瓶資料 分析出來的,做出來的效果也比白色邊框再漸變要真實些,然而不單要對內投影,還要對外,因為玻璃身有一定厚度,不可能完全透明,所以寫了 5個像素的向外投影作為瓶身的渲染色…
這裡所說的投影,是對偽類進行box-shadow inset內投影,產生一個漸變面,讓圓柱體的‘面’效果突出出來,這裡我不用背景色而采用投影,是因為很難調整到符合透視的一個角度,而投影可以很輕松的做到,而且色彩融合得很好。比較特殊投影處理的有:
1> 瓶頂bottle_top的一個向下偏移的投影,如上面瓶口bottle_mouth圖片,具體代碼:
1
0px 3px 3px -1px rgba(255,255,255,0.3);
向下偏移3像素,羽化3像素,然後縮小1個比例,顏色為0.3的白色。這裡是作為瓶頂圓柱形面的小高亮處理。
1
2> 瓶頸bottle_neck:after,如圖:
具體代碼:
1
-moz-box-shadow:0px 5px 3px -2px rgba(0,0,0,0.05);
向下偏移5像素,羽化3像素,然後縮小2個比例,顏色為0.05的黑色。這裡是作為瓶頂向瓶頸投影處理,增強立體感。
3> 瓶身bottle_main:before,如圖:
具體代碼:
1
-moz-box-shadow:0px 0px 6px rgba(255,255,255,0.7) inset,0px 0px 3px rgba(0,0,0,0.15) inset;
不偏移,羽化6像素,顏色為0.7的白色內投影,不偏移,羽化3像素,顏色為0.15的黑色內投影。這裡是作為瓶底底色設置跟邊緣泛光,增強立體感。
掛上高光,立體感強烈了許多,如圖:
分別對瓶頂、瓶頸、瓶身做高光,一條淺點細點的,一條寬點由左到右由白到透明的漸變,瓶頸只有寬沒有細,瓶身細線由上至下做一個到80%的時候為透明的漸變…值得注意的是,高光需要貼著瓶壁,高度斜度保持一致,所以需要對高光進行一個斜切的變換:
1
-webkit-transform:skew(0deg,6deg);
要不然左側對應了,那麼右側高光必然會高出瓶壁幾個像素,到此,玻璃瓶制作完成。
因為水是裝在玻璃瓶裡面的,所以展現出來是一個圓柱形,結構跟瓶身bottle_main一致,區別主要表現在渲染顏色,投影方面。以藍色的水為例:
1 2 3 4 5
.water{ background:-moz-linear-gradient(-85deg,rgba(0,204,255,0.35),rgba(0,173,216,0.55) 70%,rgba(0,173,216,0.4)); -moz-border-radius:50px 50px 20px 20px/8px 8px 10px 10px; -moz-box-shadow:0px 0px 6px rgba(0,204,255,0.5) inset,0px 0.2px 3px -1px rgba(0,0,0,0.3) inset,0px 2px 6px -1px rgba(0,0,0,0.1) inset,0px 2px 5px rgba(0,204,255,0.3),0px 1px 3px rgba(0,204,255,0.2); }
水元素邊角需要做一個橢圓化處理,因為這次需要用到背景色打底,上圓潤一點圓角過渡自然下扁在兩角有一個小拐點,因為上面的是水平面透視的,而下面是玻璃底座,需要有一定的硬度,與上面產生區別;
背景色拉一個左上右下,斜度平緩傾向於垂直的漸變,顏色由深到淺;
投影所產生的效果跟瓶身的效果差不多,顏色在左右側深中間淺;
1 2 3 4 5 6 7
.water:after{ background:-moz-linear-gradient(left,rgba(255,255,255,0.4),rgba(0,204,255,0.05) 50%,rgba(0,204,255,0.1) 80%,rgba(255,255,255,0.3)); -moz-border-radius:50px/8px; border:1px solid rgba(255,255,255,0.2); border-bottom-color:rgba(255,255,255,0.4); -moz-box-shadow:0px 1px 2px -1px rgba(0,204,255,0.35); }
背景色拉一個由左到右 白-藍-藍-白的漸變,因為已經有水主體的藍色打底色,所以上水平面顏色不用太重,邊框用0.2白色,而在前面的border-bottom則用0.4白 色,遠模糊近清晰,讓立體感更強些…這裡值得注意的是投影,我寫了一個向下偏移1像素,羽化2像素,然後縮小1個比例,顏色為0.35的藍色投影,這 個是為了跟上面的水主體呼應寫的,我們知道,在中學上化學課目測試管中溶液體積的時候,視線要要跟溶液凹面相平,否則會產生誤差,可以看這張圖:
內徑比較小的儀器,當裡面裝有水時,因為水有表面張力,所以在小內徑儀器裡不會是平的,呈現周圍高中間低的凹形,而中間的凹形狀才是真正水的標准位置,周圍的只是因為表面張力往上高了。
所以我剛才做的那個投影,配合背景色的頭尾白色,就形成了這個凹面的效果,放大200%後,效果如下:
after做的是下面箭頭指向的稍微深色的投影區域,而上面箭頭指向的,其實就是水water本體所做的內投影,現在明白為什麼這次主體要做圓角伸到最上面了吧…
其實原理跟水平面一致,背景色拉一個由左到右 深藍-藍-藍-深藍的漸變,然後在用投影加深底部漸變顏色,需要注意的是,底部跟玻璃需要保持一定的間隙,以突出玻璃的厚度和玻璃凹面。
本來想畫條魚,不過魚如果游到邊緣要拐彎的話難度太高了,就換成一個比較容易實現的水母同志,如圖:
代碼結構為:
1 2 3 4 5 6
<div class="jellyfish"> <div class="jellyfish_head"></div> <div class="jellyfish_tail"> <div class="jellyfish_tail_in"></div> </div> </div>
一只水母jellyfish,分為頭部jellyfish_head、尾部jellyfish_tail,其實裡面那個jellyfish_tail_in沒多大意義,就為了加一條觸須…
水母頭部是一個橢圓形,頂部的又大又圓,底部需要一個拐角,不能太圓,感覺就像是一個‘倒著的缽’,具體圓角代碼:
1
-moz-border-radius:20px 20px 10px 10px/20px 20px 16px 16px;
而重點的代碼是內投影:
1
-moz-box-shadow:0px 0px 4px rgba(255,255,255,0.5) inset,1px 1px 2px rgba(255,255,255,0.2) inset,3px 3px 1px rgba(255,255,255,0.2) inset,-1px -1px 1px rgba(255,255,255,0.1) inset;
采用四次內投影產生立體感,具體怎麼產生的,我解釋下,第一個是最基本的打底 色,第二第四是做向右下偏移跟向左上偏移的陰影,增加深度,第三個向右下偏移 了三個像素做一個高光效果,再用jellyfish_head:after,畫了一個橢圓旋轉rotate(-15deg),調整透明度位置後作為最亮的 高光展現,這樣水母的頭部就制作完成。
尾部jellyfish_tail取 左右邊框,上下隱藏,然後做一個淡淡的內投影,調整位置,圓角的曲率,再通過 jellyfish_tail:after、jellyfish_tail:before制作多幾條觸須,調整好觸須間的間隔,這個根據個人愛好而定,因 為我制作後發現尾部稍微大了點,就用scale縮小了一些…
氣泡bubble的制作相對比較簡單,所以放在下面,次要處理,基本也就是border、box-shadow這些主要還是體現在動畫那裡。
我 們知道,圖層之間只有上下之分,沒有穿過的,四葉草下部分需要泡在水裡,而上部分需要浮出水面,我不可能把水切成兩段,所以我把四葉草分成了上下兩部分 cloverTop和cloverBottom,類似於一個模板操作,固定寬高後hidden掉不要的那部分,再拼接起來,從而實現漂浮,穿過水面的效 果,實現效果如下:
既然說穿過了,還要搖曳,那麼必然有漣漪,總共有兩個漣漪,用cloverBottom:after、cloverBottom:before實現,具體重點代碼如下:
1 2 3 4 5 6 7 8
.cloverBottom:after{ border:0.5px solid rgba(255,255,255,0.3); -moz-border-radius:19px/2px; border-top:none; border-right:none; border-bottom-color: rgba(255,255,255,0.2); -moz-box-shadow:0px 0px 3px -1px rgba(0,0,0,0.2) inset; }
設置好邊框樣式,但是由於太小了,四條都顯示的話畫面太復雜了,所以隱藏掉後面跟右邊的兩條,下面的調整邊框顏色,在設置一個0.2黑色的內投影,調整好 圓角的曲率,做出一個漣漪的大致效果,after做一個小漣漪,before做一個大漣漪,基本制作方式一致,這裡就不分析了。
如你剛打開我源代碼頁面所看到的,有一株四葉草在玻璃瓶裡面搖曳,蕩起一個個漣漪(如果你沒看到,說明你用的是IE..哈哈..)…
那麼,漣漪的節奏應該與四葉草搖曳的節奏一致,具體的代碼如下:
1 2 3 4 5 6 7
@-moz-keyframes cloverMove{ 0%{-moz-transform:translate(0px,0px);} 25%{-moz-transform:translate(-3px,1px);} 50%{-moz-transform:translate(0px,-1px);} 75%{-moz-transform:translate(4px,1px);} 100%{-moz-transform:translate(0px,0px);} }
四葉草從原位置,向左移動-3px向下移動1px,接著向右移動3px向上移動2px,接著向右移動4px向下移動2px,然後回歸原位置。這樣整體感覺就是浮浮沉沉,左搖右擺的樣子。
而我在給元素設定動畫的時候是這樣寫的:
1
-moz-animation: cloverMove 4s linear infinite alternate;
它動畫的名字叫cloverMove,動畫時間4秒,線性運動,不停止的,反向進行。
那就這樣而已嗎?不止的,這個是四葉草整體的搖曳,那葉莖也可以搖的,具體實現代碼:
1 2 3 4 5 6 7 8 9
.branch{-moz-animation:branchMove 4s linear infinite alternate; -moz-transform-origin:0% 0%;} @-moz-keyframes branchMove{ 0%{-moz-transform:rotate(0deg);} 25%{-moz-transform:rotate(3deg);} 50%{-moz-transform:rotate(-2deg);} 75%{-moz-transform:rotate(4deg);} 100%{-moz-transform:rotate(0deg);} }
通過以左上角為中心,配合整體旋轉,這樣看起來更動感…
單單是四葉草在搖,感覺怪怪的,因為氣泡不能死氣沉沉的,也要跟節奏才行,所以:
1 2 3 4 5 6 7
@-moz-keyframes bubbleMove{ 0%{-moz-transform:translate(0px,0px) skew(0deg,2deg);} 25%{-moz-transform:translate(-2px,0.5px) skew(0deg,5deg);} 50%{-moz-transform:translate(0px,-0.5px) skew(0deg,2deg);} 75%{-moz-transform:translate(2px,0.5px) skew(0deg,0deg);} 100%{-moz-transform:translate(0px,0px) skew(0deg,2deg);} }
在輕微移動的同時進行斜切操作,因為氣泡會“晃”…
那你會說這樣也只是實現了“搖曳的氣泡”,沒有上升啊,其實有的,我總共做了三個氣泡,第三個是在水底從下往上升的:
總共有三個氣泡,第三個氣泡的動畫代碼如下:
1 2 3 4 5 6 7 8 9
@-moz-keyframes bubbleRise{ 0%{-moz-transform:translate(0px,0px); opacity:0; border-color:rgba(255,255,255,0.1);} 10%{-moz-transform:translate(0px,0px); opacity:1;} 30%{-moz-transform:translate(-1px,-15px);} 50%{-moz-transform:translate(1px,-30px);} 75%{-moz-transform:translate(-1px,-50px) scale(1.2);} 98%{opacity:1; border-color:rgba(255,255,255,0.25);} 100%{-moz-transform:translate(0px,-67px) scale(1.4); opacity:0; border-color:rgba(255,255,255,0.1);} }
氣泡先從透明到完全不透明,10%出現的出現時間,然後搖晃著上升變大,到75%的時候面積為原來的1.2倍,邊框顏色會隨著變大而模糊,所以加深一點,到100%的時候面積為原來的1.4倍,完全不透明,即消失。
靜態的水母已經很萌了,然而會游泳的,超萌那 q( >3< )p…以下是水母游水的動畫代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
@-moz-keyframes jellyfishSwimming{ 0%{-moz-transform:translate(0px,0px) rotate(-4deg) scale(0.8);} 20%{-moz-transform:translate(-1px,-3px) rotate(-6deg) scale(0.8);} 50%{-moz-transform:translate(-2px,-1px) rotate(-3deg) scale(0.8);} 70%{-moz-transform:translate(-1px,-3px) rotate(-6deg) scale(0.8);} 100%{-moz-transform:translate(0px,0px) rotate(-4deg) scale(0.8);} } @-moz-keyframes jellyfish_headChange{ 0%{-moz-transform:scale(1);} 5%{-moz-transform:scale(1.1,0.95);} 20%{-moz-transform:scale(0.95,1.1);} 50%{-moz-transform:scale(1);} 55%{-moz-transform:scale(1.1,0.95);} 70%{-moz-transform:scale(0.95,1.1);} 100%{-moz-transform:scale(1);} } @-moz-keyframes jellyfish_tailChange{ 0%{-moz-transform:scale(0.8);} 5%{-moz-transform:scale(0.9,0.75);} 20%{-moz-transform:scale(0.7,1);} 50%{-moz-transform:scale(0.8);} 55%{-moz-transform:scale(0.9,0.75);} 70%{-moz-transform:scale(0.7,1);} 100%{-moz-transform:scale(0.8);} }
jellyfishSwimming為整體的游水,變換側移位置,同時水母是圓的,會搖晃;
jellyfish_headChange為水母頭部的變化,個人覺得水母是要吸一口水,然後吐出來,利用反作用力才游的,所以0-5的時候是吸水變寬變 扁,然後5-20吐水變瘦變長,20-50變為正常,然後50-55再吸水變寬變扁,55-70吐水變瘦變長,70-100變為正常。
jellyfish_tailChange同jellyfish_headChange,其實可以用同一個,只不過我覺得尾巴相對於頭部有點大了,就再縮小些,而且吐水的時候,尾巴可以吐得長些。
這裡針對水的顏色替換,其實已經沒有多大技巧了,只不過利用類名樣式權重,覆蓋原本的初始樣式,我制作了藍色(默認)、粉紅色pink、黃色yellow、綠色green,只要在bottle後面寫下你想要變更的顏色就可以了,如下:
1
<div class="bottle green">
本來這個應該寫在水元素上比較恰當,如下:
1
<div class="water green">
因為我們變更的是水的顏色,而不是瓶子的顏色,但是水顏色對整體瓶底投影有影響,而bottle:before之前沒有用到,我也不想加多個標簽,就套上了…
由於我做的時候是用firefox做的,兼容只寫moz,webkit是臨時批量修改的,在修改的時候發現,webkit居然不支持 border:0.5px 最小只能1px,修改了氣泡那些,可能有些地方沒修…
對於源代碼頁面,我隱藏了小水母,因為太多元素的話,頁面顯得很雜,如果你想看水母的話,就隱藏了四葉草再刪叼水母對於的display:none樣式,這樣效果會好一些…