<template>
<div class="live-across-sub" id="animate">
<button @click="addFun">测试+1</button>
<div class="animate-slide">
<div
class="animate-slide__li"
v-for="item in moveList"
:key="item"
:id="item.id"
:class="item.classRank"
>
<div class="animate-slide__li--avatar">
<img :src="avatar" />
</div>
<div class="animate-slide__li--content">
<span :style="{ color: nameColor }" class="name">{{ name }}</span>
<span class="text">{{ text }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
avatar: {
type: String,
default:
'https://img10.360buyimg.com/ling/jfs/t1/181258/24/10385/53029/60d04978Ef21f2d42/92baeb21f907cd24.jpg'
},
name: {
type: String,
default: '小张'
},
nameColor: {
type: String,
default: '#ffa95a'
},
text: {
type: String,
default: '进入直播间'
}
})
let moveList = ref([])
const data = reactive({
num: 0,
waitList: [],
delList: [],
classList: ['frist', 'two', 'three'],
classCurr: computed(() => {
let getListval = Array.from(moveList.value, ({ classRank }) => classRank)
if (getListval.indexOf(data.classList[0]) === -1) {
return data.classList[0]
}
if (getListval.indexOf(data.classList[1]) === -1) {
return data.classList[1]
}
if (getListval.indexOf(data.classList[2]) === -1) {
return data.classList[2]
}
})
})
const addFun = () => {
data.num++
if (moveList.value.length < 3) {
let obj = {
id: data.num,
classRank: data.classCurr
}
moveList.value.push(obj)
} else {
data.waitList.push(data.num)
}
}
const addWait = () => {
if (data.waitList.length > 0) {
let obj = {
id: data.waitList[0],
classRank: data.classCurr
}
moveList.value.push(obj)
data.waitList = data.waitList.slice(1)
}
}
function listenerFun(e) {
// console.log('e:', e)
if (moveList.value.length > 0) {
if (data.delList.indexOf(e.target.id) > -1) {
moveList.value = moveList.value.filter(ele => ele.id != e.target.id)
return
}
setTimeout(() => {
let getDom = document.getElementById(e.target.id)
getDom.className = getDom.className + ' out'
data.delList.push(e.target.id)
}, 1500)
}
}
onMounted(() => {
document.addEventListener('animationend', listenerFun, false)
})
onBeforeUnmount(() => {
document.removeEventListener('animationend', listenerFun, false)
})
watch(
() => moveList,
(newVal, oldVal) => {
if (newVal.length < 3 && data.waitList.length > 0) {
addWait()
}
},
{ deep: true }
)
</script>
<style lang="scss" scoped>
.live-across-sub {
position: absolute;
top: 0;
left: 0;
right: 0;
}
.animate-slide {
display: flex;
flex-direction: column;
position: absolute;
top: 26px;
left: 0;
right: 0;
min-height: 128px;
&__li {
border-radius: 20px;
background-color: #fff;
display: flex;
flex-wrap: nowrap;
position: absolute;
animation: moveIn 3s linear;
&--avatar {
display: inline-block;
width: 36px;
height: 36px;
border-radius: 50%;
overflow: hidden;
vertical-align: middle;
margin-right: 10px;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
&--content {
margin-right: 12px;
line-height: 36px;
font-size: 14px;
color: #000;
white-space: nowrap;
.name {
margin-right: 5px;
}
}
}
.out {
animation: moveOut 2s linear;
}
.frist {
top: 0;
}
.two {
top: 51px;
}
.three {
top: 102px;
}
@keyframes moveIn {
from {
left: 100%;
}
to {
left: 0;
}
}
@keyframes moveOut {
0% {
opacity: 1;
transform: translateX(-9px);
}
50% {
opacity: 1;
transform: translateX(9px);
}
/* 50% {
opacity: 1;
transform: translateX(0);
} */
100% {
opacity: 0;
transform: translateX(-100%);
}
}
}
</style>