vue实现歌词滚动效果

avatar
作者
猴君
阅读量:0

1.结构

<template>     <div class="lyricScroll">         <div class="audio">             <audio id="audio" src="./common/周传雄-青花1.mp3" controls></audio>         </div>         <div class="container" id="container">             <ul id="ul">                 <li v-for="item in dataArr" :key="item.time">                     {{ item.word }}                 </li>             </ul>         </div>     </div> </template> <script> import {data} from "./common/data"; export default {     name: 'lyricScroll',     data() {         return {             dataArr: [],             doms: {}         }     },     mounted(){         this.parseLrc()         this.getDoms()         this.audioTimeUpdata()     },     methods:{         /**          * 获取dom          */         getDoms(){             this.doms['audio'] = document.getElementById("audio")             this.doms['container'] = document.getElementById("container")             this.doms['ul'] = document.getElementById("ul")         },         /**          * 将字符串转为对象数组[{ time: 0, word: 'x' }]          */         parseLrc(){             let lines = data.split('\n');             this.dataArr = lines.map(item => {                 return {                     time: this.parseTime(item.split(']')[0].split("[")[1]),                     word: item.split(']')[1]                 }             })         },         /**          * 将时间字符串转为数字(秒)          * @param {String} timeStr 时间字符串          * @param {Number} offset 设置时间偏移          */         parseTime(timeStr, offset = 0.5){             let parts = timeStr.split(":");             return +parts[0] * 60 + +parts[1] - offset         },         /**          * 计算出,在当前播放器播放到第几秒的情况下,应该高亮的歌词下标          */         findIndex(){             let curTime = this.doms.audio.currentTime;             let nowIndex = this.dataArr.findIndex(item => {                 return item.time > curTime             })             return nowIndex != -1 ? nowIndex - 1 : this.dataArr.length - 1         },         /**          * 设置ul的偏移量          */         setOffset(){             let { ul, container } = this.doms             let liHieght = ul.children[0].clientHeight             let containerHeight = container.clientHeight             let ulHeight = ul.clientHeight             let index = this.findIndex();             let oldLi = ul.querySelector('.active')             if(oldLi){                 oldLi.classList.remove('active')             }             let offset = liHieght * index + liHieght / 2 - containerHeight / 2             let resultOffset = offset < 0 ? 0 : (offset > ulHeight ? ulHeight : offset)             ul.style.transform = `translateY(${-resultOffset}px)`             ul.children[index].classList.add('active')         },         /**          * 给audio监听时间轴改变事件          */         audioTimeUpdata(){             let { audio } = this.doms             audio.addEventListener('timeupdate', this.setOffset)         }     } }; </script>  <style lang="less" scoped> * {     margin: 0;     padding: 0; }  .lyricScroll {     width: 100%;     height: 100%;     background: black;     display: flex;     flex-direction: column;     align-content: center;      .audio{         audio{             width: 400px;             margin: 0 auto;             display: block;         }     }      .container {         flex: 1;         overflow: hidden;          ul {             transition: 0.6s;             li {                 height: 50px;                 line-height: 50px;                 transition: 0.3s;                 text-align: center;                 font-size: 30px;                 &.active{                     color: #fff;                     font-size: 40px;                 }             }         }      } }</style>

2.效果

歌词滚动效果

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!