feat(components): 实现侧边栏拖动功能

- 在 SideButton 组件中添加拖动功能,支持鼠标和触摸操作
-优化 artDetail 页面中的拖动逻辑,限制拖动范围
-修复 liveRoom 组件中的拖动相关问题
This commit is contained in:
xingyy 2025-02-14 17:00:34 +08:00
parent aad429be0a
commit 2f8eb36a52
2 changed files with 130 additions and 29 deletions

View File

@ -14,7 +14,7 @@ const initData = async () => {
detail.value = res.data
}
}
const position = ref({x: window?.innerWidth - 120 || 0, y: 240}) //
const position = ref({x: window?.innerWidth - 120 || 0, y: 240})
const startPosition = ref({x: 0, y: 0})
const isDragging = ref(false)
@ -33,38 +33,30 @@ const onDrag = (e) => {
const clientX = e.touches ? e.touches[0].clientX : e.clientX
const clientY = e.touches ? e.touches[0].clientY : e.clientY
//
const maxX = window.innerWidth - 108 //
const maxY = window.innerHeight - 137 //
const maxX = window.innerWidth - 108
const maxY = window.innerHeight - 137
//
const x = Math.min(Math.max(0, clientX - startPosition.value.x), maxX)
const y = Math.min(Math.max(0, clientY - startPosition.value.y), maxY)
position.value = {x, y}
}
}
const stopDrag = () => {
isDragging.value = false
}
onMounted(() => {
//
document.addEventListener('mousemove', onDrag)
document.addEventListener('mouseup', stopDrag)
//
document.addEventListener('touchmove', onDrag)
document.addEventListener('touchend', stopDrag)
})
onUnmounted(() => {
document.removeEventListener('mousemove', onDrag)
document.removeEventListener('mouseup', stopDrag)
document.removeEventListener('touchmove', onDrag)
document.removeEventListener('touchend', stopDrag)
})
initData()
</script>

View File

@ -1,17 +1,93 @@
<script setup>
import {ref} from "vue";
import lockClosed from "@/static/images/lockdfd@2x.png";
import lockOpen from "@/static/images/lock4@2x.png";
import {liveStore} from "@/stores/live/index.js";
import { ref, computed, onMounted, onBeforeUnmount } from "vue"
import lockClosed from "@/static/images/lockdfd@2x.png"
import lockOpen from "@/static/images/lock4@2x.png"
import { liveStore } from "@/stores/live/index.js"
import xButton from '@/components/x-button/index.vue'
import tangPopup from './tangPopup.vue'
import {goodStore} from "@/stores/goods/index.js";
import {authStore} from "~/stores/auth/index.js";
import { goodStore } from "@/stores/goods/index.js"
import { authStore } from "~/stores/auth/index.js"
const {quoteStatus, changeStatus, show, auctionData, getSocketData} = liveStore();
const {pageRef} = goodStore();
const { quoteStatus, changeStatus, show, auctionData, getSocketData } = liveStore()
const { pageRef } = goodStore()
const { userInfo } = authStore()
const showTang = ref(false)
//
const isDragging = ref(false)
const startY = ref(0)
const currentTop = ref(196) // top
const sidebarRef = ref(null)
//
const minTop = 0 // top
const maxTop = window.innerHeight - 180 // top
//
const handleMouseDown = (e) => {
isDragging.value = true
startY.value = e.clientY - currentTop.value
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
}
//
const handleMouseMove = (e) => {
if (!isDragging.value) return
let newTop = e.clientY - startY.value
//
newTop = Math.max(minTop, Math.min(newTop, maxTop))
currentTop.value = newTop
//
if (sidebarRef.value) {
sidebarRef.value.style.top = `${newTop}px`
}
}
//
const handleMouseUp = () => {
isDragging.value = false
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
}
//
const handleTouchStart = (e) => {
isDragging.value = true
startY.value = e.touches[0].clientY - currentTop.value
}
const handleTouchMove = (e) => {
if (!isDragging.value) return
let newTop = e.touches[0].clientY - startY.value
newTop = Math.max(minTop, Math.min(newTop, maxTop))
currentTop.value = newTop
if (sidebarRef.value) {
sidebarRef.value.style.top = `${newTop}px`
}
}
const handleTouchEnd = () => {
isDragging.value = false
}
//
onMounted(() => {
if (sidebarRef.value) {
sidebarRef.value.style.top = `${currentTop.value}px`
}
})
//
onBeforeUnmount(() => {
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
})
const openOne = () => {
showTang.value = true
}
@ -24,24 +100,41 @@ const paySide = computed(() => {
return false
}
})
const goPay = () => {
show.value = true
}
</script>
<template>
<div class="bg-white w-60px rounded-l-4px overflow-hidden">
<div
ref="sidebarRef"
class="bg-white w-60px rounded-l-4px overflow-hidden absolute right-0 z-999 cursor-move"
@mousedown="handleMouseDown"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
<!-- 拍品信息 -->
<van-button class="w-60px !h-60px" @click="openOne" style="border: none;border-radius: 0">
<van-button
class="w-60px !h-60px"
@click="openOne"
style="border: none;border-radius: 0"
>
<div class="text-center flex flex-col justify-center items-center text-#7D7D7F text-12px">
<div>{{ $t('live_room.lots') }}</div>
<div>({{ auctionData?.artwork?.index }}/{{ pageRef.itemCount ?? 0 }})</div>
</div>
</van-button>
<tangPopup v-model:show="showTang"></tangPopup>
<!-- 出价开关 -->
<van-button class="w-60px !h-60px" @click="changeStatus"
style="border-right: none;border-left: none;border-radius: 0;padding: 0">
<van-button
class="w-60px !h-60px"
@click="changeStatus"
style="border-right: none;border-left: none;border-radius: 0;padding: 0"
>
<div class="text-center flex flex-col justify-center items-center">
<div class="mb-4px">
<img
@ -50,19 +143,35 @@ const goPay = () => {
alt="锁图标"
/>
</div>
<div :class="quoteStatus ? 'text-gray-500' : 'text-blue-600'" class="text-10px transition-colors duration-200">
<div
:class="quoteStatus ? 'text-gray-500' : 'text-blue-600'"
class="text-10px transition-colors duration-200"
>
{{ quoteStatus ? $t('live_room.colse_bid') : $t('live_room.start_bid') }}
</div>
</div>
</van-button>
<!-- 支付 -->
<van-button v-if="paySide" class="w-60px !h-60px" style="border: none;border-radius: 0" @click="goPay">
<van-button
v-if="paySide"
class="w-60px !h-60px"
style="border: none;border-radius: 0"
@click="goPay"
>
<div class="text-center flex flex-col justify-center items-center text-yellow-600">
<div class="text-10px">RMB</div>
<div class="text-12px">5,000</div>
<div class="text-10px">{{ $t('art_detail_page.button') }}</div>
</div>
</van-button>
</div>
</template>
<style scoped>
.cursor-move {
cursor: move;
user-select: none;
touch-action: none;
}
</style>