Skip to content

Commit 3c165f7

Browse files
adding containing rectangle feature
1 parent ff41625 commit 3c165f7

File tree

7 files changed

+97
-19
lines changed

7 files changed

+97
-19
lines changed

README.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,17 @@ npm install draggable-vue-directive --save
6969
...
7070
```
7171
72-
### draggable value
72+
### draggable Value
73+
The Object passed to the directive is called the directive value.<br>
74+
For example in `v-draggable="draggableValue"` draggableValue can be an object containing the folowing fields <br>
75+
76+
* [handle](#handle)
77+
* [onPositionChange](#onpositionchange)
78+
* [resetInitialPos](#resetinitialpos)
79+
* [stopDragging](#stopdragging)
80+
* [boundingRect](#boundingrect)
81+
82+
7383
#### handle
7484
Type: `HtmlElement | Vue`<br>
7585
Required: `false`<br>
@@ -116,8 +126,23 @@ will be executed with the current position as param.<br>
116126
117127
#### resetInitialPos
118128
Type: `Boolean`<br>
119-
Required: `false`
129+
Required: `false`<br>
130+
default: `undefined`<br>
131+
132+
Returns to the initial position the element was before mounted.
133+
120134
121135
#### stopDragging
122136
Type: `Boolean`<br>
123-
Required: `false`
137+
Required: `false`<br>
138+
default: `undefined`<br>
139+
140+
Immediately stop dragging.
141+
142+
143+
#### boundingRect
144+
Type: `ClientRect`<br>
145+
Required: `false`<br>
146+
default: `undefined`<br>
147+
148+
Constrains dragging to within the bounds of the rectangle.

dist/draggable.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface DraggableValue {
88
onPositionChange?: (pos: Position) => void;
99
resetInitialPos?: boolean;
1010
stopDragging?: boolean;
11+
boundingRect?: ClientRect;
1112
}
1213
export interface DraggableBindings {
1314
value: DraggableValue;

dist/draggable.js

Lines changed: 26 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/draggable.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/draggable.ts

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface DraggableValue {
1010
onPositionChange?: (pos: Position) => void;
1111
resetInitialPos?: boolean;
1212
stopDragging?: boolean;
13+
boundingRect?: ClientRect;
1314
}
1415

1516
export interface DraggableBindings {
@@ -25,30 +26,57 @@ function extractHandle(handle: HandleType): HTMLElement {
2526
}
2627
}
2728

29+
function isInBoundries(elementRect?: ClientRect, boundingRect?: ClientRect, dx: number = 0, dy: number = 0): boolean {
30+
if (boundingRect && elementRect) {
31+
const actualMaxTop = elementRect.top + elementRect.height + dy;
32+
const maxTop = boundingRect.bottom;
33+
34+
const actualMinTop = elementRect.top + dy;
35+
const minTop = boundingRect.top;
36+
37+
const actualMaxLeft = elementRect.left + dx;
38+
const maxLeft = boundingRect.right - elementRect.width;
39+
40+
const actualMinLeft = elementRect.left + dx;
41+
const minLeft = boundingRect.left;
42+
43+
if ((actualMaxTop > maxTop && actualMaxTop - dy > maxTop) ||
44+
(actualMinTop < minTop && actualMinTop - dy < minTop) ||
45+
(actualMaxLeft > maxLeft && actualMaxLeft - dx > maxLeft) ||
46+
(actualMinLeft < minLeft && actualMinLeft - dx < minLeft)) {
47+
return false;
48+
}
49+
}
50+
51+
return true
52+
}
53+
2854
export const Draggable = {
29-
bind(el: HTMLElement, binding: DraggableBindings) {
30-
Draggable.update(el, binding);
31-
},
55+
bind(el: HTMLElement, binding: DraggableBindings) {
56+
Draggable.update(el, binding);
57+
},
3258
update(el: HTMLElement, binding: DraggableBindings) {
3359
if (binding.value && binding.value.stopDragging) {
3460
return;
3561
}
3662

3763
const handler = (binding.value && binding.value.handle && extractHandle(binding.value.handle)) || el;
38-
const safeDistance = 5;
3964
init(binding);
4065

4166
function mouseMove(event: MouseEvent) {
4267
event.preventDefault();
4368
const state = getState();
4469
const dx = event.clientX - state.initialMousePos.x;
4570
const dy = event.clientY - state.initialMousePos.y;
46-
if (el.scrollHeight + event.clientY > window.innerHeight - safeDistance ||
47-
event.clientY - safeDistance < 0 ||
48-
el.scrollWidth + event.clientX > window.innerWidth - safeDistance ||
49-
event.clientX - el.scrollWidth < safeDistance) {
71+
72+
const boundingRect = binding.value && binding.value.boundingRect;
73+
const stopDragging = binding.value && binding.value.stopDragging;
74+
var elementRect = el.getBoundingClientRect();
75+
76+
if (!isInBoundries(elementRect, boundingRect, dx, dy) || stopDragging) {
5077
return;
5178
}
79+
5280
state.lastPos = {
5381
x: state.startPosition.x + dx,
5482
y: state.startPosition.y + dy
@@ -109,12 +137,12 @@ export const Draggable = {
109137
function getState() {
110138
return JSON.parse(handler.getAttribute("draggable-state") as string);
111139
}
112-
140+
113141
if (!handler.getAttribute("draggable")) {
114142
el.removeEventListener("mousedown", (el as any)["listener"]);
115143
handler.addEventListener("mousedown", mouseDown);
116-
handler.setAttribute("draggable", "true");
117-
(el as any)["listener"] = mouseDown;
144+
handler.setAttribute("draggable", "true");
145+
(el as any)["listener"] = mouseDown;
118146
setState(getInitState());
119147
onPositionChanged();
120148
}

0 commit comments

Comments
 (0)