vue2做的弹幕效果
2022-06-24 本文已影响0人
IamaStupid
vue2做的弹幕效果
image.png<template>
<div class="view-content home">
<button @click="toggleDanmuAnimate">stop</button>
<div class="danmu-box">
<template v-for="(item, i) in danmuList">
<div class="danmu-item" :key="'dm' + i" :style="{'left': item.left + 'px', top: item.top + 'px'}">{{item.text}}</div>
</template>
</div>
</div>
</template>
<script>
let originData = []
let reqFrame = null
export default {
name: "home-view",
data: function () {
return {
btnToggle: false,
winSize: null,
addIndex: -1,
danmuList: [],
danmuBoxHeight: 0,
danmuSpeed: 1,
turnTime: 0,
addOnceNum: 3
};
},
created() {
this.getWinInfo()
this.danmuBoxHeight = 410 * this.winSize.rem / 100
this.ajax()
},
methods:{
getWinInfo() {
let win = {
w: window.innerWidth, h: window.innerHeight, rem: 0
}
let doc = document.documentElement.style.fontSize.replace('px', '') - 0
if (doc > 0) {
win.rem = doc
}
this.winSize = win
},
ajax() {
setTimeout(() => {
let data = [
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
{text: '1111111111111111'},
{text: 'tttttttt'},
]
originData = data
this.animateRequest()
}, 2000)
},
isOutDanmu(item) {
return item.left <= (this.winSize.w * -1)
},
animateRequest() {
let tempArr = []
let addNum = Math.floor(Math.random() * this.addOnceNum)
if (this.addIndex === -1) {
// 第一次 如果随机添加的数量是0,强制添加1个
this.turnTime = 110
if (addNum < 1) {
addNum = 1
}
}
// console.log('addNum:', addNum)
if (addNum > 0 && this.turnTime > 100) {
tempArr = originData.slice(this.addIndex + 1, this.addIndex + 1 + addNum)
this.addIndex = this.addIndex + addNum
this.turnTime = 0
}
tempArr = [].concat(this.danmuList, tempArr)
tempArr.forEach((item, i) => {
if(item.top === undefined || this.isOutDanmu(item)) {
if (i === 0) {
item.top = Math.floor(this.danmuBoxHeight / 2 - 50)
} else {
item.top = Math.floor(Math.random() * (this.danmuBoxHeight - 30))
// 为防止弹幕重合
if (Math.abs(item.top - tempArr[i - 1].top) < 25) {
// 有可能重合了
if (item.top > tempArr[i - 1].top) {
// 两个60 25没有特殊联系,估摸着写的, 主要是为了不让弹幕的位置太靠下
if (item.top > (this.danmuBoxHeight - 60)) {
item.top = item.top - 60
} else {
item.top = item.top + 25
}
} else {
item.top = item.top - 25
}
}
}
if (item.top < 0) {
item.top = 0
}
}
if(item.left === undefined || this.isOutDanmu(item)) {
item.left = Math.floor(this.winSize.w * 1.1)
} else {
item.left -= this.danmuSpeed
if (this.isOutDanmu(item)) {
tempArr.splice(i, 1)
}
}
})
this.danmuList = tempArr
this.turnTime++
if (tempArr.length === 0) {
this.addIndex = -1
}
reqFrame = window.requestAnimationFrame(this.animateRequest)
// test code
// if (this.addIndex < 50) {
// window.requestAnimationFrame(this.animateRequest)
// }
},
toggleDanmuAnimate() {
this.btnToggle = !this.btnToggle
if (this.btnToggle) {
window.cancelAnimationFrame(reqFrame);
reqFrame = null
} else {
reqFrame = window.requestAnimationFrame(this.animateRequest)
}
}
}
};
</script>
<style lang="less" scoped>
.danmu-box {
width: 100%; height: 410px; position: absolute; left: 0; top: 266px; overflow: hidden; background: #f00;
.danmu-item {
display: inline-block; padding: 3px 8px; border-radius: 6px; background-color: rgba(0, 0, 0, 0.5);
position: absolute; left: 110%; color: #fff;
}
}
</style>