
查看演示
源码下载
看到上面的效果是不是有点像人站室内看窗外雨中的夜景,窗户上雨滴的效果是那么的真实,窗外的夜景却又是那么的模糊。咱们不在诗意化了,我想大家更为关注的是用什么样的技术来实现这样的一个效果。
预处理器
在这个示例中,使用了HAML和Sass来替代我们熟悉的HTML和CSS。主要是为了制作雨滴需要上百个<div>元素,另外需要对上百个<div>写样式,毕竟每个雨滴都长得不一致嘛。使用预处理器除了可以帮助我们减少工作量之外,还可以使用预处理器中的循环、变量等。最主要的是可以使用随机函数产生的随机值,让我们不需要单独处理上百个雨滴。
有关于HAML和Sass的语法可以各自到其官网上查阅。如果你自己本地电脑不具备这样的开发环境,可以直接在Codepen创建DEMO,并且选择对应的预处理器。在HTML和CSS的配置中选择对应的预处理器。比如在HTML设置中选择HAML,在CSS设置中选择SCSS。
有关于Sass更多的中文教程,可以点击这里阅读。
结构
制作窗户雨滴的效果,其结构并不太复杂。主要分两个层次,其中是窗户,而另个是雨滴。在案例中使用.window来表示窗户,在.raindrops容器中放置了上面个雨滴.雨滴是通过.border和.drops来制作。并且将窗户.window和雨滴.raindrops都放置在容器.
container中:
.container .window .raindrops .borders- (1..120).each do.border .drops- (1..120).each do.raindrop
<div class="container"> <div class="window"></div> <div class="raindrops"> <div class="borders"><div class="border"></div><!-- 此处省略 118个border --><div class="border"></div> </div> <div class="drops"><div class="raindrop"></div><!-- 此处省略 118个raindrop --><div class="raindrop"></div> </div> </div></div>样式
$image: "http://www.w3cplus.com/sites/default/files/blogs/2015/1506/huadenchushang.jpg";$width:100vw;$height:100vh;
$raindrops:120;
.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%;}使用了两个关键知识点:.window{ ... filter:blur(10px);} 
现实生活中的雨露
在我们继续讨论之前,让我们看看现实生活中雨滴在窗户上的效果:

图片来自:Wikipedia
由于折射,雨滴翻转图像。另外,雨滴形状或多或少有些类似半球体,而且综们看起来有黑色边框。
雨滴
基于我们看到的雨滴效果,让我们来尝试制作一个单独的雨滴效果。
HAML
.container .window .raindrop
$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);}这是很简单的,我做就是使用div.raindrop画了一个椭圆。并且用了当初的背景图进行了填补,并做了一个倒转的效果。 
现在,我们要添加一个小边框,让雨滴看起来更像雨点(看起来有立体效果)。
HAML
.container .window .border .raindrop
.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);} 
请注意,我们不只是添加了一个边框,我们还对边框进行了挤压,所以看起来雨滴更自然一些。
雨滴看上去OK了,这个时候我们可以添加数以百计的雨滴:
HAML
.container .window .raindrops .borders- (1..120).each do.border .drops- (1..120).each do.raindrop
@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循环对每个雨滴做样式处理,并且使用随机函数random()产生随机值,让每个雨滴的大小,挤压都不一致。同时还使用percentage()函数,让雨滴的背景图采用不同的位置。 
上面看到的效果都是静态的,为了让它更具下雨的效果。雨滴滴下的效果,可以使用CSS3的animation来制作动画效果。
@keyframes falling { from { } to { transform: translateY(500px); }}定义好falling动画之后,只需要在雨滴上调用:@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; }}到了这一步,你也就能看到文章开头显示的雨滴窗户的效果了。是不是感觉很爽呀。