有趣的css—简单的下雨效果2.0版
简单的下雨效果2.0版
前言
笔者上一篇发布的文章有趣的css—简单的下雨效果中有位老哥给我提了一个很棒的建议,大致意思是波纹应该产生于雨滴的消失处。
这是按照老哥的建议完善后的效果图:
由于我制作GIF图片的工具最多只支持制作33FPS的GIF图,所以看起来可能有一点点卡顿,实际的效果比图片还是要好一些的,点击这里可以在线查看2.0版的效果。
思路
制作背景
首先给body中添加一个id为rain的div,并通过背景颜色线性渐变得到天空-地平线-海面的效果。
<!DOCTYPE html>
<html>
<head>
<meta name="charset" content="utf-8"/>
<title>简单的下雨效果2.0</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%;}
}
制作波纹效果
通过背景透明和圆形边框得到圆形的环,再将其沿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;
}
}
在雨滴被移除的位置添加波纹
通过计算移除雨滴的随机时间得到雨滴消失时距离顶部的距离。
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');
let left = parseInt(Math.random() * clientWidth, 10) + 'px';
el.style.left = left;
rain.appendChild(el);
let time = parseInt(Math.random() * 350, 10);
setTimeout(() => {
rain.removeChild(el);
let newEl = document.createElement('div');
newEl.setAttribute('class', 'ripple');
newEl.style.left = left;
newEl.style.top = parseInt(clientHeight / 100 * 50 + (time / 350 * (clientHeight / 100 * 50)), 10) + 'px';
rain.appendChild(newEl);
setTimeout(() => {
rain.removeChild(newEl);
}, 600)
}, 400 + time, 10)
}
}, parseInt(10 + Math.random() * 10, 10))
}
dorpRain();
}
使波纹以水滴消失位置为圆心扩散
其实到这一步还是有个问题,就是波纹是向右下方扩散的,下面是笔者将动画时间增大10倍,以及将波纹动画中的属性的宽高增大10倍后的效果:
产生此效果的原因是此时只能达到雨滴与波纹两个属性左上角的点重合,如果要使波纹以水滴消失位置为圆心扩散,需要让两个元素的中心点重合。
修改代码,先去掉rotate(原因后面再说),再使用translate(-50%, -50%)将元素向左上方移动,使两个元素的中心点等于雨滴被移除时的位置。
.raindrop {
/* 将transform: rotateY(45deg)改为transform: translate(-50%, -50%),其余不变*/
transform: translate(-50%, -50%);
/* ...... 其余的css不要删除*/
}
.ripple {
/* 将transform: rotateX(75deg)改为transform: translate(-50%, -50%),其余不变*/
transform: translate(-50%, -50%);
/* ...... 其余的css不要删除*/
}
效果图:
此时已经达到了波纹以水滴消失位置为圆心扩散,但要是加入了rotate之后,效果就完全不一样了:
.raindrop {
/* 将transform: translate(-50%, -50%)改为transform: rotateY(45deg) translate(-50%, -50%),其余不变*/
transform: rotateY(45deg) translate(-50%, -50%);
/* ...... 其余的css不要删除*/
}
.ripple {
/* 将transform: translate(-50%, -50%)改为transform: rotateX(75deg) translate(-50%, -50%),其余不变*/
transform: rotateX(75deg) translate(-50%, -50%);
/* ...... 其余的css不要删除*/
}
效果图:
可以看出此时的波纹是向下方扩散,这是为什么呢?
让我们先看一段很简单的代码:
<!DOCTYPE html>
<html>
<head>
<meta name="charset" content="utf-8"/>
<title>测试</title>
</head>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
div {
width: 100px;
height: 100px;
background-color: #fe0000;
margin-top: 20px;
}
</style>
<body>
<div></div>
<div style="transform: rotateX(75deg);"></div>
</body>
</html>
效果图:
rotateX会改变元素的高度,但其并不会改变元素在rotateX前占据的位置的大小!!!所以当我们使用同时使用 rotate 和translate(-50%, -50%)时并达到预期的效果。
就比如上面的数据,元素的宽高皆为100px,将其rotateX(75deg)后,宽度不变,translateX(-50%)会将元素移动到Y轴的中心线上;但此时元素的高度已经变为25.88px,translateY(-50%)只能将其向上移动12.94px,实际上是需要向上移动50px才能达到X轴的中心线上。
就比如下图(尝试将看待元素的视角从XY转移到YZ)
A、B、C、D四条线,B的长度与A一致,AB之间的角度为45°,AD与CD之间皆为直角,那么根据正弦定理,C的长度等于B的长度的sin45°,也就是A的长度的sin45°。
元素rotateX(75deg)后,height由100px变为25.88,也就是:
100 * sin(90° - 75°)
= 100 * sin(15°)
= 100 * 0.25881904510252
≈ 100 * 0.2588
≈ 25.88
所以rotateY(45deg)
sin(45°)
= 0.70710678118655
≈ 0.71
要使雨滴达到rotateY(45deg)前 translateX(-50%)的效果,需要 translateX(-50% / 0.71) 约等于 translateX(-70%),也就是:
.raindrop {
/* 将transform: rotateY(45deg) translate(-50%, -50%)改为transform: rotateY(45deg) translate(-70%, -50%),其余不变*/
transform: rotateY(45deg) translate(-70%, -50%);
/* ...... 其余的css不要删除*/
}
rotateX(75deg)
sin(90° - 75°)
= sin(15°)
= 0.25881904510252
≈ 0.26
同理,要使波纹达到rotateX(75deg)前translateY(-50%)的效果,需要 translateY(-50% / 0.26) 约等于 translateY(-192%) ,也就是:
.ripple {
/* 将transform: rotateX(75deg) translate(-50%, -50%)改为transform: rotateX(75deg) translate(-50%, -192%),其余不变*/
transform: rotateX(75deg) translate(-50%, -192%)
/* ...... 其余的css不要删除*/
}
效果图:
随后再递归调用dorpRain方法,即可生成批量的雨滴以及对应的波纹。
结尾
笔者才疏学浅,慌忙之下难免有遗漏或是疏忽,如有错误之处,还望各位看官不吝赐教,笔者在此感谢。
最终的代码我放在简单的下雨效果2.0。
作者:Fatman
博客园地址:https://www.cnblogs.com/liujingjiu
CSDN地址:https://blog.csdn.net/qq_35508835
版权归Fatman所有,欢迎保留原文链接进行转载:)
有趣的css—简单的下雨效果2.0版的更多相关文章
- 有趣的css—简单的下雨效果
简单的下雨效果 前言 最近在b站上看到一个下雨效果的视频,感觉思路很清奇,我也按照自己的思路做了一个简单的下雨效果. 由于我制作GIF图片的工具最多只支持制作33FPS的GIF图,所以看起来可能有一点 ...
- 用PHP写的一个简单的分页类 1.0版
<?php /* 分页类 用于实现对多条数据分页显示 version:1.0 author:Knight E-Mail:S.Knight.Work@gmail.com Date:2013-10- ...
- 用PHP写的一个简单的分页类 2.0版
<?php /* 分页类 用于实现对多条数据分页显示 version:2.0 //基于1.0 数据库查询用mysqli实现 author:Knight E-Mail:S.Knight.Work@ ...
- 使用CSS实现一个简单的幻灯片效果
方法一: 简单的CSS代码实现幻灯片效果 方法二: 使用CSS3 Animation来制作幻灯片 方法一: 简单的CSS代码实现幻灯片效果 话不多说,直接上代码 <!DOCTYPE html&g ...
- HTML与CSS简单页面效果实例
本篇博客实现一个HTML与CSS简单页面效果实例 index.html <!DOCTYPE html> <html> <head> <meta charset ...
- Css实现一个简单的幻灯片效果页面
使用animation动画实现一个简单的幻灯片效果. 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 2 ...
- css实现简单音乐符效果
css实现简单音乐符效果 利用css3中的transform.animation.keyframes实现 <!DOCTYPE html> <html lang="en&qu ...
- 3.8.1 HTML与CSS简单页面效果实例
HTML与CSS简单页面效果实例 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
随机推荐
- IPFS挖矿硬盘满了会怎样?
IPFS是一个互联网协议,对标现在的HTTP.所以,可以想见未来IPFS有多大的价值.所谓IPFS挖矿,是基于IPFS,挖的是filecoin,称其为filecoin挖矿倒是更为贴切.许多初接触IPF ...
- C语言宏的使用
使用条件宏进行条件编译 譬如,对于同一份代码,我想编译出两个不同的版本,在其中一个版本中去掉某一部分功能, 这时可以通过条件宏判断是否编译,例: 如果不使用条件宏进行控制,想编译两个不同版本的程序,就 ...
- Web安全(更新中)
sql注入 创建一个数据库 create database admin1; 查询数据库 查看所有数据库 show databases; 使用该数据库 use admin1; 创建一个表 创建一个 ...
- C++并发与多线程学习笔记--future成员函数、shared_future、atomic
std::future的其他成员函数 std::shared_future 原子操作.概念.基本用法 多线程主要是为了执行某个函数,本文的函数的例子,采用如下写法 int mythread() { c ...
- ATMS中去pause Activity A.
上文写完之后,感觉这个部分写的还是不清晰,本文继续补充一下. 首先还是看堆栈. obtain:78, PauseActivityItem (android.app.servertransaction) ...
- angularjs 图片上传
<input type="file" file-model="myFile"/><div class="col-md-12" ...
- SQLserver数据库安装教程
大家好,这期给大家带来一期SQL server的安装教程 下载SQL Server 2019 Developer 官方网址: https://www.microsoft.com/zh-cn/sql-s ...
- oo第二单元博客总结
P1 设计结构 三次作业的架构都没有较大的改动,基本上都是靠调度器接受输入的请求并放入队列,然后调度器根据不同的电梯的当前状态来把请求分配至不同电梯的请求队列中,最后电梯再根据自己的请求队列去运行.因 ...
- PYTHON工业互联网应用实战12—客户端操作
本章节我们将实现与admin里类似的列操作"下达"功能,演示客户端是如何实现操作功能,同时,演示也会强调一点,何时合并你的功能代码,避免相同功能使用不同的代码段来实现,在企业开发中 ...
- 机器学习--PR曲线, ROC曲线
在机器学习领域,如果把Accuracy作为衡量模型性能好坏的唯一指标,可能会使我们对模型性能产生误解,尤其是当我们模型输出值是一个概率值时,更不适宜只采取Accuracy作为衡量模型性泛化能的指标.这 ...