来自 Web前端 2020-05-07 05:42 的文章
当前位置: 网上澳门金莎娱乐 > Web前端 > 正文

CSS实现雨滴动画效果

时间: 2019-09-02阅读: 358标签: 效果玻璃窗

  1. 黑白图像

今天我们要实现的是雨滴效果,不过实现雨滴前,我们先把毛玻璃的效果弄出来,没有玻璃窗,雨都进屋了,还有啥好敲打的。

这段代码会让你的彩色照片显示为黑白照片,是不是很酷?

div class='window'/div

.window { position: absolute; width: 100vw; height: 100vh; background: url("?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg"); background-size: cover; background-position: 100%; filter: blur(10px);}

img.desaturate {

其实就是给一张图片,做了个模糊化的效果,看起来像毛玻璃的效果

    filter: grayscale(100%);

一滴雨

    -webkit-filter: grayscale(100%);

雨滴的效果就很巧妙了,让我们看下一滴雨完整的效果图

    -moz-filter: grayscale(100%);

这滴雨其实分为两个部分,第一部分是底部的阴影部分,其实是个边框来的,代码如下:

    -ms-filter: grayscale(100%);

.border { position: absolute; margin-left: 92px; margin-top: 51px; border-radius: 100%; box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.6); transform: rotateY(0); width: 20px; height: 28px;}

div class='border'/div

    -o-filter: grayscale(100%);

通过width和height属性和border-radius把border拉成一个椭圆形,然后用box-shadow把阴影拉出来,作为水滴的阴影,边框的最终效果如下:

}

然后是水滴的部分

  1. 使用 :not() 在菜单上应用/取消应用边框
.raindrop { filter: brightness(1.2); position: absolute; margin-left: 90px; margin-top: 50px; background-size: 5vw 5vh; border-radius: 100%; background-image: url("?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg"); transform: rotate(180deg) rotateY(0); background-position: 48.1994160428% 54.3259834959%; width: 24px; height: 28px;}

div class='raindrop'/div

先给每一个菜单项添加边框

水滴用background-image设置了玻璃的图片作为倒影,倒影之所以是倒影,是因为影子是倒着的,所以用transform的rotate()旋转了图片180,正好倒过来通过background-position设置图片在水滴的显示的位置,后面不同的水滴会显示出的倒影因为图片位置的变化都不同,显得真实raindrop的width比border的width多几个像素,是为了让水滴的两边盖住border,只留border的上下显示阴影raindrop的margin-left和margin-top和border的也是略有不同,是为了raindrop能居中覆盖在border上面,使得水滴和阴影融合的更真实

/* add border */

单独无阴影的水滴效果如下:

.nav li {

随机雨滴

  border-right: 1px solid #666;

雨从来都不是一滴一滴来的,而且也不会很有规律的来,为了让雨滴随机出现在玻璃窗上,css-doodle框架。

}

css-doodle use="var(--rule)"/css-doodle

……然后再除去最后一个元素……

先创建一个css-doodle的自定义组件

// remove border /

--rule: ( :doodle { @grid: 10x10/ 100%; overflow: visible;}

.nav li:last-child {

打出10*10个grid,这样最多可以出现100滴雨

  border-right: none;

transform: scale(@rand(.5, .9));

}

通过transform:scale让雨滴随机变大变小

……可以直接使用 :not() 伪类来应用元素:

:before { content: ''; position: absolute; margin-left: @var(--mleft); margin-top: @var(--mtopb); border-radius: 100%; box-shadow: 0 0 0 @var(--shadow-size) rgba(0, 0, 0, 0.6); transform: rotateY(0); width: @var(--widthb); height: @var(--height);}:after { content: ''; filter: brightness(1.2); position: absolute; margin-left: @var(--mleft); margin-top: @var(--mtopa); background-size: 5vw 5vh; border-radius: 100%; background-image: url("?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg"); transform: rotate(180deg) rotateY(0); background-position: @r(1%, 100%) @r(1%, 100%); width: @var(--widtha); height: @var(--height); }

.nav li:not(:last-child) {

这里的:before和:after大家看的是不是很眼熟,其实:before里面的内容就是前面border的样式,:after里面的就是前面raindrop的样式。content必须要有,因为在伪元素(before,after)里如果没有设置“content”属性,伪元素是无用的,整个:before和:after里面的配置就都无效了。为了让雨滴显得更清晰,加了filter: brightness(1.2)让雨滴显得更亮一些。

  border-right: 1px solid #666;

这里面比较奇怪的是@var(),它其实就是css的变量,在css-doodle做了一层包装,作用和css的var()是一样的,我们看下这些变量的定义

}

--size:(4 + @r(1, 8));--shadow-size: calc(((@var(--size)*0.3) - 1)*1px);--mleft:@r(1, 100)px;--mtop:@r(1, 100);--mtop1:(@var(--mtop) - 1);--mtopb:calc(@var(--mtop)*1px);--mtopa:calc(@var(--mtop1)*1px);--height:@r(15, 25)px;--width:@r(8, 20);--width1:(@var(--width) + 5);--widthb:calc(@var(--width)*1px);--widtha:calc(@var(--width1)*1px);

这样代码就干净,易读,易于理解了。

这里有几个坑要说明一下:

当然,如果你的新元素有兄弟元素的话,也可以使用通用的兄弟选择符(~):

1号坑:css-doodle提供了@calc(),但是这里计算还是要用css的calc(),使用@calc()无效。2号坑:在使用@var做加减法的时候,+-号的两遍要有空格,否则计算无效,切记切记。3号不是坑:计算好数值后,怎么带上px单位呢,用calc(value*1px)这种方法就可以了,其他的单位也可以用这种方法。4号说明:为什么要用变量?是因为before和after不在一起,为了让boder和raindrop的margin-left、margin-top、width、height等属性能够保持一致,就需要用变量在before和after外面定义好,传值到里面去。

..nav li:first-child ~ li {

最终的效果如下:

  border-left: 1px solid #666;

没动画效果怎么敲打我窗

}

雨点如果只是这样洒在窗户,那就没有敲打的意思,为了体现敲打,我决定让雨点动起来。

  1. 页面顶部阴影
:before { content: ''; position: absolute; margin-left: @var(--mleft); margin-top: @var(--mtopb); border-radius: 100%; box-shadow: 0 0 0 @var(--shadow-size) rgba(0, 0, 0, 0.6); transform: rotateY(0); width: @var(--widthb); height: @var(--height); opacity: 0; animation: raindrop-fall 500ms cubic-bezier(0.175, 0.885, 0.32, 1.275); animation-fill-mode: forwards; animation-delay: @var(--delay);}:after { content: ''; filter: brightness(1.2); position: absolute; margin-left: @var(--mleft); margin-top: @var(--mtopa); background-size: 5vw 5vh; border-radius: 100%; background-image: url("?id=OHR.ParrotsIndia_ZH-CN8386276023_UHD.jpg"); transform: rotate(180deg) rotateY(0); background-position: @r(1%, 100%) @r(1%, 100%); width: @var(--widtha); height: @var(--height); opacity: 0; animation: raindrop-fall 500ms cubic-bezier(0.175, 0.885, 0.32, 1.275); animation-fill-mode: forwards; animation-delay: @var(--delay);}

下面这个简单的 css3 代码片段可以给网页加上漂亮的顶部阴影效果:

重点是:before和:after里面的最后三行,是用来实现动画效果的。

body:before {

cubic-bezier()控制动画的速度,使得雨滴落到玻璃窗的效果更逼真animation-delay 雨点出现的时间随机,同样是为了效果更逼真,逼真的效果真麻烦

          content: "";

再来看看raindrop-fall的@keyframe设置

          position: fixed;

@keyframes raindrop-fall { 0% { opacity: 0; transform: rotate(180deg) scale(2.5, 2.3) rotateY(0); } 100% { opacity: 1; transform: rotate(180deg) scale(1, 1) rotateY(0); }}

          top: -10px;

          left: 0;

          width: 100%;

          height: 10px;

          -webkit-box-shadow: 0px 0px 10px rgba(0,0,0,.8);

          -moz-box-shadow: 0px 0px 10px rgba(0,0,0,.8);

          box-shadow: 0px 0px 10px rgba(0,0,0,.8);

          z-index: 100;

}

  1. 给 body 添加行高

你不需要分别添加 line-height 到每个p,h标记等。只要添加到 body 即可:

body {

  line-height: 1;

}

这样文本元素就可以很容易地从 body 继承。

  1. 所有一切都垂直居中

要将所有元素垂直居中,太简单了:

#####  方法一

html, body {

  height: 100%;

  margin: 0;

}

body {

  -webkit-align-items: center; 

  -ms-flex-align: center; 

  align-items: center;

  display: -webkit-flex;

  display: flex;

}

#####  方法二

.node{

width : 300px;

height : 400px;

position : absolute;

left : 50%;

top : 50%;

margin-left : -150px; /*一半的高度*/

margin-top : -200px;  /*一半的宽度*/

}

#####  方法三

.node {

width: 600px; 

height: 400px;

position: absolute; 

left: 50%; 

top: 50%;

transform: translate(-50%, -50%);

/* 50%为自身尺寸的一半 */

}

#####  方法四

.node {

width: 600px;

height: 400px;

position: absolute;

left: 0;

top: 0;

right: 0;

bottom: 0;

margin: auto;    /* 有了这个就自动居中了 */

}

看,是不是很简单。

注意:在IE11中要小心flexbox。

  1. 逗号分隔的列表

让html列表项看上去像一个真正的,用逗号分隔的列表:

ul > li:not(:last-child)::after {

  content: ",";

}

对最后一个列表项使用 :not() 伪类。

  1. 使用负的 nth-child 选择项目

在CSS中使用负的 nth-child 选择项目1到项目n。

li {

  display: none;

}

/* select items 1 through 3 and display them */

li:nth-child(-n+3) {

  display: block;

}

  1. 对图标使用 SVG

我们没有理由不对图标使用SVG:

.logo {

  background: url("logo.svg");

}

SVG对所有的分辨率类型都具有良好的扩展性,并支持所有浏览器都回归到IE9。这样可以避开.png、.jpg或.gif文件了。

  1. 优化显示文本

有时,字体并不能在所有设备上都达到最佳的显示,所以可以让设备浏览器来帮助你:

html {

  -moz-osx-font-smoothing: grayscale;

  -webkit-font-smoothing: antialiased;

  text-rendering: optimizeLegibility;

}

注:请负责任地使用 optimizeLegibility。此外,IE /Edge没有 text-rendering 支持。

  1. 对纯 CSS 滑块使用 max-height

使用 max-height 和溢出隐藏来实现只有CSS的滑块:

.slider ul {

  max-height: 0;

  overlow: hidden;

}

.slider:hover ul {

  max-height: 1000px;

  transition: .3s ease;

}

  1. 继承 box-sizing

让 box-sizing 继承 html:

html {

  box-sizing: border-box;

}

*, *:before, *:after {

  box-sizing: inherit;

}

这样在插件或杠杆其他行为的其他组件中就能更容易地改变 box-sizing 了。

  1. 表格单元格等宽

表格工作起来很麻烦,所以务必尽量使用 table-layout: fixed 来保持单元格的等宽:

.calendar {

  table-layout: fixed;

}

本文由网上澳门金莎娱乐发布于Web前端,转载请注明出处:CSS实现雨滴动画效果

关键词: