css3动画-自由落体实现原理

167 阅读2分钟

寻寻觅觅,冷冷清清,凄凄惨惨戚戚。乍暖还寒时候,最难将息。三杯两盏淡酒,怎敌他、晚来风急!雁过也,正伤心,却是旧时相识。

满地黄花堆积,憔悴损,如今有谁堪摘?守着窗儿,独自怎生得黑!梧桐更兼细雨,到黄昏、点点滴滴。这次第,怎一个愁字了得!

喜欢李清照的词,也喜欢在雨天睡个天昏地暗,生活本来平淡,所以在平淡中学会寻找心灵的归宿,而落雨,淅淅沥沥的,让心灵得到最大的安宁。

下面我们聊聊落雨的实现原理,超级简单,主要是各种参数要看感觉。

自由落体的模拟

通过animation 中的 cubic-bezier 来模拟自由落体的运动曲线,数值我是用过chrome浏览器自己也调的,这个主要凭感觉。

复制代码 animation: drops 1s cubic-bezier(0.47, 0.05, 0.98, 0.47) infinite;

接下来是对雨滴的描述

@keyframes drops{ 
    0%{ 
        opacity: 0; 
    } 
    30%{ 
        opacity: 1; 
    } 
    90%{ 
        opacity: 1; 
    } 
    100%{ 
        opacity: 0; 
        transform: translate3d(10vh,110vh,0);
    } 
 }

重点是 0%到30% 90%到100%雨滴的显示和隐藏。整个落雨的动画就定义完了。

接下来定义雨滴,这个可以自由发挥,细线也好,图片也罢,看着怎么舒服怎么来,因为我的雨落的速度快,所以我是雨线

position: absolute; 
width: 4px; 
height: 40px; 
background: #6e7766; 
clip-path: ellipse(10% 30% at 50% 50%); 
opacity: 0;
body {
  height: 100%;
}
.drop {
  position: relative;
  height: 100%;
  overflow: hidden;
  .yudi {
    position: absolute;
    width: 4px;
    height: 40px;
    background: #6e7766;
    opacity: 0;
    animation: drops 1s cubic-bezier(0.47, 0.05, 0.98, 0.47) infinite;
    clip-path: ellipse(10% 30% at 50% 50%);
  }
}
@keyframes drops {
  0% {
    opacity: 0;
  }
  30% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: translate3d(10vh, 110vh, 0);
    opacity: 0;
  }
}

落雨的分布

而js部分主要就是 雨滴 这个元素节点在我们屏幕上的添加,以及增加一个 delay 的延迟函数

我用的就是随机数这个算法,核心算法就是

复制代码Math.random()

这样得到一个随机数,来去定义一个横行的坐标系列,通过累加的方式避免 雨滴重叠

let outX = 0;
for (let i = 0; i < 30; i++) {
  let lefts = Math.floor(Math.random() * 4 + 2);
  outX += lefts;
}

同理在定义一个随机函数,来实现我们刚刚添加的雨滴延迟动画的触发。

for (let i = 0; i < 30; i++) {
  let delay = Math.floor(Math.random() * 50 + 1);
}

完整的添加就是

<body> <div class="drop"> </div> </body>
let drop = $('.drop');
let eleArray = [];
let increment = 0;
for (let i = 0; i < 30; i++) {
  let delay = Math.floor(Math.random() * 50 + 1);
  let lefts = Math.floor(Math.random() * 4 + 2);
  let newDiv = $('<div/>').addClass('yudi');
  increment += lefts;
  newDiv.css({ left: `${increment}%`, top: `${lefts * 2}%`, 'animation-delay': `${delay / 10}s` });
  drop.append(newDiv);
}

这样落雨就实现了,大家尝试一下吧~