用 CSS3 做一个流星雨动画
昨天 UI 提交过来一个登录页的设计稿,要求背景有一个流星雨动画,做完之后觉得挺有趣,分享一下~
一、流星动画
首先创建一个 div 作为画布
<div id="stars"> <div class="star" style="top: 0px;left: 500px;"></div> </div>
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: linear-gradient(rgba(0, 108, 172, 1), rgba(0, 122, 195, .7)); } #stars { margin: 0 auto; max-width: 1600px; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 2; }
为了防止浏览器分辨率太大而影响视觉效果,给画布加了 max-width 和 margin:auto
然后画出流星的形状
.star { display: block;
width: 1px;
background: transparent; position: relative; opacity: 0; /*过渡动画*/ animation: star-fall 3s linear infinite; -webkit-animation: star-fall 3s linear infinite; -moz-animation: star-fall 3s linear infinite; } .star:after { content: ''; display: block; border: 0px solid #fff; border-width: 0px 90px 2px 90px; border-color: transparent transparent transparent rgba(255, 255, 255, .5); box-shadow: 0 0 1px 0 rgba(255, 255, 255, .1); /*变形*/ transform: rotate(-45deg) translate3d(1px, 3px, 0); -webkit-transform: rotate(-45deg) translate3d(1px, 3px, 0); -moz-transform: rotate(-45deg) translate3d(1px, 3px, 0); transform-origin: 0% 100%; -webkit-transform-origin: 0% 100%; -moz-transform-origin: 0% 100%; }
创建动画,实现流星划过、渐入渐隐的效果
@keyframes star-fall { 0% { opacity: 0; transform: scale(0.5) translate3d(0, 0, 0); -webkit-transform: scale(0.5) translate3d(0, 0, 0); -moz-transform: scale(0.5) translate3d(0, 0, 0); } 50% { opacity: 1; transform: translate3d(-200px, 200px, 0); -webkit-transform: translate3d(-200px, 200px, 0); -moz-transform: translate3d(-200px, 200px, 0); } 100% { opacity: 0; transform: scale(1.2) translate3d(-300px, 300px, 0); -webkit-transform: scale(1.2) translate3d(-300px, 300px, 0); -moz-transform: scale(1.2) translate3d(-300px, 300px, 0); } }
在50%的节点上,我没有加上 scale(1) 这条属性
是因为加上之后,动画进行到 50% 的时候,会有一个很明显的停顿
删掉 scale(1) 能改善这个情况,但并没有解决
而且当 animation-timing-function 设置为 linear 之外的属性的时候,问题特别严重
如果有朋友知道这个问题的原因,一定要留言告诉我,并收下我的膝盖~
二、形成流星雨
上面只是创建了一个流星,如果要形成流星雨,还需要继续
<div id="stars"></div>
var stars = document.getElementById('stars') // js随机生成流星 for (var j=0;j<30;j++) { var newStar = document.createElement("div") newStar.className = "star" newStar.style.top = randomDistance(500, -100) + 'px' newStar.style.left = randomDistance(1300, 300) + 'px' stars.appendChild(newStar) } // 封装随机数方法 function randomDistance (max, min) { var distance = Math.floor(Math.random() * (max - min + 1) + min) return distance }
通过 js 动态生成流星,保证 left 和 top 的值在某一范围内随机,就能产生较好的效果
然后用 js 添加动画延时,让流星不会同时出现
var star = document.getElementsByClassName('star') // 给流星添加动画延时 for (var i = 0, len = star.length; i < len; i++) {
star[i].style.animationDelay = i % 6 == 0 ? '0s' : i * 0.8 + 's' }
为了防止一开始只有一个流星的尴尬场面,我将 index 为 6 的倍数的流星设为一开始就出现
然后流星雨的动画就完成了,可以点击这里查看在线示例