Libon

拖拽画布来移动画布内部的容器

1Mins #HTML#canvas
拖拽画布来移动画布内部的容器
1
<template>
2
<div
3
class="w-full h-full outline-none overflow-hidden relative flex justify-center items-center cursor-grab active:cursor-grabbing"
4
tabindex="-1"
5
@pointerdown="onPressDown"
6
>
7
<div ref="containerRef" class="absolute will-change-transform cursor-default">
8
<slot />
9
</div>
10
</div>
83 collapsed lines
11
</template>
12
13
<script setup>
14
/**
15
* 鼠标按下时的位置
16
*/
17
const position = {
18
x: 0,
19
y: 0
20
}
21
22
/**
23
* @constant
24
* @type {import('vue').Ref<HTMLElement>}
25
* @description 用于获取容器的 ref
26
*/
27
const containerRef = ref()
28
29
function getPositions (ev) {
30
if (ev instanceof MouseEvent) {
31
return {
32
x: ev.clientX,
33
y: ev.clientY
34
}
35
}
36
37
return {
38
x: ev.touches[0].clientX,
39
y: ev.touches[0].clientY
40
}
41
}
42
43
/**
44
* 当按下鼠标或手指
45
* @param {MouseEvent|TouchEvent} ev 事件对象
46
*/
47
function onPressDown (ev) {
48
// 如果不是点击的鼠标左键,则不处理
49
if (ev instanceof MouseEvent && ev.button !== 0) {
50
return
51
}
52
53
// 防止在拖动的过程中选中文字
54
document.body.classList.add('select-none')
55
56
// 记录按下时的位置
57
Object.assign(position, getPositions(ev))
58
59
document.addEventListener('pointerup', onPressUp, { once: true })
60
document.addEventListener('pointermove', onPressMove, { passive: true })
61
}
62
63
/**
64
* 当按下并移动鼠标或手指
65
* @param {MouseEvent|TouchEvent} ev 事件对象
66
*/
67
function onPressMove (ev) {
68
const { x, y } = getPositions(ev)
69
70
const elStyle = containerRef.value.style
71
72
// 计算鼠标/手指按下到这一次移动的偏移量
73
const offsetX = x - position.x
74
const offsetY = y - position.y
75
76
// 获取当前的 transform 位置
77
const [, currentX = 0, currentY = 0] = elStyle.transform.match(/translate3d\((.+?)px, (.+?)px, 0px\)/) ?? []
78
79
elStyle.transform = `translate3d(${~~currentX + offsetX}px, ${~~currentY + offsetY}px, 0)`
80
81
// 更新上一次移动的位置
82
Object.assign(position, { x, y })
83
}
84
85
/**
86
* 当松开鼠标或手指
87
*/
88
function onPressUp () {
89
document.body.classList.remove('select-none')
90
document.removeEventListener('pointermove', onPressMove)
91
}
92
93
</script>

CD ..
接下来阅读
CSS 属性选择器