前言
最近在b站上看到一个下雨效果的视频,感觉思路很清奇,我也按照自己的思路做了一个简单的下雨效果。
由于我制作GIF图片的工具最多只支持制作33FPS的GIF图,所以看起来可能有一点点卡顿,实际的效果比图片还是要好一些的,点击这里可以在线查看效果。
思路
制作背景
首先给body中添加一个id为rain的div,并通过背景颜色线性渐变得到天空-地平线-海面的效果。
<!DOCTYPE html>
<html>
<head>
<meta name="charset" content="utf-8"/>
<title>简单的下雨效果</title>
</head>
<body>
<div id="rain"></div>
</body>
</html>
#rain {
position: relative;
height: 100%;
background: linear-gradient(#333,#999 ,#1f4794);
background-repeat: no-repeat;
background-size: 100% 100%;
}
制作雨滴
通过设置背景颜色径向渐变得到圆形的水滴,再将其沿Y轴进行旋转得到椭圆形的水滴,最后给其添加水滴下落的动画效果。
.raindrop {
display: inline-block;
position: absolute;
top: 0;
left: 150px;
width: 5px;
height: 5px;
background: radial-gradient(#8fd4fc, #52b1f2, #0599fc);
border-radius: 5000px;
transform: rotateY(45deg);
animation: raindrop .8s;
}
@keyframes raindrop {
0% {top:5%;}
10% {top:10%;}
20% {top:20%;}
30% {top:30%;}
40% {top:40%;}
50% {top:50%;}
60% {top:60%;}
70% {top:70%;}
80% {top:80%;}
90% {top:90%;}
100% {top:95%;}
}
动态添加大批量的雨滴
通过appendChild添加随机位置的雨滴节点,并随机在400ms~750ms之间通过removeChild将其移除。
let clientWidth;
let clientHeight;
window.onload = function onload(){
let rain = document.getElementById(‘rain‘);
clientWidth = document.body.clientWidth;
clientHeight = document.body.clientHeight;
function dorpRain(){
setTimeout(() => {
if(typeof clientWidth !== ‘undefined‘ && null !== clientWidth){
let el = document.createElement(‘div‘);
el.setAttribute(‘class‘, ‘raindrop‘);
el.style.left = parseInt(Math.random() * clientWidth, 10) + ‘px‘;
rain.appendChild(el);
setTimeout(() => {
rain.removeChild(el);
}, parseInt(400 + Math.random() * 350, 10))
}
dorpRain();
}, parseInt(10 + Math.random() * 10, 10))
}
dorpRain();
}
制作波纹效果
通过背景透明和圆形边框得到圆形的环,再将其沿X轴进行旋转得到椭圆形的环,最后给其添加环逐渐扩大的动画效果。
.ripple {
display: inline-block;
position: absolute;
top: 60vh;
left: 50vh;
border: 2px solid #8fd4fc;
border-radius: 5000px;
background: rgba(0, 0, 0, 0);
transform: rotateX(72deg);
animation: ripple .6s;
}
@keyframes ripple {
0% {
width: 2px;
height: 2px;
}
10% {
width: 4px;
height: 4px;
}
20% {
width: 6px;
height: 6px;
}
30% {
width: 8px;
height: 8px;
}
40% {
width: 10px;
height: 10px;
}
50% {
width: 12px;
height: 12px;
}
60% {
width: 14px;
height: 14px;
}
70% {
width: 16px;
height: 16px;
}
80% {
width: 18px;
height: 18px;
}
90% {
width: 20px;
height: 20px;
}
100% {
width: 22px;
height: 22px;
}
}
动态添加大批量的波纹
通过appendChild添加随机位置的雨滴节点,并在动画效果过后通过removeChild将其移除。
let clientWidth;
let clientHeight;
window.onload = function onload(){
let rain = document.getElementById(‘rain‘);
clientWidth = document.body.clientWidth;
clientHeight = document.body.clientHeight;
function ripple(){
setTimeout(() => {
if(typeof clientWidth !== ‘undefined‘ && null !== clientWidth && typeof clientHeight !== ‘undefined‘ && null !== clientHeight){
let el = document.createElement(‘div‘);
el.setAttribute(‘class‘, ‘ripple‘);
el.style.left = parseInt(Math.random() * clientWidth, 10) + ‘px‘;
el.style.top = parseInt(clientHeight / 100 * 50 + (Math.random() * (clientHeight / 100 * 50)), 10) + ‘px‘;
rain.appendChild(el);
setTimeout(() => {
rain.removeChild(el);
}, 600)
}
ripple();
}, parseInt(10 + Math.random() * 10, 10))
}
ripple();
}
细节
最后再完善一些细节,比如window.onresize监听窗口变化以及overflow: hidden隐藏超出屏幕外的内容等等。
#rain {
position: relative;
height: 100%;
overflow: hidden;
background: linear-gradient(#333,#999 ,#1f4794);
background-repeat: no-repeat;
background-size: 100% 100%;
}
let clientWidth;
let clientHeight;
window.onresize = function onresize(){
clientWidth = document.body.clientWidth;
clientHeight = document.body.clientHeight;
}
结尾
笔者才疏学浅,慌忙之下难免有遗漏或是疏忽,如有错误之处,还望各位看官不吝赐教,笔者在此感谢。
最终的代码我放在简单的下雨效果。
<p>作者:<a herf="https://www.cnblogs.com/liujingjiu">Fatman</a></p>
<p>博客园地址:<a
herf="https://www.cnblogs.com/liujingjiu">https://www.cnblogs.com/liujingjiu</a></p>
<p>CSDN地址:<a
herf="https://blog.csdn.net/qq_35508835">https://blog.csdn.net/qq_35508835</a></p>
版权归<a
herf="https://www.cnblogs.com/liujingjiu">Fatman</a>所有,欢迎保留原文链接进行转载:)