前言
昨天下班的时候无意间听到了以前经常听的歌 “一起去看流星雨”(暴露年龄了,哈哈),然后突发奇想的做了这个html设计;
最终展示图
第一步:流星雨背景
1.1 夜空
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%) }
1.2 html部分
<!-- 流星雨 --> <div id="stars"> <div class="star" style="top: 0px;left: 500px;"></div> </div>
1.3 流星
#stars { margin: 0 auto; width: 100vw; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 2; } .star { display: block; width: 1px; background: transparent; position: relative; opacity: 0; filter: drop-shadow(0 0 6px #ffffff); /*过渡动画*/ animation: star-fall 3.5s linear infinite; -webkit-animation: star-fall 3.5s linear infinite; -moz-animation: star-fall 3.5s linear infinite; } .star:after { content: ''; display: block; border: 0px solid #fff; border-width: 0px 90px 2px 90px; border-top-right-radius: 100%; border-bottom-right-radius: 100%; border-color: transparent transparent transparent rgba(255, 255, 255, .6); 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%; animation: star-fall-after 3.5s linear initial; -webkit-animation: star-fall-after 3.5s linear initial; -moz-animation: star-fall-after 3.5s linear initial; } @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(-300px, 300px, 0); -webkit-transform: translate3d(-300px, 300px, 0); -moz-transform: translate3d(-300px, 300px, 0); } 100% { opacity: 0; transform: scale(1.2) translate3d(-500px, 500px, 0); -webkit-transform: scale(1.2) translate3d(-500px, 500px, 0); -moz-transform: scale(1.2) translate3d(-500px, 500px, 0); } } @keyframes star-fall-after { 0% { border-width: 0px 80px 2px 80px; } 50% { border-width: 0px 90px 2px 90px; } 100% { border-width: 0px 45px 2px 45px; } }
1.4 js动态渲染多个流星并随机位置出现
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(300, -100) + "px"; newStar.style.left = randomDistance(1600, 300) + "px"; stars.appendChild(newStar); } // 封装随机数方法 function randomDistance(max, min) { var distance = Math.floor(Math.random() * (max - min + 1) + min); return distance; } 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"; }
效果图
第二步 弹幕
2.1 html部分
<!-- 弹幕层 --> <div class="barrage-wrapper"></div>
2.2 css部分
/* 弹幕的样式 */ .barrage-wrapper { width: 100%; height: 100%; position: relative; z-index: 10; } @keyframes barrage{ from{ left:100%; transform:translateX(0); } to{ left:0; transform:translateX(-100%); } } .block{ position:absolute; top: 50%; left: 100%; width: 100%; color: #fff; }
2.3 js部分获取弹幕内容并随机位置、速度进行展示
// 弹幕的内容 var barrages = [ "空降成功", "真香警告", "温馨提示,前方请调高音量/赶紧戴耳机", "弹幕护体!弹幕护体!弹幕护体!", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!", "前方高能", "我从未见过如此厚颜无耻之人", "完结撒花", "空降成功", "真香警告", "温馨提示,前方请调高音量/赶紧戴耳机", "弹幕护体!弹幕护体!弹幕护体!", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!", "前方高能", "我从未见过如此厚颜无耻之人", "完结撒花", "空降成功", "真香警告", "温馨提示,前方请调高音量/赶紧戴耳机", "弹幕护体!弹幕护体!弹幕护体!", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!", "前方高能", "我从未见过如此厚颜无耻之人", "完结撒花", "空降成功", "真香警告", "温馨提示,前方请调高音量/赶紧戴耳机", "弹幕护体!弹幕护体!弹幕护体!", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!", "前方高能", "我从未见过如此厚颜无耻之人", "完结撒花", "空降成功", "真香警告", "温馨提示,前方请调高音量/赶紧戴耳机", "弹幕护体!弹幕护体!弹幕护体!", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!", "前方高能", "我从未见过如此厚颜无耻之人", "完结撒花", "空降成功", "真香警告", "温馨提示,前方请调高音量/赶紧戴耳机", "弹幕护体!弹幕护体!弹幕护体!", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!", "前方高能", "我从未见过如此厚颜无耻之人", "完结撒花", "空降成功", "真香警告", "温馨提示,前方请调高音量/赶紧戴耳机", "弹幕护体!弹幕护体!弹幕护体!", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!", "前方高能", "我从未见过如此厚颜无耻之人", "完结撒花", "刘思琪,也许我们再也遇不到了,但是我还是想说,我喜欢你!" ]; const wrapper = document.querySelector(".barrage-wrapper"); for (const item of barrages) { const block = document.createElement("div"); block.classList.add("block"); block.style.top = randomDistance(700,-50) + "px"; // 弹幕的位置不能超过容器的高度 block.style.animation = `barrage ${randomDistance(50,0)}s linear ${randomDistance(60,0)}s`; // 随机动画效果 block.textContent = item; wrapper.appendChild(block); }
随机的方法调用的是上面流星雨中封装的随机方法
效果图
第三步 背景音乐+背景图片+点击展示星星
3.1 背景音乐
<!-- 背景音乐 --> <audio src="mp3/张翰魏晨朱梓骁俞灏明 - 让我为你唱首歌.mp3" autoplay loop></audio>
3.2 背景图片
#stars { margin: 0 auto; width: 100vw; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 2; background-image: url("https://tse2-mm.cn.bing.net/th/id/OIP.hutsmUcFnqB-8AKGKSoOEgHaL2?pid=Api&rs=1"); background-size: contain; background-repeat: no-repeat; background-position: 50% 50%; }
3.3 点击出现星星
这个就和我上篇文章讲的方法是一样的,都是监听鼠标全局点击或移动事件,获取位置相关信息来展示动画效果
3.3.1 css部分
/* 鼠标点击的星星 */ .star-five{ position: fixed; display: block; color: #fff; width: 0px; height: 0px; border-right: 10px solid transparent; border-bottom: 7px solid #fff; border-left: 10px solid transparent; transform:rotate(35deg); filter: drop-shadow(0 0 6px #ffffff); } .star-five:before { border-bottom: 8px solid #fff; border-left: 3px solid transparent; border-right: 3px solid transparent; position: absolute; height: 0; width: 0; top: -4.5px; left: -6.5px; display: block; content: ''; transform: rotate(-35deg); } .star-five:after { position: absolute; display: block; color: #fff; top: .3px; left: -10.5px; width: 0px; height: 0px; border-right: 10px solid transparent; border-bottom: 7px solid #fff; border-left: 10px solid transparent; transform: rotate(-70deg); content: ''; }
3.3.2 js部分
let meteor = []; gameloop(); window.onclick = function (event) { createMeteor(event); }; // 创建星星 function createMeteor(event) { let span = document.createElement("span"); span.className = "star-five"; meteor.push({ el: span, x: event.clientX - 5, y: event.clientY - 5, scale: 1, alpha: 1, }); document.body.appendChild(span); } function gameloop() { for (var i = 0; i < meteor.length; i++) { if (meteor[i].alpha <= 0) { document.body.removeChild(meteor[i].el); meteor.splice(i, 1); continue; } // meteor[i].y--; meteor[i].scale += 0.04; meteor[i].alpha -= 0.013; meteor[i].el.style.cssText = "left:" + meteor[i].x + "px;top:" + meteor[i].y + "px;opacity:" + meteor[i].alpha + ";transform:scale(" + meteor[i].scale + "," + meteor[i].scale + ");"; } requestAnimationFrame(gameloop); }
效果图
总结
动画在明白思路之后实现起来都不难,本身我想像音乐播放器那样加上歌词字幕效果,不过音乐网有防爬虫,处理起来有些麻烦,所以下次有机会再做咯,需要源代码的小伙伴可以到这里下载: https://github.com/13632756286/meteor