純css實(shí)現(xiàn)窗戶玻璃雨滴逼真效果
這里僅是用CSS技術(shù)來(lái)演示這樣的一個(gè)場(chǎng)景,可能并不太實(shí)用。然而這是一個(gè)探索CSS新功能的最佳機(jī)會(huì)??梢宰屇銍L試使用一些新特性和新工具。并且逐漸將在工作中實(shí)踐。在制作窗口雨滴效果,將使用到HAML和Sass。
案例效果

看到上面的效果是不是有點(diǎn)像人站室內(nèi)看窗外雨中的夜景,窗戶上雨滴的效果是那么的真實(shí),窗外的夜景卻又是那么的模糊。咱們不在詩(shī)意化了,我想大家更為關(guān)注的是用什么樣的技術(shù)來(lái)實(shí)現(xiàn)這樣的一個(gè)效果。
預(yù)處理器
在這個(gè)示例中,使用了HAML和Sass來(lái)替代我們熟悉的HTML和CSS。主要是為了制作雨滴需要上百個(gè)<div>元素,另外需要對(duì)上百個(gè)<div>寫樣式,畢竟每個(gè)雨滴都長(zhǎng)得不一致嘛。使用預(yù)處理器除了可以幫助我們減少工作量之外,還可以使用預(yù)處理器中的循環(huán)、變量等。最主要的是可以使用隨機(jī)函數(shù)產(chǎn)生的隨機(jī)值,讓我們不需要單獨(dú)處理上百個(gè)雨滴。
有關(guān)于HAML和Sass的語(yǔ)法可以各自到其官網(wǎng)上查閱。如果你自己本地電腦不具備這樣的開發(fā)環(huán)境,可以直接在Codepen創(chuàng)建DEMO,并且選擇對(duì)應(yīng)的預(yù)處理器。在HTML和CSS的配置中選擇對(duì)應(yīng)的預(yù)處理器。比如在HTML設(shè)置中選擇HAML,在CSS設(shè)置中選擇SCSS。
有關(guān)于Sass更多的中文教程,可以點(diǎn)擊這里閱讀。
結(jié)構(gòu)
制作窗戶雨滴的效果,其結(jié)構(gòu)并不太復(fù)雜。主要分兩個(gè)層次,其中是窗戶,而另個(gè)是雨滴。在案例中使用.window來(lái)表示窗戶,在.raindrops容器中放置了上面?zhèn)€雨滴.雨滴是通過(guò).border和.drops來(lái)制作。并且將窗戶.window和雨滴.raindrops都放置在容器.
container中:
.container .window .raindrops .borders - (1..120).each do .border .drops - (1..120).each do .raindrop
編譯出來(lái)的結(jié)構(gòu):
<div class="container"> <div class="window"></div> <div class="raindrops"> <div class="borders"> <div class="border"></div> <!-- 此處省略 118個(gè)border --> <div class="border"></div> </div> <div class="drops"> <div class="raindrop"></div> <!-- 此處省略 118個(gè)raindrop --> <div class="raindrop"></div> </div> </div> </div>
樣式
樣式分為三個(gè)層次:
模糊的窗外夜景(理解成窗戶的效果也可以)
雨滴效果
雨滴下滑動(dòng)畫效果
接下來(lái)簡(jiǎn)單了解這些效果是怎么實(shí)現(xiàn)的,又使用了哪些CSS新特性。
設(shè)置變量
整個(gè)效果都是使用Sass來(lái)編寫,如果你從未了解或接觸過(guò)Sass,建議您先對(duì)其做一個(gè)簡(jiǎn)單的了解。這樣更有助于你快速理解案例效果制作。
窗外的夜景找了一張華燈初上的圖片,而且讓窗戶占據(jù)全屏,在這里首先聲明三個(gè)變量:
$image: "http://www.w3cplus.com/sites/default/files/blogs/2015/1506/huadenchushang.jpg"; $width:100vw; $height:100vh;
初此之外,需要設(shè)置雨滴變量:
$raindrops:120;
特別需要注意,雨滴的變量值最好和HTML中的雨滴結(jié)構(gòu)相匹配。
讓窗戶占據(jù)全屏
首先要做的是讓窗戶占據(jù)全屏。其實(shí)就是讓.window全屏顯示。至于如何實(shí)現(xiàn)全屏效果,這也不是什么難的事情。我想懂點(diǎn)CSS的同學(xué),分分鐘就能搞定。不過(guò)這里采用的是CSS3的新方法,采用viewport單位來(lái)實(shí)現(xiàn)全屏效果:
.container{
position:relative;
width:$width;
height:$height;
overflow:hidden;
}
.window{
position:absolute;
width:$width;
height:$height;
background:url($image);
background-size:cover;
background-position:50%;
}
使用了兩個(gè)關(guān)鍵知識(shí)點(diǎn):
使用viewport單位vw和vh,讓容器.container和.window和視窗窗口一樣大。(有關(guān)于Viewport單位相關(guān)介紹,這里有做詳細(xì)介紹)
使用CSS3的background-size屬性,讓背景圖片滿屏顯示。
模糊效果(毛玻璃)
我們要的效果不僅僅是背景圖全屏這么簡(jiǎn)單,看上去圖片是模糊的效果。或許有同學(xué)會(huì)說(shuō),使用制作軟件整一張模糊的背影圖片,也就分分鐘的事情。如果你還是使用這樣的方法來(lái)處理,說(shuō)明你已經(jīng)Out了。
CSS3中有一個(gè)filter屬性,將其設(shè)置blur(),效果就出來(lái)了。
.window{
...
filter:blur(10px);
}

現(xiàn)實(shí)生活中的雨露
在我們繼續(xù)討論之前,讓我們看看現(xiàn)實(shí)生活中雨滴在窗戶上的效果:

圖片來(lái)自:Wikipedia
由于折射,雨滴翻轉(zhuǎn)圖像。另外,雨滴形狀或多或少有些類似半球體,而且綜們看起來(lái)有黑色邊框。
雨滴
基于我們看到的雨滴效果,讓我們來(lái)嘗試制作一個(gè)單獨(dú)的雨滴效果。
HAML
.container .window .raindrop
SCSS
$drop-width:15px;
$drop-stretch:1.1;
$drop-height:$drop-width*$drop-stretch;
.raindrop{
position:absolute;
top:$height/2;
left:$width/2;
width:$drop-width;
height:$drop-height;
border-radius:100%;
background-image:url($image);
background-size:$width*0.05 $height*0.05;
transform:rotate(180deg);
}
這是很簡(jiǎn)單的,我做就是使用div.raindrop畫了一個(gè)橢圓。并且用了當(dāng)初的背景圖進(jìn)行了填補(bǔ),并做了一個(gè)倒轉(zhuǎn)的效果。

現(xiàn)在,我們要添加一個(gè)小邊框,讓雨滴看起來(lái)更像雨點(diǎn)(看起來(lái)有立體效果)。
HAML
.container .window .border .raindrop
SCSS
.border{
position:absolute;
top:$height/2;
left:$width/2;
margin-left:2px;
margin-top:1px;
width:$drop-width - 4;
height:$drop-height;
border-radius:100%;
box-shadow:0 0 0 2px rgba(0,0,0,0.6);
}

請(qǐng)注意,我們不只是添加了一個(gè)邊框,我們還對(duì)邊框進(jìn)行了擠壓,所以看起來(lái)雨滴更自然一些。
雨滴看上去OK了,這個(gè)時(shí)候我們可以添加數(shù)以百計(jì)的雨滴:
HAML
.container .window .raindrops .borders - (1..120).each do .border .drops - (1..120).each do .raindrop
我們做了120個(gè)雨滴。
接下來(lái)使用Sass的循環(huán)給每個(gè)雨滴寫樣式:
@for $i from 1 through $raindrops{
$x:random();
$y:random();
$drop-width:5px+random(11);
$drop-stretch:0.7+(random()*0.5);
$drop-height:$drop-width*$drop-stretch;
.raindrop:nth-child(#{$i}){
left:$x * $width;
top:$y * $height;
width:$drop-width;
height:$drop-height;
background-position:percentage($x) percentage($y);
}
.border:nth-child(#{$i}){
left:$x * $width;
top:$y * $height;
width:$drop-width - 4;
height:$drop-height;
}
}
這里采用了Sass的@for循環(huán)對(duì)每個(gè)雨滴做樣式處理,并且使用隨機(jī)函數(shù)random()產(chǎn)生隨機(jī)值,讓每個(gè)雨滴的大小,擠壓都不一致。同時(shí)還使用percentage()函數(shù),讓雨滴的背景圖采用不同的位置。

上面看到的效果都是靜態(tài)的,為了讓它更具下雨的效果。雨滴滴下的效果,可以使用CSS3的animation來(lái)制作動(dòng)畫效果。
@keyframes falling {
from {
}
to {
transform: translateY(500px);
}
}
定義好falling動(dòng)畫之后,只需要在雨滴上調(diào)用:
@for $i from 1 through $raindrops{
$x:random();
$y:random();
$drop-width:5px+random(11);
$drop-stretch:0.7+(random()*0.5);
$drop-delay: (random()*2.5) + 1;
$drop-height:$drop-width*$drop-stretch;
.raindrop:nth-child(#{$i}){
left:$x * $width;
top:$y * $height;
width:$drop-width;
height:$drop-height;
background-position:percentage($x) percentage($y);
animation: #{$drop-delay}s falling 0.3s ease-in infinite;
}
.border:nth-child(#{$i}){
left:$x * $width;
top:$y * $height;
width:$drop-width - 4;
height:$drop-height;
animation: #{$drop-delay}s falling 0.3s ease-in infinite;
}
}
到了這一步,你也就能看到文章開頭顯示的雨滴窗戶的效果了。是不是感覺(jué)很爽呀。
總結(jié)
文章一步一步演示了如何使用CSS新特性制作一個(gè)華燈初上,雨滴窗戶的效果。整個(gè)實(shí)現(xiàn)過(guò)程采用了預(yù)處理器來(lái)編寫代碼。從整個(gè)過(guò)程中你可以很明顯的感知,如果沒(méi)有HAML和Sass這樣的預(yù)處理器,你要為數(shù)以百計(jì)的雨滴寫樣式效果,那絕對(duì)是一件非??啾频氖虑?。而使用之后,采用他們的功能特性,配合CSS3的一些新特性就能很輕松的完成。
瀏覽這個(gè)效果建議您使用Chrome瀏覽器瀏覽,因?yàn)檫@里使用了CSS3一些新特性,大家應(yīng)該都懂的。千萬(wàn)別問(wèn)我IE6瀏覽器怎么破,我也破不了。
純css實(shí)現(xiàn)窗戶玻璃雨滴逼真效果,內(nèi)容到此為止,希望大家喜歡。
相關(guān)文章
JavaScript函數(shù)this指向問(wèn)題詳解
這篇文章主要為大家介紹了JavaScript函數(shù)this指向,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2021-11-11
JS實(shí)現(xiàn)完全語(yǔ)義化的網(wǎng)頁(yè)選項(xiàng)卡效果代碼
這篇文章主要介紹了JS實(shí)現(xiàn)完全語(yǔ)義化的網(wǎng)頁(yè)選項(xiàng)卡效果代碼,可實(shí)現(xiàn)基于鼠標(biāo)滑過(guò)及點(diǎn)擊的選項(xiàng)卡切換效果,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-09-09
vue 集成騰訊地圖實(shí)現(xiàn)api(附DEMO)
之前項(xiàng)目使用騰訊地圖,不利于開發(fā)者查找,這篇文章主要介紹了vue 集成騰訊地圖實(shí)現(xiàn)api,具有一定的參考價(jià)值,感興趣的可以了解下2021-07-07
JavaScript自動(dòng)點(diǎn)擊鏈接 防止繞過(guò)瀏覽器訪問(wèn)的方法
下面小編就為大家?guī)?lái)一篇JavaScript自動(dòng)點(diǎn)擊鏈接 防止繞過(guò)瀏覽器訪問(wèn)的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
JavaScript中的Window.open()用法示例詳解
這篇文章主要給大家介紹了關(guān)于JavaScript中Window.open()用法的相關(guān)資料,今天在項(xiàng)目中用到了彈出子窗口,就想到了用JavaScript實(shí)現(xiàn)的兩種方法,其中一個(gè)就是window.open(),需要的朋友可以參考下2023-07-07
javascript實(shí)現(xiàn)密碼強(qiáng)度顯示
這篇文章主要介紹了使用javascript實(shí)現(xiàn)密碼強(qiáng)度顯示,十分實(shí)用的功能,從個(gè)人項(xiàng)目中移植出來(lái)的,分享給大家,希望大家能夠喜歡。2015-03-03
Js 時(shí)間函數(shù)getYear()的使用問(wèn)題探討
不推薦使用getYear()這個(gè)函數(shù),因?yàn)樵诨鸷酗@示是不正確的,所以推薦使用getFullYear() 函數(shù),接下來(lái)為大家詳細(xì)介紹下getYear函數(shù)在不同瀏覽下的使用問(wèn)題2013-04-04
微信小程序底部tabBar遮擋內(nèi)容的簡(jiǎn)單處理方法
幾乎每個(gè)app都會(huì)用到底部導(dǎo)航的,相對(duì)于小程序而言自然也是如此了,這篇文章主要給大家介紹了關(guān)于微信小程序底部tabBar遮擋內(nèi)容的簡(jiǎn)單處理方法,需要的朋友可以參考下2021-08-08
JavaScript定義函數(shù)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了JavaScript定義函數(shù)的相關(guān)資料,需要的朋友可以參考下2017-06-06

