liveh5-nuxt/app/components/liveMinWindow/index.vue
xingyy 50fe1248e3 refactor(liveRoom): 优化直播室组件和支付功能
- 移除 paymentInput 组件中的冗余属性
- 在 liveMinWindow 组件中添加路由监听,实现自动关闭功能
- 删除 PaymentInput 组件中的无用日志输出
2025-02-11 15:39:22 +08:00

183 lines
4.7 KiB
Vue

<template>
<div ref="dragRef"
:style="style"
class="fixed rounded-5px overflow-hidden shadow-lg cursor-move z-50"
@mousedown.stop="handleDragStart"
@touchstart.stop="handleDragStart">
<div class="relative" @click.stop="handleClick">
<img :src="props.snapshot"
class="w-80px object-cover"
alt="直播画面">
<div class="absolute inset-0 bg-black/40 flex items-center justify-center"
>
<span class="text-white text-12px">点击回到直播</span>
</div>
<button @click.stop="handleClose"
class="absolute top-10px right-10px text-white bg-black/40 rounded-full w-5 h-5 flex items-center justify-center hover:bg-black/60 cursor-pointer">
<van-icon name="cross" />
</button>
</div>
</div>
</template>
<script setup>
import { ref, computed, onBeforeUnmount, shallowRef, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useThrottleFn } from '@vueuse/core'
const props = defineProps({
snapshot: {
type: String,
required: true
},
onClose: {
type: Function,
default: () => {}
},
onClick: {
type: Function,
default: () => {}
},
initialPosition: {
type: Object,
default: () => ({
top: '80px',
right: '16px'
})
}
})
const router = useRouter()
const dragRef = shallowRef(null)
const route = useRoute()
const isDragging = ref(false)
const startX = ref(0)
const startY = ref(0)
const left = ref(0)
const top = ref(0)
onMounted(() => {
const rect = dragRef.value.getBoundingClientRect()
left.value = window.innerWidth - rect.width - parseInt(props.initialPosition.right)
top.value = parseInt(props.initialPosition.top)
})
const style = computed(() => ({
left: left.value ? `${left.value}px` : 'auto',
top: top.value ? `${top.value}px` : 'auto',
right: !left.value ? props.initialPosition.right : 'auto',
transition: isDragging.value ? 'none' : 'all 0.3s ease',
}))
const handleDragStart = (event) => {
event.stopPropagation()
isDragging.value = true
const point = event.touches ? event.touches[0] : event
const rect = dragRef.value.getBoundingClientRect()
left.value = rect.left
top.value = rect.top
startX.value = point.clientX - left.value
startY.value = point.clientY - top.value
if (event.type === 'mousedown') {
document.addEventListener('mousemove', handleDragMove)
document.addEventListener('mouseup', handleDragEnd)
} else {
document.addEventListener('touchmove', handleDragMove, { passive: false })
document.addEventListener('touchend', handleDragEnd)
}
}
const handleDragMove = useThrottleFn((event) => {
if (!isDragging.value) return
event.preventDefault()
event.stopPropagation()
const point = event.touches ? event.touches[0] : event
const rect = dragRef.value.getBoundingClientRect()
const maxX = window.innerWidth - rect.width
const maxY = window.innerHeight - rect.height
left.value = Math.min(Math.max(0, point.clientX - startX.value), maxX)
top.value = Math.min(Math.max(0, point.clientY - startY.value), maxY)
}, 16)
const handleEdgeSnap = useThrottleFn(() => {
const rect = dragRef.value.getBoundingClientRect()
const centerX = rect.left + rect.width / 2
left.value = centerX > window.innerWidth / 2
? window.innerWidth - rect.width - 16
: 16
}, 100)
const handleDragEnd = () => {
if (!isDragging.value) return
isDragging.value = false
handleEdgeSnap()
document.removeEventListener('mousemove', handleDragMove)
document.removeEventListener('mouseup', handleDragEnd)
document.removeEventListener('touchmove', handleDragMove)
document.removeEventListener('touchend', handleDragEnd)
}
const handleClick = (event) => {
event.stopPropagation()
if (!isDragging.value) {
handleReturnLive()
}
}
const handleReturnLive = () => {
props.onClick()
}
const handleClose = (event) => {
event?.stopPropagation()
props.onClose()
}
watch(() => route.path, (newVal) => {
if (['/','/home'].includes(newVal)){
handleClose()
}
})
onBeforeUnmount(() => {
document.removeEventListener('mousemove', handleDragMove)
document.removeEventListener('mouseup', handleDragEnd)
document.removeEventListener('touchmove', handleDragMove)
document.removeEventListener('touchend', handleDragEnd)
})
</script>
<style scoped>
.fixed {
will-change: transform, opacity;
touch-action: none;
-webkit-user-select: none;
user-select: none;
transform: translateZ(0);
}
.min-window-enter-active,
.min-window-leave-active {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.min-window-enter-from,
.min-window-leave-to {
transform: translateY(100%);
opacity: 0;
}
img {
pointer-events: none;
-webkit-user-drag: none;
user-drag: none;
}
</style>