马黑黑 发表于 2022-1-26 21:32

分享一个CSS+JS下雨特效

本帖最后由 马黑黑 于 2022-1-26 21:44 编辑

刚刚封装了一个在某开源社区看到的CSS+JS的下雨特效,作者是FatMan,我简单做些改装与分离,以便能应用于论坛帖子。
使用方法:

<link rel="stylesheet" href="https://638183.freep.cn/638183/qd/rain.css" />
<!-- 帖子代码开始 -->
<div id="rain"></div>
<!-- 帖子代码结束 -->
<!-- 这里是 JS 代码 -->

JS代码这里运行不了外部封装的。完整JS代码如下:

<script language="javascript">

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)
                        }
                        dorpRain();
                }, parseInt(10 + Math.random() * 10, 10))
      }
      dorpRain();
}

function debounce(fn, wait, context){
      let timer = null;
      return function() {
                timer ? clearTimeout(timer) : '';
                        timer = setTimeout(() => {
                        fn.apply(context, arguments);
                         }, wait)
      }
}

      function onresize(event) {
                clientWidth = document.body.clientWidth;
                clientHeight = document.body.clientHeight;
      }

window.addEventListener("resize", debounce(onresize, 200, null))

</script>

可以将 id 为 rain 的 div (下称rain),也就是下雨的场地,作为帖子的父窗体,它的定位设定时 relative,居中,可以重新定义,还可以修改尺寸、大小、背景色等等。rain 的下雨效果是全景的,但可大可小,由使用者设定尺寸。改变 rain 场地属性的方法:

<div id="rain" style="background: #444;width:800px;height:460px;"></div>

当然,如果愿意,也可在 <link ... /> 语句之后重新用CSS页内嵌入方法定义 #rain 的属性,但不建议做太复杂的定义,尺寸、具体定位、背景色等就好。

另外,请确保web也代码中没有其他地方使用 rain 做 id 标识。

效果可看下楼。


马黑黑 发表于 2022-1-26 21:35

本帖最后由 马黑黑 于 2022-1-26 21:41 编辑 <br /><br /><link rel="stylesheet" href="https://638183.freep.cn/638183/qd/rain.css">
<div id="rain" style="margin: auto; width: 700px; height: 400px;"></div>

<script>

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)
                        }
                        dorpRain();
                }, parseInt(10 + Math.random() * 10, 10))
        }
        dorpRain();
}

function debounce(fn, wait, context){
        let timer = null;
        return function() {
                timer ? clearTimeout(timer) : '';
                        timer = setTimeout(() => {
                        fn.apply(context, arguments);
                       }, wait)
        }
}

        function onresize(event) {
                clientWidth = document.body.clientWidth;
                clientHeight = document.body.clientHeight;
        }

window.addEventListener("resize", debounce(onresize, 200, null))

</script>

马黑黑 发表于 2022-1-26 21:40

dz不让运行外部 JS ,只能全代码加入

马黑黑 发表于 2022-1-26 21:46

效果还是达不到要求,估计与dz对JS的相关限制有关。感兴趣的朋友请在本地尝试一下如下完整代码:

<link rel="stylesheet" href="https://638183.freep.cn/638183/qd/rain.css">
<div id="rain" style="margin: auto; width: 700px; height: 400px;"></div>
<script language="javascript" src="https://638183.freep.cn/638183/qd/rain.js"></script>

红影 发表于 2022-1-26 21:54

马黑黑 发表于 2022-1-26 21:46
效果还是达不到要求,估计与dz对JS的相关限制有关。感兴趣的朋友请在本地尝试一下如下完整代码:

怎么尝试,就直接用这句就可以了?我试试去。。。

红影 发表于 2022-1-26 21:58

马黑黑 发表于 2022-1-26 21:46
效果还是达不到要求,估计与dz对JS的相关限制有关。感兴趣的朋友请在本地尝试一下如下完整代码:

看到了,而且还有地面的涟漪。论坛里的好像看不到落在地上的涟漪啊。

马黑黑 发表于 2022-1-26 22:50

红影 发表于 2022-1-26 21:58
看到了,而且还有地面的涟漪。论坛里的好像看不到落在地上的涟漪啊。

嗯,查了一下资料,这是Window.onlod冲突问题。dz用很多封装的JS,里面肯定用到了Window.onload事件,这个事件只能用一次

马黑黑 发表于 2022-1-26 22:50

红影 发表于 2022-1-26 21:54
怎么尝试,就直接用这句就可以了?我试试去。。。

{:4_181:}
页: [1]
查看完整版本: 分享一个CSS+JS下雨特效