hookehuyr

feat(弹幕组件): 优化弹幕循环逻辑和持续性

增强弹幕组件的循环逻辑,确保在没有数据时自动重新获取
调整弹幕轨道数量和容器高度以优化显示效果
...@@ -387,7 +387,7 @@ const startDanmuAnimation = (danmu, track) => { ...@@ -387,7 +387,7 @@ const startDanmuAnimation = (danmu, track) => {
387 animationTimers.value.set(danmu.id, timer) 387 animationTimers.value.set(danmu.id, timer)
388 } 388 }
389 389
390 -// 重置弹幕位置实现循环 390 +// 重置弹幕位置实现循环 - 增强持续性
391 const resetDanmuForLoop = (danmu, track) => { 391 const resetDanmuForLoop = (danmu, track) => {
392 if (!isPlaying.value) return 392 if (!isPlaying.value) return
393 393
...@@ -395,10 +395,20 @@ const resetDanmuForLoop = (danmu, track) => { ...@@ -395,10 +395,20 @@ const resetDanmuForLoop = (danmu, track) => {
395 danmu.isMoving = false 395 danmu.isMoving = false
396 danmu.opacity = 1 396 danmu.opacity = 1
397 397
398 - // 切换下一条数据,遵循首轮不重复规则 398 + // 切换下一条数据,确保持续循环
399 const nextData = getNextUnusedDanmu() 399 const nextData = getNextUnusedDanmu()
400 if (nextData) { 400 if (nextData) {
401 danmu.data = nextData 401 danmu.data = nextData
402 + } else {
403 + // 如果没有数据,重新获取弹幕数据
404 + console.log('弹幕数据不足,尝试重新获取')
405 + fetchDanmuData().then(() => {
406 + const retryData = getNextUnusedDanmu()
407 + if (retryData) {
408 + danmu.data = retryData
409 + }
410 + })
411 + return
402 } 412 }
403 413
404 // 复位到右侧并重新计时 414 // 复位到右侧并重新计时
...@@ -407,7 +417,11 @@ const resetDanmuForLoop = (danmu, track) => { ...@@ -407,7 +417,11 @@ const resetDanmuForLoop = (danmu, track) => {
407 track.lastDanmuTime = Date.now() 417 track.lastDanmuTime = Date.now()
408 418
409 // 重新启动动画(无缝继续) 419 // 重新启动动画(无缝继续)
410 - nextTick(() => { 420 + nextTick(async () => {
421 + // 重新测量宽度,确保准确性
422 + await measureDanmuWidth(danmu)
423 + recalculateDuration(danmu)
424 + danmu.startTime = Date.now()
411 startDanmuAnimation(danmu, track) 425 startDanmuAnimation(danmu, track)
412 }) 426 })
413 } 427 }
...@@ -441,7 +455,7 @@ const resetDanmuIndex = () => { ...@@ -441,7 +455,7 @@ const resetDanmuIndex = () => {
441 isFirstRound = true 455 isFirstRound = true
442 } 456 }
443 457
444 -// 获取下一个未使用的弹幕数据 458 +// 获取下一个弹幕数据 - 优化循环逻辑
445 const getNextUnusedDanmu = () => { 459 const getNextUnusedDanmu = () => {
446 if (!familyDanmus.value || familyDanmus.value.length === 0) { 460 if (!familyDanmus.value || familyDanmus.value.length === 0) {
447 return null 461 return null
...@@ -462,20 +476,17 @@ const getNextUnusedDanmu = () => { ...@@ -462,20 +476,17 @@ const getNextUnusedDanmu = () => {
462 currentDanmuIndex++ 476 currentDanmuIndex++
463 } 477 }
464 478
465 - // 第一轮遍历完成 479 + // 第一轮遍历完成,开始无限循环
466 isFirstRound = false 480 isFirstRound = false
467 currentDanmuIndex = 0 481 currentDanmuIndex = 0
468 usedDanmuIds.clear() 482 usedDanmuIds.clear()
483 + console.log('弹幕第一轮完成,开始无限循环')
469 } 484 }
470 485
471 - // 第一轮遍历完成后,重新开始循环 486 + // 无限循环模式 - 确保永远有弹幕
472 - if (!isFirstRound) {
473 const danmuData = familyDanmus.value[currentDanmuIndex % familyDanmus.value.length] 487 const danmuData = familyDanmus.value[currentDanmuIndex % familyDanmus.value.length]
474 - currentDanmuIndex++ 488 + currentDanmuIndex = (currentDanmuIndex + 1) % familyDanmus.value.length
475 return danmuData 489 return danmuData
476 - }
477 -
478 - return null
479 } 490 }
480 491
481 // 发送顺序弹幕 492 // 发送顺序弹幕
...@@ -488,7 +499,7 @@ const sendSequentialDanmu = () => { ...@@ -488,7 +499,7 @@ const sendSequentialDanmu = () => {
488 } 499 }
489 } 500 }
490 501
491 -// 自动发送弹幕 502 +// 自动发送弹幕 - 增强持续性
492 let autoSendTimer = null 503 let autoSendTimer = null
493 const startAutoSend = () => { 504 const startAutoSend = () => {
494 if (autoSendTimer) return 505 if (autoSendTimer) return
...@@ -510,8 +521,11 @@ const startAutoSend = () => { ...@@ -510,8 +521,11 @@ const startAutoSend = () => {
510 const intervalMultiplier = Math.max(1, (6 - availableTrackCount) * 0.2) // 减少间隔倍数 521 const intervalMultiplier = Math.max(1, (6 - availableTrackCount) * 0.2) // 减少间隔倍数
511 const dynamicInterval = baseInterval * intervalMultiplier + Math.random() * 300 522 const dynamicInterval = baseInterval * intervalMultiplier + Math.random() * 300
512 523
524 + // 确保持续循环,即使暂时没有可用轨道也要继续尝试
525 + if (isPlaying.value) {
513 autoSendTimer = setTimeout(sendNext, dynamicInterval) 526 autoSendTimer = setTimeout(sendNext, dynamicInterval)
514 } 527 }
528 + }
515 529
516 // 立即发送第一条弹幕,不等待 530 // 立即发送第一条弹幕,不等待
517 sendNext() 531 sendNext()
......
1 <!-- 1 <!--
2 * @Date: 2025-09-01 13:07:52 2 * @Date: 2025-09-01 13:07:52
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-10-28 16:36:47 4 + * @LastEditTime: 2025-10-29 09:53:38
5 * @FilePath: /lls_program/src/pages/FamilyRank/index.vue 5 * @FilePath: /lls_program/src/pages/FamilyRank/index.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -159,9 +159,9 @@ ...@@ -159,9 +159,9 @@
159 <!-- 隐藏的弹幕组件,在页面加载时就开始滚动 --> 159 <!-- 隐藏的弹幕组件,在页面加载时就开始滚动 -->
160 <view class="danmu-section mt-8" :style="{ visibility: activeTab === 'support' ? 'visible' : 'hidden', position: activeTab === 'support' ? 'static' : 'absolute', top: activeTab === 'support' ? 'auto' : '-9999px' }"> 160 <view class="danmu-section mt-8" :style="{ visibility: activeTab === 'support' ? 'visible' : 'hidden', position: activeTab === 'support' ? 'static' : 'absolute', top: activeTab === 'support' ? 'auto' : '-9999px' }">
161 <NativeDanmuComponent 161 <NativeDanmuComponent
162 - :container-height="1200" 162 + :container-height="1100"
163 :show-controls="true" 163 :show-controls="true"
164 - :track-count="7" 164 + :track-count="5"
165 @danmu-click="handleDanmuClick" 165 @danmu-click="handleDanmuClick"
166 @danmu-hover="handleDanmuHover" 166 @danmu-hover="handleDanmuHover"
167 ref="danmuRef" 167 ref="danmuRef"
......