This commit is contained in:
2025-12-08 16:38:47 +08:00
parent d12f04c7aa
commit dad278fe15

View File

@@ -64,9 +64,11 @@ const enabled = ref(true)
const danmakuWrapper = ref(null)
const activeDanmakus = ref([])
const danmakuQueue = ref([])
const pendingQueue = ref([]) // 待处理的弹幕队列
const lastFetchTime = ref(null)
const fetchTimer = ref(null)
const processedIds = ref(new Set()) // 已处理的记录ID避免重复显示
const isProcessing = ref(false) // 是否正在处理弹幕
// 计算时间差(多少分钟前)
const calculateTimeAgo = (timeStr) => {
@@ -132,11 +134,14 @@ const fetchLatestApiCalls = async () => {
return true
})
// 将新记录添加到队列
// 将新记录添加到待处理队列
newItems.forEach(item => {
addDanmakuToQueue(item)
addToPendingQueue(item)
})
// 开始处理队列
processPendingQueue()
lastFetchTime.value = new Date()
}
} catch (error) {
@@ -144,7 +149,45 @@ const fetchLatestApiCalls = async () => {
}
}
// 添加弹幕到队列
// 添加到待处理队列
const addToPendingQueue = (item) => {
pendingQueue.value.push(item)
// 如果队列太长,移除最旧的
if (pendingQueue.value.length > props.maxDanmakus * 2) {
pendingQueue.value.shift()
}
}
// 处理待处理队列每次弹幕间隔1.5秒+随机0-2秒
const processPendingQueue = () => {
if (isProcessing.value || pendingQueue.value.length === 0) {
return
}
isProcessing.value = true
const processNext = () => {
if (pendingQueue.value.length === 0) {
isProcessing.value = false
return
}
const item = pendingQueue.value.shift()
addDanmakuToQueue(item)
// 计算下一个弹幕的延迟1.5秒 + 0-2秒随机
const delay = 1500 + Math.random() * 2000
setTimeout(() => {
processNext()
}, delay)
}
processNext()
}
// 添加弹幕到显示队列
const addDanmakuToQueue = (item) => {
const danmaku = {
id: item.id || `danmaku-${Date.now()}-${Math.random()}`,
@@ -155,14 +198,12 @@ const addDanmakuToQueue = (item) => {
startAt: item.start_at || item.created_at,
timeAgo: calculateTimeAgo(item.start_at || item.created_at),
top: 0,
duration: 0, // 将在添加到DOM后计算
duration: props.danmakuSpeed,
delay: 0
}
// 计算垂直位置(随机分散,避免重叠)
danmaku.top = calculateTopPosition()
// 增加随机延迟让弹幕错开时间出现0-2000ms
danmaku.delay = Math.random() * 2000
danmakuQueue.value.push(danmaku)
@@ -171,15 +212,9 @@ const addDanmakuToQueue = (item) => {
danmakuQueue.value.shift()
}
// 延迟添加弹幕,让它们错开时间出现
setTimeout(() => {
// 使用固定的动画时间,确保弹幕完全移出左侧
// translateX(-200%) 意味着向左移动自身宽度的200%,应该足够移出容器
danmaku.duration = props.danmakuSpeed
activeDanmakus.value.push(danmaku)
// 弹幕会在动画结束时通过 animationend 事件自动移除
}, danmaku.delay)
// 立即添加到活动弹幕列表
activeDanmakus.value.push(danmaku)
// 弹幕会在动画结束时通过 animationend 事件自动移除
}
// 处理动画结束事件