85 lines
2.4 KiB
JavaScript
85 lines
2.4 KiB
JavaScript
import { ref } from 'vue'
|
||
|
||
export function useDialogRotation() {
|
||
let timer = null
|
||
let screenWidth = 375
|
||
let screenHeight = 812
|
||
|
||
const initDialogRotation = ({ screenW, screenH }) => {
|
||
screenWidth = screenW
|
||
screenHeight = screenH
|
||
}
|
||
|
||
const isCabinInViewport = (cabin) => {
|
||
return new Promise((resolve) => {
|
||
const query = uni.createSelectorQuery()
|
||
query.select(`#cabin-${cabin.key}`).boundingClientRect((rect) => {
|
||
if (!rect) {
|
||
resolve(false)
|
||
return
|
||
}
|
||
|
||
const visibleTop = Math.max(0, rect.top)
|
||
const visibleBottom = Math.min(screenHeight, rect.bottom)
|
||
const visibleLeft = Math.max(0, rect.left)
|
||
const visibleRight = Math.min(screenWidth, rect.right)
|
||
const visibleWidth = Math.max(0, visibleRight - visibleLeft)
|
||
const visibleHeight = Math.max(0, visibleBottom - visibleTop)
|
||
const visibleArea = visibleWidth * visibleHeight
|
||
const totalArea = rect.width * rect.height
|
||
const visiblePercent = totalArea > 0 ? visibleArea / totalArea : 0
|
||
|
||
resolve(visiblePercent > 0.7)
|
||
}).exec()
|
||
})
|
||
}
|
||
|
||
const rotateDialogVisibility = async (cabins) => {
|
||
if (!cabins.length) return
|
||
|
||
// 先全部重置为 false
|
||
cabins.forEach(c => c.showDialog = false)
|
||
|
||
// 筛选符合条件的 cabin:有昵称、有展位剩余
|
||
const hasData = cabins.filter(c => c.nickname && c.sharedBoothSlotsRemaining !== null)
|
||
|
||
// 批量检查所有 cabin 是否在可视区域内
|
||
const viewportChecks = await Promise.all(hasData.map(c => isCabinInViewport(c)))
|
||
const eligible = hasData.filter((c, i) => viewportChecks[i])
|
||
|
||
if (eligible.length === 0) return
|
||
|
||
// 随机选择 2-3 个
|
||
const count = Math.min(Math.floor(Math.random() * 2) + 2, eligible.length, 3)
|
||
const shuffled = eligible.sort(() => Math.random() - 0.5)
|
||
for (let i = 0; i < count; i++) {
|
||
shuffled[i].showDialog = true
|
||
}
|
||
}
|
||
|
||
const startDialogRotation = (cabins) => {
|
||
stopDialogRotation()
|
||
|
||
const rotate = async () => {
|
||
await rotateDialogVisibility(cabins)
|
||
const interval = Math.floor(Math.random() * 1000) + 2000
|
||
timer = setTimeout(rotate, interval)
|
||
}
|
||
|
||
rotate()
|
||
}
|
||
|
||
const stopDialogRotation = () => {
|
||
if (timer) {
|
||
clearTimeout(timer)
|
||
timer = null
|
||
}
|
||
}
|
||
|
||
return {
|
||
initDialogRotation,
|
||
startDialogRotation,
|
||
stopDialogRotation,
|
||
}
|
||
}
|