Talk is cheap. Show me your code

用 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  的倍数的流星设为一开始就出现

 

然后流星雨的动画就完成了,可以点击这里查看在线示例

 

posted @ 2017-07-06 10:17  Wise.Wrong  阅读(10579)  评论(5编辑  收藏  举报