中秋特别文章——css实现海上升明月

2022-08-22 09:43:58 浏览数 (2)

想了好久都没想到什么好的创意,刚好今天想到了一句诗,海上生明月,天涯共此时。由此引发了一些思路,特意做出来和大家分享一下。

效果预览

构思

我想做的就是海面上缓缓的升起一个月亮,天上有着星星,星星要会闪,月亮是从海面升起来的,就这么简单,那下面就一起来实现吧。 首先,我们来确定整体的画面构图,大概是这样子的。

实现

天空和海面好实现,直接两个div,来一个背景渐变即可

代码语言:javascript复制
  <div class="wrap">
    <div class="sky" id="sky">
    </div>
    <div class="sea">
    </div>
  </div>
代码语言:javascript复制
    * {
      margin: 0;
      padding: 0;
    }
    .wrap {
      width: 100vw;
      height: 100vh;
      display: flex;
      flex-direction: column;
    }
    .sky {
      height: 50%;
      background-image: linear-gradient(#000ea9, #101984);
    }
    .sea {
      height: 50%;
      background-image: linear-gradient(#0049b7, #00085f);
    }

接下来我们就要画月亮也很简单,直接画一个圆就行了,再加一个阴影就行了,升上来的动画再来一个animate就行,由于后面左边要放诗句,为了对称,所以要让月亮跑到右边,至于如何让月亮沿着弧线运动,我没研究,有大神的话可以指导一下,这里为了给海面加点生机,我们来个月亮的倒影。这里月亮从海里升出来的效果,我们使用overflow:hidden来完成。

月亮在海面上的倒影一般不会太清晰,所以我们这里使用opacity降低一下透明度,再使用filter: blur(10px)来一个高斯模糊。

代码语言:javascript复制
  <div class="wrap">
    <div class="sky" id="sky">
      <div class="sky_moon moon"></div>
    </div>
    <div class="sea">
      <div class="sea_moon moon"></div>
    </div>
  </div>
代码语言:javascript复制
.sky {
  height: 50%;
  background-image: linear-gradient(#000ea9, #101984);
  position: relative;
  overflow: hidden;
}
.sea {
  height: 50%;
  background-image: linear-gradient(#0049b7, #00085f);
  position: relative;
  overflow: hidden;
}
.moon {
  width: 200px;
  height: 200px;
  background: #f1eacb;
  box-shadow: 0 0 10px 5px rgba(255, 255, 255, .25);
  border-radius: 50%;
  position: absolute;
  left: 70%;
}
.sky_moon {
  top: 10%;
  animation: skymove ease-out 5s;
}
.sea_moon {
  bottom: 10%;
  opacity: .2;
  filter: blur(10px); 
  animation: seamove ease-out 5s;
}
@keyframes skymove {
  0% { top: 112%; left: 50% }
  100% { top: 10%; left: 70% }
}
@keyframes seamove {
  0% { bottom: 112%; left: 50% }
  100% { bottom: 10%; left: 70% }
}

这个完成之后,其实主要的功能已经实现了,但是画面还是太单调,我们可以给夜空加一些星星 添加星星的时候,我们给了一个随机的位置,之后又用animation动画给来了个一闪一闪的效果,但如果一起添加的话,所有的星星就会一起闪,效果不好,所以我们添加星星时候给了个定时器,随机给个1秒以内的延迟,这样闪烁就有间隔了,也更符合常理。

代码语言:javascript复制
.star {
  position: absolute;
  width: 3px;
  height: 3px;
  background: #f1eacb;
  animation: star infinite 2s;
}
@keyframes star {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
代码语言:javascript复制
  const sky = document.getElementById('sky')
  function addStar (length) {
    for (let index = 0; index < length; index  ) {
      setTimeout(function () {
        let star = document.createElement('div')
        star.className = 'star'
        let width = document.body.clientWidth
        let height = document.body.clientHeight / 2
        let left = Math.random() * width   'px'
        let top = Math.random() * height   'px'
        star.style.top = top
        star.style.left = left
        sky.append(star)
      }, Math.random() * 1000)
      
    }
  }
  addStar(10)

最后再加上我们的祝福语就大功告成了,这里我们设计的是在月亮动画结束后祝福语再出来,所以给动画延时时间加了5秒,由于gif录制时长问题,本来摄像的文字一个一个出来就没有做,直接整体出来。

代码语言:javascript复制
  <div class="sky" id="sky">
    <div class="sky_moon moon"></div>
    <div class="text-wrap">
      海上升明月,<br>
      天涯共此时,<br>
      祝掘金所有小伙伴中秋快乐
    </div>
  </div>
代码语言:javascript复制
    .text-wrap {
      margin: 10% 0 0 20%;
      color: #f1eacb;
      letter-spacing: 5px;
      font-size: 32px;
      opacity: 0;
      animation: text 2s 5s forwards;
    }
    @keyframes text {
      0% { opacity: 0; }
      100% { opacity: 1; }
    }

OK。到这里就全部完成啦

0 人点赞