use-canvas-drag 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +204 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,37 +1,204 @@
|
|
|
1
|
-
# use-canvas-drag
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
# use-canvas-drag
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
Vue3 画布拖拽组合式函数,轻量、无依赖、TypeScript 支持,开箱即用。
|
|
9
|
+
|
|
10
|
+
## 特性
|
|
11
|
+
|
|
12
|
+
- 🌿 **轻量无依赖** - 仅 ~1KB,零外部依赖
|
|
13
|
+
- 🔧 **多种触发方式** - 支持右键、中键、左键 + 组合键
|
|
14
|
+
- 📦 **开箱即用** - 组合式函数设计,天然 Tree-Shakable
|
|
15
|
+
- 🔰 **TypeScript** - 完整类型提示,IDE 友好
|
|
16
|
+
- 🎯 **零外部依赖** - 不依赖任何 UI 框架
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install use-canvas-drag
|
|
22
|
+
# 或
|
|
23
|
+
pnpm add use-canvas-drag
|
|
24
|
+
# 或
|
|
25
|
+
yarn add use-canvas-drag
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 快速开始
|
|
29
|
+
|
|
30
|
+
```vue
|
|
31
|
+
<template>
|
|
32
|
+
<div id="canvas" ref="canvasRef" class="canvas">
|
|
33
|
+
<div class="draggable-box" :style="{ left: x + 'px', top: y + 'px' }">
|
|
34
|
+
拖动我
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<script setup>
|
|
40
|
+
import { ref } from 'vue'
|
|
41
|
+
import { useCanvasDrag } from 'use-canvas-drag'
|
|
42
|
+
|
|
43
|
+
const canvasRef = ref(null)
|
|
44
|
+
const x = ref(100)
|
|
45
|
+
const y = ref(100)
|
|
46
|
+
|
|
47
|
+
const { isPanning, stopPan } = useCanvasDrag({
|
|
48
|
+
container: canvasRef,
|
|
49
|
+
mode: 'right',
|
|
50
|
+
onDrag: ({ x: dx, y: dy }) => {
|
|
51
|
+
x.value += dx
|
|
52
|
+
y.value += dy
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<style scoped>
|
|
58
|
+
.canvas {
|
|
59
|
+
width: 100%;
|
|
60
|
+
height: 500px;
|
|
61
|
+
border: 1px solid #ddd;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
position: relative;
|
|
64
|
+
}
|
|
65
|
+
.draggable-box {
|
|
66
|
+
position: absolute;
|
|
67
|
+
padding: 20px;
|
|
68
|
+
background: #4a90e2;
|
|
69
|
+
color: white;
|
|
70
|
+
cursor: grab;
|
|
71
|
+
user-select: none;
|
|
72
|
+
}
|
|
73
|
+
.draggable-box:active {
|
|
74
|
+
cursor: grabbing;
|
|
75
|
+
}
|
|
76
|
+
</style>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 多按钮配置
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { useCanvasDrag } from 'use-canvas-drag'
|
|
83
|
+
|
|
84
|
+
const { handlers, stopPan } = useCanvasDrag({
|
|
85
|
+
container: '#canvas',
|
|
86
|
+
mode: ['right', 'middle'], // 右键或中键触发
|
|
87
|
+
enabled: true,
|
|
88
|
+
onStartDrag: (e) => {
|
|
89
|
+
console.log('开始拖拽', e.clientX, e.clientY)
|
|
90
|
+
},
|
|
91
|
+
onDrag: ({ x, y, deltaX, deltaY }) => {
|
|
92
|
+
console.log(`移动了: ${deltaX}, ${deltaY}`)
|
|
93
|
+
},
|
|
94
|
+
onEndDrag: () => {
|
|
95
|
+
console.log('结束拖拽')
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 画布平移
|
|
101
|
+
|
|
102
|
+
```vue
|
|
103
|
+
<template>
|
|
104
|
+
<div id="canvas" ref="canvasRef" class="canvas">
|
|
105
|
+
<div class="content" :style="{ transform: `translate(${offset.x}px, ${offset.y}px)` }">
|
|
106
|
+
<div class="item">Item 1</div>
|
|
107
|
+
<div class="item">Item 2</div>
|
|
108
|
+
<div class="item">Item 3</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</template>
|
|
112
|
+
|
|
113
|
+
<script setup>
|
|
114
|
+
import { reactive } from 'vue'
|
|
115
|
+
import { useCanvasDrag } from 'use-canvas-drag'
|
|
116
|
+
|
|
117
|
+
const canvasRef = ref(null)
|
|
118
|
+
const offset = reactive({ x: 0, y: 0 })
|
|
119
|
+
|
|
120
|
+
const { isPanning } = useCanvasDrag({
|
|
121
|
+
container: canvasRef,
|
|
122
|
+
mode: 'right',
|
|
123
|
+
onDrag: ({ deltaX, deltaY }) => {
|
|
124
|
+
offset.x += deltaX
|
|
125
|
+
offset.y += deltaY
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
</script>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## API
|
|
132
|
+
|
|
133
|
+
### useCanvasDrag(options)
|
|
134
|
+
|
|
135
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
136
|
+
|------|------|------|------|
|
|
137
|
+
| `container` | `string \| HTMLElement \| () => HTMLElement` | ✅ | 画布容器,支持选择器、元素或返回元素的函数 |
|
|
138
|
+
| `mode` | `'left' \| 'right' \| 'middle' \| 'shift-left' \| 'ctrl-left' \| 'alt-left' \| (Trigger)[]'` | ❌ | 触发方式,默认 `'right'` |
|
|
139
|
+
| `enabled` | `boolean` | ❌ | 是否启用,默认 `true` |
|
|
140
|
+
| `onStartDrag` | `(e: MouseEvent) => void` | ❌ | 开始拖拽时触发 |
|
|
141
|
+
| `onDrag` | `(info: DragInfo) => void` | ❌ | 拖拽过程中触发 |
|
|
142
|
+
| `onEndDrag` | `() => void` | ❌ | 结束拖拽时触发 |
|
|
143
|
+
|
|
144
|
+
### DragInfo
|
|
145
|
+
|
|
146
|
+
| 属性 | 类型 | 说明 |
|
|
147
|
+
|------|------|------|
|
|
148
|
+
| `x` | `number` | 相对于起始位置的 X 轴偏移 |
|
|
149
|
+
| `y` | `number` | 相对于起始位置的 Y 轴偏移 |
|
|
150
|
+
| `deltaX` | `number` | 相对于上一帧的 X 轴偏移 |
|
|
151
|
+
| `deltaY` | `number` | 相对于上一帧的 Y 轴偏移 |
|
|
152
|
+
|
|
153
|
+
### 返回值
|
|
154
|
+
|
|
155
|
+
| 属性 | 类型 | 说明 |
|
|
156
|
+
|------|------|------|
|
|
157
|
+
| `isPanning` | `Ref<boolean>` | 是否正在平移 |
|
|
158
|
+
| `handlers` | `object` | mousedown/mousemove/mouseup 事件处理器 |
|
|
159
|
+
| `stopPan` | `() => void` | 手动停止平移 |
|
|
160
|
+
| `setEnabled` | `(enabled: boolean) => void` | 动态启用/禁用 |
|
|
161
|
+
|
|
162
|
+
### DragButtonConfig (类型导出)
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
interface DragButtonConfig {
|
|
166
|
+
button: number; // 鼠标按钮: 0=左键, 1=中键, 2=右键
|
|
167
|
+
ctrlKey?: boolean; // 是否需要 Ctrl 键
|
|
168
|
+
shiftKey?: boolean; // 是否需要 Shift 键
|
|
169
|
+
altKey?: boolean; // 是否需要 Alt 键
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## 触发模式
|
|
174
|
+
|
|
175
|
+
| 模式 | 说明 |
|
|
176
|
+
|------|------|
|
|
177
|
+
| `'left'` | 鼠标左键 |
|
|
178
|
+
| `'right'` | 鼠标右键 |
|
|
179
|
+
| `'middle'` | 鼠标中键(滚轮) |
|
|
180
|
+
| `'shift-left'` | Shift + 左键 |
|
|
181
|
+
| `'ctrl-left'` | Ctrl + 左键 |
|
|
182
|
+
| `'alt-left'` | Alt + 左键 |
|
|
183
|
+
|
|
184
|
+
## 常见问题
|
|
185
|
+
|
|
186
|
+
### Q: 右键菜单被阻止了吗?
|
|
187
|
+
|
|
188
|
+
A: 是的,插件会自动调用 `e.preventDefault()` 阻止默认右键菜单。
|
|
189
|
+
|
|
190
|
+
### Q: 如何在拖拽时隐藏自定义鼠标指针?
|
|
191
|
+
|
|
192
|
+
A: 通过 `isPanning` 控制:
|
|
193
|
+
|
|
194
|
+
```vue
|
|
195
|
+
<div :class="{ 'hide-cursor': isPanning }">...</div>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Q: 支持多画布吗?
|
|
199
|
+
|
|
200
|
+
A: 支持,只需创建多个实例即可。
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT
|