|
@@ -9,8 +9,8 @@
|
|
|
:style="getDanmakuStyle(item)"
|
|
|
>
|
|
|
<view class="danmaku-content">
|
|
|
- <image class="danmaku-avatar" :src="item.avatar || defaultAvatar" mode="aspectFill"></image>
|
|
|
- <view class="danmaku-text">{{ item.text }}</view>
|
|
|
+ <image class="danmaku-avatar" :src="item.icon || defaultAvatar" mode="aspectFill"></image>
|
|
|
+ <view class="danmaku-text">{{ item.msg }}</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
@@ -54,6 +54,11 @@ const animationTimer = ref(null)
|
|
|
const danmakuIdCounter = ref(0)
|
|
|
const trackOccupancy = ref(new Array(props.trackCount).fill(0)) // 记录每个轨道的占用情况
|
|
|
|
|
|
+// 监听trackCount变化,重新初始化trackOccupancy
|
|
|
+watch(() => props.trackCount, (newCount) => {
|
|
|
+ trackOccupancy.value = new Array(newCount).fill(0)
|
|
|
+})
|
|
|
+
|
|
|
const trackHeight = computed(() => props.height / props.trackCount)
|
|
|
|
|
|
// 默认头像
|
|
@@ -101,17 +106,14 @@ const calculateDanmakuHeight = () => {
|
|
|
const calculateTrackSpacing = () => {
|
|
|
const danmakuHeight = calculateDanmakuHeight()
|
|
|
const trackHeight = props.height / props.trackCount
|
|
|
- // 对于低高度容器,增加轨道间距避免叠加
|
|
|
- const minSpacing = props.height < 150 ? danmakuHeight + 20 : danmakuHeight + 10
|
|
|
+ // 增加轨道间距,避免弹幕重叠
|
|
|
+ const minSpacing = danmakuHeight + 30 // 增加间距到30px
|
|
|
return Math.max(minSpacing, trackHeight) // 确保轨道间距足够
|
|
|
}
|
|
|
|
|
|
// 查找可用轨道
|
|
|
const findAvailableTrack = () => {
|
|
|
- const screenWidth = uni.getSystemInfoSync().screenWidth || 375
|
|
|
const currentTime = Date.now()
|
|
|
- const danmakuHeight = calculateDanmakuHeight()
|
|
|
- const trackSpacing = calculateTrackSpacing()
|
|
|
|
|
|
// 清理过期的轨道占用记录
|
|
|
for (let i = 0; i < trackOccupancy.value.length; i++) {
|
|
@@ -120,45 +122,18 @@ const findAvailableTrack = () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 计算可用的轨道数量,确保弹幕不会超出容器边界
|
|
|
- const maxTracks = Math.floor((props.height - danmakuHeight) / trackSpacing) + 1
|
|
|
- const availableTracks = Math.min(props.trackCount, maxTracks)
|
|
|
+ // 简化轨道分配:使用较少的轨道数量
|
|
|
+ const finalTracks = Math.min(3, props.trackCount)
|
|
|
|
|
|
- // 对于低高度容器,减少可用轨道数量避免叠加
|
|
|
- const finalTracks = props.height < 150 ? Math.min(availableTracks, 3) : availableTracks
|
|
|
-
|
|
|
- // 首先尝试寻找完全空闲的轨道
|
|
|
- for (let i = 0; i < finalTracks; i++) {
|
|
|
- if (trackOccupancy.value[i] === 0) {
|
|
|
- // 检查相邻轨道是否被占用
|
|
|
- const prevTrack = i > 0 ? trackOccupancy.value[i - 1] : 0
|
|
|
- const nextTrack = i < finalTracks - 1 ? trackOccupancy.value[i + 1] : 0
|
|
|
-
|
|
|
- // 优先选择完全空闲的轨道
|
|
|
- if (prevTrack === 0 && nextTrack === 0) {
|
|
|
- return i
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 如果没有完全空闲的轨道,寻找任何空闲轨道
|
|
|
+ // 直接寻找空闲轨道
|
|
|
for (let i = 0; i < finalTracks; i++) {
|
|
|
if (trackOccupancy.value[i] === 0) {
|
|
|
return i
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 如果所有轨道都被占用,选择最早释放的轨道
|
|
|
- let earliestTrack = 0
|
|
|
- let earliestTime = trackOccupancy.value[0]
|
|
|
- for (let i = 1; i < finalTracks; i++) {
|
|
|
- if (trackOccupancy.value[i] < earliestTime) {
|
|
|
- earliestTime = trackOccupancy.value[i]
|
|
|
- earliestTrack = i
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return earliestTrack
|
|
|
+ // 如果所有轨道都被占用,选择第一个轨道
|
|
|
+ return 0
|
|
|
}
|
|
|
|
|
|
const createDanmaku = (text, avatar = null) => {
|
|
@@ -170,16 +145,15 @@ const createDanmaku = (text, avatar = null) => {
|
|
|
const screenWidth = uni.getSystemInfoSync().screenWidth || 375
|
|
|
const left = screenWidth + props.spacing
|
|
|
|
|
|
- // 计算弹幕持续时间并记录轨道占用,增加缓冲时间
|
|
|
- const extraDistance = 200
|
|
|
- const duration = (screenWidth + width + extraDistance) / props.speed
|
|
|
- const endTime = Date.now() + duration * 1000
|
|
|
+ // 简化轨道占用时间计算
|
|
|
+ const duration = (screenWidth + width + 200) / props.speed
|
|
|
+ const endTime = Date.now() + duration * 1000 // 移除额外缓冲时间
|
|
|
trackOccupancy.value[track] = endTime
|
|
|
|
|
|
return {
|
|
|
id,
|
|
|
- text,
|
|
|
- avatar,
|
|
|
+ msg: text, // 修改为msg字段,与模板保持一致
|
|
|
+ icon: avatar, // 修改为icon字段,与模板保持一致
|
|
|
track,
|
|
|
width,
|
|
|
left,
|
|
@@ -188,10 +162,13 @@ const createDanmaku = (text, avatar = null) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const addDanmaku = (text, avatar = null) => {
|
|
|
- const danmaku = createDanmaku(text, avatar)
|
|
|
+const addDanmaku = (msg, icon = null) => {
|
|
|
+ console.log('添加弹幕:', { msg, icon })
|
|
|
+ const danmaku = createDanmaku(msg, icon)
|
|
|
+ console.log('创建的弹幕对象:', danmaku)
|
|
|
|
|
|
visibleDanmakus.value.push(danmaku)
|
|
|
+ console.log('当前可见弹幕数量:', visibleDanmakus.value.length)
|
|
|
|
|
|
setTimeout(() => {
|
|
|
danmaku.isScrolling = true
|
|
@@ -224,7 +201,11 @@ const clearDanmakus = () => {
|
|
|
}
|
|
|
|
|
|
const startDanmakuAnimation = () => {
|
|
|
- if (props.danmakuList.length === 0) return
|
|
|
+ console.log('开始弹幕动画,数据列表:', props.danmakuList)
|
|
|
+ if (props.danmakuList.length === 0) {
|
|
|
+ console.log('弹幕列表为空,不启动动画')
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
let currentIndex = 0
|
|
|
|
|
@@ -238,15 +219,16 @@ const startDanmakuAnimation = () => {
|
|
|
}
|
|
|
|
|
|
const danmaku = props.danmakuList[currentIndex]
|
|
|
- addDanmaku(danmaku.text, danmaku.avatar)
|
|
|
+ console.log('播放弹幕:', danmaku)
|
|
|
+
|
|
|
+ // 直接播放弹幕,不检查轨道占用
|
|
|
+ addDanmaku(danmaku.msg, danmaku.icon)
|
|
|
currentIndex++
|
|
|
|
|
|
- // 根据容器高度动态调整间隔时间,低高度容器需要更大的间隔避免叠加
|
|
|
- const baseInterval = props.height < 150 ?
|
|
|
- Math.max(3000, props.height * 2) : // 低高度容器使用适中的基础间隔
|
|
|
- Math.max(1500, props.height * 2) // 正常高度容器
|
|
|
+ // 减少弹幕播放间隔
|
|
|
+ const baseInterval = Math.max(2000, props.height * 2) // 减少基础间隔
|
|
|
const minInterval = baseInterval
|
|
|
- const maxInterval = baseInterval + (props.height < 150 ? 2000 : 2000)
|
|
|
+ const maxInterval = baseInterval + 2000 // 减少随机间隔范围
|
|
|
const interval = Math.random() * (maxInterval - minInterval) + minInterval
|
|
|
animationTimer.value = setTimeout(playNext, interval)
|
|
|
}
|
|
@@ -262,10 +244,14 @@ const stopDanmakuAnimation = () => {
|
|
|
}
|
|
|
|
|
|
watch(() => props.danmakuList, (newList) => {
|
|
|
+ console.log('弹幕数据变化:', newList)
|
|
|
if (newList.length > 0) {
|
|
|
+ console.log('弹幕数据不为空,重新启动动画')
|
|
|
stopDanmakuAnimation()
|
|
|
clearDanmakus()
|
|
|
startDanmakuAnimation()
|
|
|
+ } else {
|
|
|
+ console.log('弹幕数据为空')
|
|
|
}
|
|
|
}, { deep: true })
|
|
|
|
|
@@ -371,3 +357,5 @@ defineExpose({
|
|
|
background: rgba(244, 246, 248, 0.6);
|
|
|
}
|
|
|
</style>
|
|
|
+
|
|
|
+
|