1. 礼物特效
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<!-- 始终挂载,用 v-show 隐藏,避免关闭时 v-if 拆树与清空列表打架 -->
|
||||
<div v-show="enabled" class="danmaku-layer" aria-hidden="true">
|
||||
<div
|
||||
v-show="enabled"
|
||||
class="danmaku-layer"
|
||||
:style="layerBoxStyle"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div
|
||||
v-for="row in rows"
|
||||
:key="row.id"
|
||||
@@ -29,15 +34,18 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { ref, watch, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { getDanmaku } from '@/api/wedding'
|
||||
import { formatRelativeTime } from '@/utils/relativeTime'
|
||||
import { resolveDanmakuColor, resolveDanmakuTint } from '@/utils/danmakuColors'
|
||||
import { DANMAKU_AREA_BOX } from '@/utils/danmakuArea'
|
||||
|
||||
const props = defineProps({
|
||||
enabled: { type: Boolean, default: true },
|
||||
showTime: { type: Boolean, default: true },
|
||||
active: { type: Boolean, default: true },
|
||||
/** top30 | top | bottom | full */
|
||||
area: { type: String, default: 'top30' },
|
||||
})
|
||||
|
||||
const POLL_MS = 30000
|
||||
@@ -46,6 +54,15 @@ const TRACKS = 5
|
||||
/** 同轨占用结束前不可再发,避免重叠 */
|
||||
const TRACK_GAP_MS = 420
|
||||
|
||||
const layerBoxStyle = computed(() => {
|
||||
const box = DANMAKU_AREA_BOX[props.area] || DANMAKU_AREA_BOX.top30
|
||||
return {
|
||||
top: box.top,
|
||||
height: box.height,
|
||||
bottom: 'auto',
|
||||
}
|
||||
})
|
||||
|
||||
const items = ref([])
|
||||
const rows = ref([])
|
||||
let cursor = 0
|
||||
@@ -154,7 +171,8 @@ const buildRow = (item, { force = false } = {}) => {
|
||||
const tint = resolveDanmakuTint(item.color)
|
||||
const id = ++uid
|
||||
const totalDelay = delay + slot.extraDelay
|
||||
const topPct = 7 + slot.track * 14
|
||||
// 轨道分布在当前弹幕层内部(由 area 控制层高度)
|
||||
const topPct = TRACKS <= 1 ? 50 : 12 + (slot.track / (TRACKS - 1)) * 70
|
||||
const isGradient = typeof tint.background === 'string' && tint.background.includes('gradient')
|
||||
|
||||
const timeLabel = force
|
||||
@@ -319,6 +337,15 @@ watch(
|
||||
},
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.area,
|
||||
() => {
|
||||
if (!props.enabled) return
|
||||
clearFlying()
|
||||
syncSpawn()
|
||||
},
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
if (!props.enabled) return
|
||||
await fetchList()
|
||||
@@ -336,7 +363,10 @@ defineExpose({ refresh: fetchList, pushItem })
|
||||
<style scoped>
|
||||
.danmaku-layer {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 30%;
|
||||
z-index: 40;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
|
||||
Reference in New Issue
Block a user