fix(弹幕组件): 修复低端机弹幕突然消失的问题
This commit is contained in:
parent
0bb4b13586
commit
54e09023f0
@ -1,6 +1,10 @@
|
||||
<!-- Barrage.vue 优化版 -->
|
||||
<template>
|
||||
<div ref="containerRef" class="barrage-root" :class="{ 'barrage-lite': liteAnimations }">
|
||||
<div
|
||||
ref="containerRef"
|
||||
class="barrage-root"
|
||||
:class="{ 'barrage-lite': liteAnimations, 'barrage-paused': isBarragePaused }"
|
||||
>
|
||||
<div
|
||||
v-for="(track, index) in visibleTracks"
|
||||
:key="index"
|
||||
@ -87,6 +91,7 @@ const tracks = ref([[], []])
|
||||
const containerRef = ref(null)
|
||||
const idCounter = ref(0)
|
||||
const currentIndex = ref(0)
|
||||
const isBarragePaused = ref(false)
|
||||
const liteAnimations = shouldUseLiteAnimations()
|
||||
const visibleTracks = computed(() => tracks.value.filter((track) => track.length > 0))
|
||||
const effectiveMaxItems = computed(() => (liteAnimations ? Math.min(props.maxItems, 1) : props.maxItems))
|
||||
@ -186,7 +191,7 @@ function getNextBarrage() {
|
||||
}
|
||||
|
||||
function canRunBarrage() {
|
||||
return isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
return !isBarragePaused.value && isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
}
|
||||
|
||||
function stopBarrage(clearTracks = false) {
|
||||
@ -218,9 +223,24 @@ function restartBarrage(clearTracks = false) {
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function pauseBarrage(clearTracks = false) {
|
||||
isBarragePaused.value = true
|
||||
stopBarrage(clearTracks)
|
||||
}
|
||||
|
||||
function resumeBarrage() {
|
||||
isBarragePaused.value = false
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
isPageVisible = !document.hidden
|
||||
restartBarrage(true)
|
||||
if (isPageVisible && isInViewport) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
}
|
||||
|
||||
function setupViewportObserver() {
|
||||
@ -231,7 +251,12 @@ function setupViewportObserver() {
|
||||
viewportObserver = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
isInViewport = entry?.isIntersecting !== false
|
||||
restartBarrage(true)
|
||||
if (isInViewport && isPageVisible) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
},
|
||||
{ rootMargin: '80px 0px', threshold: 0 },
|
||||
)
|
||||
@ -262,7 +287,12 @@ watch(
|
||||
[() => props.barrageList, () => locale.value],
|
||||
() => {
|
||||
currentIndex.value = 0
|
||||
restartBarrage(true)
|
||||
if (props.barrageList.length === 0) {
|
||||
stopBarrage(true)
|
||||
return
|
||||
}
|
||||
|
||||
restartBarrage(false)
|
||||
},
|
||||
{ deep: false },
|
||||
)
|
||||
@ -300,6 +330,10 @@ watch(
|
||||
will-change: auto;
|
||||
}
|
||||
|
||||
.barrage-paused .barrage-item {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
.barrage-avatar {
|
||||
width: 10vw;
|
||||
border-radius: 50%;
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
<!-- Barrage.vue 优化版 -->
|
||||
<template>
|
||||
<div ref="containerRef" class="barrage-root" :class="{ 'barrage-lite': liteAnimations }">
|
||||
<div
|
||||
ref="containerRef"
|
||||
class="barrage-root"
|
||||
:class="{ 'barrage-lite': liteAnimations, 'barrage-paused': isBarragePaused }"
|
||||
>
|
||||
<div
|
||||
v-for="(track, index) in visibleTracks"
|
||||
:key="index"
|
||||
@ -92,6 +96,7 @@ const tracks = ref([[], []])
|
||||
const containerRef = ref(null)
|
||||
const idCounter = ref(0)
|
||||
const currentIndex = ref(0)
|
||||
const isBarragePaused = ref(false)
|
||||
const liteAnimations = shouldUseLiteAnimations()
|
||||
const visibleTracks = computed(() => tracks.value.filter((track) => track.length > 0))
|
||||
const effectiveMaxItems = computed(() => (liteAnimations ? Math.min(props.maxItems, 1) : props.maxItems))
|
||||
@ -182,7 +187,7 @@ function getNextBarrage() {
|
||||
}
|
||||
|
||||
function canRunBarrage() {
|
||||
return isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
return !isBarragePaused.value && isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
}
|
||||
|
||||
function stopBarrage(clearTracks = false) {
|
||||
@ -214,9 +219,24 @@ function restartBarrage(clearTracks = false) {
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function pauseBarrage(clearTracks = false) {
|
||||
isBarragePaused.value = true
|
||||
stopBarrage(clearTracks)
|
||||
}
|
||||
|
||||
function resumeBarrage() {
|
||||
isBarragePaused.value = false
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
isPageVisible = !document.hidden
|
||||
restartBarrage(true)
|
||||
if (isPageVisible && isInViewport) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
}
|
||||
|
||||
function setupViewportObserver() {
|
||||
@ -227,7 +247,12 @@ function setupViewportObserver() {
|
||||
viewportObserver = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
isInViewport = entry?.isIntersecting !== false
|
||||
restartBarrage(true)
|
||||
if (isInViewport && isPageVisible) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
},
|
||||
{ rootMargin: '80px 0px', threshold: 0 },
|
||||
)
|
||||
@ -258,7 +283,12 @@ watch(
|
||||
[() => props.barrageList, () => locale.value],
|
||||
() => {
|
||||
currentIndex.value = 0
|
||||
restartBarrage(true)
|
||||
if (props.barrageList.length === 0) {
|
||||
stopBarrage(true)
|
||||
return
|
||||
}
|
||||
|
||||
restartBarrage(false)
|
||||
},
|
||||
{ deep: false },
|
||||
)
|
||||
@ -296,6 +326,10 @@ watch(
|
||||
will-change: auto;
|
||||
}
|
||||
|
||||
.barrage-paused .barrage-item {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
.barrage-avatar {
|
||||
width: 10vw;
|
||||
border-radius: 50%;
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
<!-- Barrage.vue 优化版 -->
|
||||
<template>
|
||||
<div ref="containerRef" class="barrage-root" :class="{ 'barrage-lite': liteAnimations }">
|
||||
<div
|
||||
ref="containerRef"
|
||||
class="barrage-root"
|
||||
:class="{ 'barrage-lite': liteAnimations, 'barrage-paused': isBarragePaused }"
|
||||
>
|
||||
<div
|
||||
v-for="(track, index) in visibleTracks"
|
||||
:key="index"
|
||||
@ -92,6 +96,7 @@ const tracks = ref([[], []])
|
||||
const containerRef = ref(null)
|
||||
const idCounter = ref(0)
|
||||
const currentIndex = ref(0)
|
||||
const isBarragePaused = ref(false)
|
||||
const liteAnimations = shouldUseLiteAnimations()
|
||||
const visibleTracks = computed(() => tracks.value.filter((track) => track.length > 0))
|
||||
const effectiveMaxItems = computed(() => (liteAnimations ? Math.min(props.maxItems, 1) : props.maxItems))
|
||||
@ -182,7 +187,7 @@ function getNextBarrage() {
|
||||
}
|
||||
|
||||
function canRunBarrage() {
|
||||
return isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
return !isBarragePaused.value && isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
}
|
||||
|
||||
function stopBarrage(clearTracks = false) {
|
||||
@ -214,9 +219,24 @@ function restartBarrage(clearTracks = false) {
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function pauseBarrage(clearTracks = false) {
|
||||
isBarragePaused.value = true
|
||||
stopBarrage(clearTracks)
|
||||
}
|
||||
|
||||
function resumeBarrage() {
|
||||
isBarragePaused.value = false
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
isPageVisible = !document.hidden
|
||||
restartBarrage(true)
|
||||
if (isPageVisible && isInViewport) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
}
|
||||
|
||||
function setupViewportObserver() {
|
||||
@ -227,7 +247,12 @@ function setupViewportObserver() {
|
||||
viewportObserver = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
isInViewport = entry?.isIntersecting !== false
|
||||
restartBarrage(true)
|
||||
if (isInViewport && isPageVisible) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
},
|
||||
{ rootMargin: '80px 0px', threshold: 0 },
|
||||
)
|
||||
@ -258,7 +283,12 @@ watch(
|
||||
[() => props.barrageList, () => locale.value],
|
||||
() => {
|
||||
currentIndex.value = 0
|
||||
restartBarrage(true)
|
||||
if (props.barrageList.length === 0) {
|
||||
stopBarrage(true)
|
||||
return
|
||||
}
|
||||
|
||||
restartBarrage(false)
|
||||
},
|
||||
{ deep: false },
|
||||
)
|
||||
@ -296,6 +326,10 @@ watch(
|
||||
will-change: auto;
|
||||
}
|
||||
|
||||
.barrage-paused .barrage-item {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
.barrage-avatar {
|
||||
width: 10vw;
|
||||
border-radius: 50%;
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
<!-- 告白墙弹幕 -->
|
||||
<template>
|
||||
<div ref="containerRef" class="barrage-root" :class="{ 'barrage-lite': liteAnimations }">
|
||||
<div
|
||||
ref="containerRef"
|
||||
class="barrage-root"
|
||||
:class="{ 'barrage-lite': liteAnimations, 'barrage-paused': isBarragePaused }"
|
||||
>
|
||||
<div
|
||||
v-for="(track, index) in visibleTracks"
|
||||
:key="index"
|
||||
@ -127,6 +131,7 @@ const tracks = ref([[], []])
|
||||
const containerRef = ref(null)
|
||||
const idCounter = ref(0)
|
||||
const currentIndex = ref(0)
|
||||
const isBarragePaused = ref(false)
|
||||
const liteAnimations = shouldUseLiteAnimations()
|
||||
const visibleTracks = computed(() => tracks.value.filter((track) => track.length > 0))
|
||||
const effectiveMaxItems = computed(() => (liteAnimations ? Math.min(props.maxItems, 1) : props.maxItems))
|
||||
@ -204,7 +209,7 @@ function getNextBarrage() {
|
||||
}
|
||||
|
||||
function canRunBarrage() {
|
||||
return isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
return !isBarragePaused.value && isPageVisible && isInViewport && props.barrageList.length > 0
|
||||
}
|
||||
|
||||
function stopBarrage(clearTracks = false) {
|
||||
@ -236,9 +241,24 @@ function restartBarrage(clearTracks = false) {
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function pauseBarrage(clearTracks = false) {
|
||||
isBarragePaused.value = true
|
||||
stopBarrage(clearTracks)
|
||||
}
|
||||
|
||||
function resumeBarrage() {
|
||||
isBarragePaused.value = false
|
||||
startBarrage()
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
isPageVisible = !document.hidden
|
||||
restartBarrage(true)
|
||||
if (isPageVisible && isInViewport) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
}
|
||||
|
||||
function setupViewportObserver() {
|
||||
@ -249,7 +269,12 @@ function setupViewportObserver() {
|
||||
viewportObserver = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
isInViewport = entry?.isIntersecting !== false
|
||||
restartBarrage(true)
|
||||
if (isInViewport && isPageVisible) {
|
||||
resumeBarrage()
|
||||
return
|
||||
}
|
||||
|
||||
pauseBarrage(false)
|
||||
},
|
||||
{ rootMargin: '80px 0px', threshold: 0 },
|
||||
)
|
||||
@ -280,7 +305,12 @@ watch(
|
||||
() => props.barrageList,
|
||||
() => {
|
||||
currentIndex.value = 0
|
||||
restartBarrage(true)
|
||||
if (props.barrageList.length === 0) {
|
||||
stopBarrage(true)
|
||||
return
|
||||
}
|
||||
|
||||
restartBarrage(false)
|
||||
},
|
||||
{ deep: false },
|
||||
)
|
||||
@ -324,6 +354,10 @@ watch(
|
||||
will-change: auto;
|
||||
}
|
||||
|
||||
.barrage-paused .barrage-item {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
.avatar-pair {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user