1. 礼物特效

This commit is contained in:
李琦
2026-08-03 14:27:32 +08:00
parent eac87759f3
commit fe10dd3fa5
14 changed files with 2787 additions and 24 deletions

View File

@@ -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;