123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- <template>
- <div
- class="cover-layout"
- @click="clickHandler"
- @mousedown.stop.prevent="downHandler"
- @touchstart.stop.prevent="downHandler"
- :class="{ move: move }"
- :style="style"
- ref="dom"
- >
- <slot />
- </div>
- </template>
- <script setup lang="ts">
- import {computed, onMounted, onUnmounted, ref, watch} from 'vue'
- import {Pos, Pos3D} from '@/sdk'
- import {useSDK} from '@/hook'
- import { getPostionByTarget} from '@/components/base/utils'
- const props = defineProps<{
- pos: Pos3D
- }>()
- const emit = defineEmits<{
- (m: 'changePos', pos: Pos3D): void
- (m: 'focus'): void
- (m: 'blur'): void
- }>()
- const sdk = useSDK()
- const dom = ref<HTMLElement>()
- const screen = ref<Pos>(null)
- const style = computed(
- () =>
- screen.value && {
- left: screen.value.x + 'px',
- top: screen.value.y + 'px'
- }
- )
- const updatePos = () => {
- if (props.pos) {
- const data = sdk.scene.getScreenByPoint(props.pos)
- screen.value = data.trueSide ? data.pos : null
- }
- }
- sdk.scene.on('posChange', updatePos)
- watch(props, updatePos)
- updatePos()
- const move = ref(false)
- const downHandler = (sev: MouseEvent | TouchEvent) => {
- const el = sev.target as HTMLElement
- const mountEl = document.documentElement
- const preset = {
- x: el.offsetWidth / 2,
- y: el.offsetHeight
- }
- if (sev instanceof TouchEvent) {
- const pos = getPostionByTarget(el, document.querySelector("#app") as HTMLElement);
- preset.x = preset.x - (sev.touches[0].pageX - (pos.x - preset.x))
- preset.y = preset.y - (sev.touches[0].pageY - (pos.y - preset.y))
- console.log(
- pos,
- sev.touches[0].clientX,
- sev.touches[0].clientY,
- preset
- )
- } else {
- preset.x -= sev.offsetX
- preset.y -= sev.offsetY
- }
- const moveHandler = (ev: MouseEvent | TouchEvent) => {
- move.value = true
- const pos = sdk.scene.getPointByScreen({
- x: (ev instanceof TouchEvent ? ev.touches[0].pageX : ev.pageX) + preset.x,
- y: (ev instanceof TouchEvent ? ev.touches[0].pageY : ev.pageY) + preset.y,
- inDrag: true
- })
- if (pos.position) {
- emit('changePos', pos.position);
- }
- }
- const upHandler = (ev: MouseEvent) => {
- mountEl.removeEventListener('mousemove', moveHandler)
- mountEl.removeEventListener('mouseup', upHandler)
- mountEl.removeEventListener('touchmove', moveHandler)
- mountEl.removeEventListener('touchend', upHandler)
- move.value = false
- }
- mountEl.addEventListener('mousemove', moveHandler)
- mountEl.addEventListener('mouseup', upHandler)
- mountEl.addEventListener('touchmove', moveHandler)
- mountEl.addEventListener('touchend', upHandler)
- }
- const clickHandler = ev => {
- emit("focus")
- const handler = (ev: MouseEvent) => {
- if (!dom.value.contains(ev.target as HTMLElement) && ev.target !== dom.value) {
- emit("blur")
- document.documentElement.removeEventListener("click", handler)
- }
- }
- document.documentElement.addEventListener("click", handler, { passive: true })
- }
- onUnmounted(() => {
- emit("blur")
- })
- </script>
- <style scoped lang="scss">
- .cover-layout {
- position: absolute;
- z-index: 1;
- transform: translate(-50%, -100%);
- cursor: move;
- }
- .move {
- pointer-events: none;
- }
- </style>
|