Skip to content

Commit a500a60

Browse files
committed
Merge branch 'snap-restrict-element-rect'
Conflicts: interact.js
2 parents cf1d6ad + e7196c9 commit a500a60

File tree

1 file changed

+107
-29
lines changed

1 file changed

+107
-29
lines changed

interact.js

Lines changed: 107 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@
7171
tapTime = 0, // time of the most recent tap event
7272
prevTap = null,
7373

74+
startOffset = { left: 0, right: 0, top: 0, bottom: 0 },
75+
restrictOffset = { left: 0, right: 0, top: 0, bottom: 0 },
76+
snapOffset = { x: 0, y: 0},
77+
7478
tmpXY = {}, // reduce object creation in getXY()
7579

7680
inertiaStatus = {
@@ -168,8 +172,10 @@
168172
anchors : [],
169173
paths : [],
170174

175+
elementOrigin: null,
176+
171177
arrayTypes : /^anchors$|^paths$|^actions$/,
172-
objectTypes : /^grid$|^gridOffset$/,
178+
objectTypes : /^grid$|^gridOffset$|^elementOrigin$/,
173179
stringTypes : /^mode$/,
174180
numberTypes : /^range$/,
175181
boolTypes : /^endOnly$/
@@ -182,7 +188,7 @@
182188
gesture: null,
183189
endOnly: false
184190
},
185-
restrictEnabled: true,
191+
restrictEnabled: false,
186192

187193
autoScroll: {
188194
container : window, // the item that is scrolled (Window or HTMLElement)
@@ -1094,6 +1100,30 @@
10941100
return (axis === 'xy' || thisAxis === 'xy' || thisAxis === axis);
10951101
}
10961102

1103+
function checkSnap (interactable, action) {
1104+
var options = interactable.options;
1105+
1106+
action = action || prepared;
1107+
1108+
if (/^resize/.test(action)) {
1109+
action = 'resize';
1110+
}
1111+
1112+
return (options.snapEnabled && indexOf(options.snap.actions, action) !== -1);
1113+
}
1114+
1115+
function checkRestrict (interactable, action) {
1116+
var options = interactable.options;
1117+
1118+
action = action || prepared;
1119+
1120+
if (/^resize/.test(action)) {
1121+
action = 'resize';
1122+
}
1123+
1124+
return options.restrictEnabled && options.restrict[action];
1125+
}
1126+
10971127
function collectDrops (event, element) {
10981128
var drops = [],
10991129
elements = [],
@@ -1387,7 +1417,7 @@
13871417
client.x -= origin.x;
13881418
client.y -= origin.y;
13891419

1390-
if (options.snapEnabled && indexOf(options.snap.actions, action) !== -1) {
1420+
if (checkSnap(target) && !(phase === 'start' && options.snap.elementOrigin)) {
13911421

13921422
this.snap = {
13931423
range : snapStatus.range,
@@ -1409,7 +1439,7 @@
14091439
}
14101440
}
14111441

1412-
if (target.options.restrict[action] && restrictStatus.restricted) {
1442+
if (checkRestrict(target) && !(phase === 'start' && options.restrict.elementRect) && restrictStatus.restricted) {
14131443
page.x += restrictStatus.dx;
14141444
page.y += restrictStatus.dy;
14151445
client.x += restrictStatus.dx;
@@ -2088,8 +2118,8 @@
20882118

20892119
range = typeof anchor.range === 'number'? anchor.range: snap.range;
20902120

2091-
dx = anchor.x - page.x;
2092-
dy = anchor.y - page.y;
2121+
dx = anchor.x - page.x + snapOffset.x;
2122+
dy = anchor.y - page.y + snapOffset.y;
20932123
distance = hypot(dx, dy);
20942124

20952125
inRange = distance < range;
@@ -2134,11 +2164,11 @@
21342164
status.dy = closest.dy;
21352165
}
21362166
else if (snap.mode === 'grid') {
2137-
var gridx = Math.round((page.x - snap.gridOffset.x) / snap.grid.x),
2138-
gridy = Math.round((page.y - snap.gridOffset.y) / snap.grid.y),
2167+
var gridx = Math.round((page.x - snap.gridOffset.x - snapOffset.x) / snap.grid.x),
2168+
gridy = Math.round((page.y - snap.gridOffset.y - snapOffset.y) / snap.grid.y),
21392169

2140-
newX = gridx * snap.grid.x + snap.gridOffset.x,
2141-
newY = gridy * snap.grid.y + snap.gridOffset.y;
2170+
newX = gridx * snap.grid.x + snap.gridOffset.x + snapOffset.x,
2171+
newY = gridy * snap.grid.y + snap.gridOffset.y + snapOffset.y;
21422172

21432173
dx = newX - page.x;
21442174
dy = newY - page.y;
@@ -2163,10 +2193,14 @@
21632193
}
21642194

21652195
function setRestriction (event, status) {
2166-
var action = interact.currentAction() || prepared,
2167-
restriction = target && target.options.restrict[action],
2196+
var restrict = target && target.options.restrict,
2197+
restriction = restrict && restrict[prepared],
21682198
page;
21692199

2200+
if (!restriction) {
2201+
return status;
2202+
}
2203+
21702204
status = status || restrictStatus;
21712205

21722206
page = status.useStatusXY
@@ -2185,10 +2219,6 @@
21852219
status.dy = 0;
21862220
status.restricted = false;
21872221

2188-
if (!action || !restriction) {
2189-
return status;
2190-
}
2191-
21922222
var rect;
21932223

21942224
if (restriction === 'parent') {
@@ -2221,8 +2251,8 @@
22212251
}
22222252
}
22232253

2224-
status.dx = Math.max(Math.min(rect.right , page.x), rect.left) - page.x;
2225-
status.dy = Math.max(Math.min(rect.bottom, page.y), rect.top ) - page.y;
2254+
status.dx = Math.max(Math.min(rect.right - restrictOffset.right , page.x), rect.left + restrictOffset.left) - page.x;
2255+
status.dy = Math.max(Math.min(rect.bottom - restrictOffset.bottom, page.y), rect.top + restrictOffset.top ) - page.y;
22262256
status.restricted = true;
22272257

22282258
return status;
@@ -2338,22 +2368,54 @@
23382368
}
23392369

23402370
if (prepared && target) {
2341-
var shouldRestrict = target.options.restrictEnabled && (!target.options.restrict.endOnly || preEnd),
2371+
var shouldRestrict = checkRestrict(target) && (!target.options.restrict.endOnly || preEnd),
23422372
starting = !(dragging || resizing || gesturing),
23432373
snapEvent = starting? downEvent: event;
23442374

23452375
if (starting) {
23462376
prevEvent = downEvent;
2377+
2378+
var rect = target.getRect(),
2379+
snap = target.options.snap,
2380+
restrict = target.options.restrict;
2381+
2382+
if (rect) {
2383+
startOffset.left = startCoords.pageX - rect.left;
2384+
startOffset.top = startCoords.pageY - rect.top;
2385+
2386+
startOffset.right = rect.right - startCoords.pageX;
2387+
startOffset.bottom = rect.bottom - startCoords.pageY;
2388+
}
2389+
else {
2390+
startOffset.left = startOffset.top = startOffset.right = startOffset.bottom = 0;
2391+
}
2392+
2393+
if (rect && snap.elementOrigin) {
2394+
snapOffset.x = startOffset.left + (rect.width * snap.elementOrigin.x);
2395+
snapOffset.y = startOffset.top + (rect.height * snap.elementOrigin.y);
2396+
}
2397+
else {
2398+
snapOffset.x = snapOffset.y = 0;
2399+
}
2400+
2401+
if (rect && restrict.elementRect) {
2402+
restrictOffset.left = startOffset.left - (rect.width * restrict.elementRect.left);
2403+
restrictOffset.top = startOffset.top - (rect.height * restrict.elementRect.top);
2404+
2405+
restrictOffset.right = startOffset.right - (rect.width * (1 - restrict.elementRect.right));
2406+
restrictOffset.bottom = startOffset.bottom - (rect.height * (1 - restrict.elementRect.bottom));
2407+
}
2408+
else {
2409+
restrictOffset.left = restrictOffset.top = restrictOffset.right = restrictOffset.bottom = 0;
2410+
}
23472411
}
23482412

23492413
if (!shouldRestrict) {
23502414
restrictStatus.restricted = false;
23512415
}
23522416

23532417
// check for snap
2354-
if (target.options.snapEnabled
2355-
&& indexOf(target.options.snap.actions, prepared) !== -1
2356-
&& (!target.options.snap.endOnly || preEnd)) {
2418+
if (checkSnap(target) && (!target.options.snap.endOnly || preEnd)) {
23572419

23582420
setSnapping(snapEvent);
23592421

@@ -2871,7 +2933,7 @@
28712933
}
28722934
}
28732935

2874-
if (options.restrictEnabled && options.restrict.endOnly) {
2936+
if (checkRestrict(target) && target.options.restrict.endOnly) {
28752937
var restrict = setRestriction(event, statusObject);
28762938

28772939
if (restrict.restricted) {
@@ -2899,8 +2961,8 @@
28992961
return;
29002962
}
29012963

2902-
if ((options.snapEnabled && options.snap.endOnly)
2903-
|| (options.restrictEnabled && options.restrict.endOnly)) {
2964+
if ((checkSnap(target) && target.options.snap.endOnly)
2965+
|| (checkRestrict(target) && target.options.restrict.endOnly)) {
29042966
// fire a move event at the snapped coordinates
29052967
pointerMove(event, true);
29062968
}
@@ -3629,6 +3691,7 @@
36293691
snap.grid = this.validateSetting('snap', 'grid' , options.grid);
36303692
snap.gridOffset = this.validateSetting('snap', 'gridOffset', options.gridOffset);
36313693
snap.anchors = this.validateSetting('snap', 'anchors' , options.anchors);
3694+
snap.elementOrigin = this.validateSetting('snap', 'elementOrigin' , options.elementOrigin);
36323695

36333696
this.options.snapEnabled = true;
36343697
this.options.snap = snap;
@@ -3977,7 +4040,10 @@
39774040
return this.options.restrict;
39784041
}
39794042

3980-
if (newValue instanceof Object) {
4043+
if (typeof newValue === 'boolean') {
4044+
defaultOptions.restrictEnabled = newValue;
4045+
}
4046+
else if (newValue instanceof Object) {
39814047
var newRestrictions = {};
39824048

39834049
if (newValue.drag instanceof Object || /^parent$|^self$/.test(newValue.drag)) {
@@ -3994,10 +4060,13 @@
39944060
newRestrictions.endOnly = newValue.endOnly;
39954061
}
39964062

4063+
if (newValue.elementRect instanceof Object) {
4064+
newRestrictions.elementRect = newValue.elementRect;
4065+
}
4066+
39974067
this.options.restrictEnabled = true;
39984068
this.options.restrict = newRestrictions;
39994069
}
4000-
40014070
else if (newValue === null) {
40024071
delete this.options.restrict;
40034072
delete this.options.restrictEnabled;
@@ -4886,6 +4955,7 @@
48864955
if (options.anchors instanceof Array ) { snap.anchors = options.anchors; }
48874956
if (options.grid instanceof Object) { snap.grid = options.grid; }
48884957
if (options.gridOffset instanceof Object) { snap.gridOffset = options.gridOffset; }
4958+
if (options.elementOrigin instanceof Object) { snap.elementOrigin = options.elementOrigin; }
48894959

48904960
return interact;
48914961
}
@@ -5093,7 +5163,10 @@
50935163
return defaultOptions.restrict;
50945164
}
50955165

5096-
if (newValue instanceof Object) {
5166+
if (typeof newValue === 'boolean') {
5167+
defaultOptions.restrictEnabled = newValue;
5168+
}
5169+
else if (newValue instanceof Object) {
50975170
if (newValue.drag instanceof Object || /^parent$|^self$/.test(newValue.drag)) {
50985171
defaults.drag = newValue.drag;
50995172
}
@@ -5107,8 +5180,13 @@
51075180
if (typeof newValue.endOnly === 'boolean') {
51085181
defaults.endOnly = newValue.endOnly;
51095182
}
5110-
}
51115183

5184+
if (newValue.elementRect instanceof Object) {
5185+
defaults.elementRect = newValue.elementRect;
5186+
}
5187+
5188+
defaultOptions.restrictEnabled = true;
5189+
}
51125190
else if (newValue === null) {
51135191
defaults.drag = defaults.resize = defaults.gesture = null;
51145192
defaults.endOnly = false;

0 commit comments

Comments
 (0)