童年回忆——萤火虫纷飞的夏夜

2,377 阅读3分钟

f42a4ce9c32876fd46a569fb5eacecf0.jpeg

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!

前言

作为一个在钢筋混凝土城市中的打工人,已经很久没有在夏天的夜晚,散步在乡村的小径上,体会丛林中漫天纷飞的萤火虫带来的流萤之美,只有珍藏在记忆中的童年时光,拥有这样美好的场景。

今天使用css3和js简单实现一个萤火虫纷飞的夏夜,给在城市中打拼的自己带来些许慰藉。

实现思路

  1. 首先找一张唯美的夏夜图片,平铺整个页面;再加一层黑色蒙层
.content {
  width: 100vw;
  height: 100vh;
  background: url('./images/glow-bg.jpg') no-repeat;
  background-position: center bottom;
  background-size: 100% 100%;
  overflow: hidden;
}
.content:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.4);
}
  1. 设置萤火虫的大小,并固定几个萤火虫。使用动画属性,把关键帧flicker周期持续4000ms,先快后慢,无限做颜色变换动画。关键帧开始、结束设置萤火虫颜色为深黄色;30%,70%设置萤火虫颜色为浅黄色,期间阴影也做相应变化,50%设置外阴影颜色为深黄色透明度为0.8的荧光色,实现萤火虫一闪一闪的发光效果
.beetle {
  width: 7px;
  height: 4px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.4);
  animation: flicker 4000ms ease infinite;
  position: relative;
  z-index: 88;
  top: 50%;
  left: 50%;
}

.beetle1 {
  top: 60%;
  left: 20%;
}

.beetle2 {
  top: 40%;
  left: 60%;
}

.beetle3 {
  top: 38%;
  left: 30%;
}

.beetle4 {
  top: 40%;
  left: 80%;
}

@keyframes flicker {

  0%,
  100% {
    background: #fefa01;
    box-shadow: 0 0 8px #fefa01, inset 0 0 0 0 rgba(14, 10, 10, 0.1);
  }

  30%,
  70% {
    background: #fffd99;
    box-shadow: 0 0 16px 8px #fefa01, inset 0 0 0 0 rgba(14, 10, 10, 0.1);
  }

  50% {
    box-shadow: 0 0 16px 8px rgba(254, 250, 1, 0.8), inset 0 0 0 0 rgba(14, 10, 10, 0.1);
  }
  1. 设置萤火虫向上飞舞的动画。首先萤火虫一开始隐藏,再出现向上飞,并可以向左或者向右飞一段距离,最后消失飞出界面
@keyframes fade {
  0% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

@keyframes up {
  0% {
    transform: translate(0px, 10vh);
  }

  100% {
    transform: translate(0px, -90vh);
  }
}

@keyframes clockwiseSpin {
  0% {
    transform: translate(0, 10vh) rotate(-50deg);
  }

  30% {
    transform: translate(100px, -10vh) rotate(0deg);
  }

  100% {
    transform: translate(0, -90vh) rotate(50deg);
  }
}

@keyframes counterclockwiseSpin {
  0% {
    transform: translate(0, 10vh) rotate(50deg);
  }

  30% {
    transform: translate(-100px, -10vh) rotate(0deg);
  }

  100% {
    transform: translate(50px, -90vh) rotate(-50deg);
  }
    }
  1. 设置一个固定的需要生成的萤火虫数量,循环该数量依次生成萤火虫元素,并追加到页面中,并动态加入萤火虫向上飞的动画,以及随机飞舞的时间。
const NUMBER_OF_LEAVES = 40;
function init() {
  let container = document.getElementById('leafContainer');
  for (let i = 0; i < NUMBER_OF_LEAVES; i++) {
    container.appendChild(createALeaf());
  }
}

//返回设置的随机整数
function randomInteger(low, high) {
  return low + Math.floor(Math.random() * (high - low));
}
//返回设置的随机浮点数
function randomFloat(low, high) {
  return low + Math.random() * (high - low);
}

function pixelValue(value) {
  return value + 'px';
}

function durationValue(value) {
  return value + 's';
}
function createALeaf() {
  // 创建萤火虫元素
  var leafDiv = document.createElement('div');
  leafDiv.className = 'beetle'
  // 萤火虫初始位置
  leafDiv.style.bottom = "100px";

  //萤火虫距页面左侧的距离
  leafDiv.style.left = pixelValue(randomInteger(0, 1500));

  // 随机得到正时针旋转并向右移动的动画、逆时针旋转并向左移动的动画;
  var spinAnimationName = (Math.random() < 0.5) ? 'clockwiseSpin' : 'counterclockwiseSpin';
  // 给生成的萤火虫元素添加动画
  leafDiv.style.animationName = 'flicker,fade, up,' + spinAnimationName;
  // 随机设置动画时间
  var fadeAndDropDuration = durationValue(randomFloat(5, 11));
  var leafDelay = durationValue(randomFloat(0, 5));
  leafDiv.style.animationDelay = leafDelay;
  leafDiv.style.animationDuration = fadeAndDropDuration;

  return leafDiv;
}

window.addEventListener('load', init);
  1. 增加一个夏天夜晚的虫鸣大合唱,并在打开页面自动播放,更能有种身临其境的感觉
<audio src="./music/music.mp3" loop="loop"  autoplay="autoplay" preload="auto" style="display: none;"></audio>

注:打开页面并不会自动播放音乐,但是把该页面加到一个主页面,跳转打开,就可以实现自动播放

展示效果

未标题-1.gif

后记

一开始为了有个线上的展示效果,在码上掘金中发布了代码,但是没有引入外部资源,效果不好看,就没有展示出来。

最近在逛codepen的时候,看到里面代码片段中的图片是引用的线上网址。因此把码上掘金中需要的外部资源都用线上网址替代了(ps:为了薅小黄鸭),具体效果如下:

展示地址