/
Drag.Move.js
119 lines (97 loc) · 3.33 KB
/
Drag.Move.js
1
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
Script: Drag.Move.js
A Drag extension that provides support for the constraining of draggables to containers and droppables.
License:
MIT-style license.
Authors:
Valerio Proietti
Tom Occhinno
Jan Kassens*/
Drag.Move = new Class({
Extends: Drag,
options: {/*
onEnter: $empty(thisElement, overed),
onLeave: $empty(thisElement, overed),
onDrop: $empty(thisElement, overed, event),*/
droppables: [],
container: false,
precalculate: false,
includeMargins: true,
checkDroppables: true
},
initialize: function(element, options){
this.parent(element, options);
this.droppables = $$(this.options.droppables);
this.container = $(this.options.container);
if (this.container && $type(this.container) != 'element') this.container = $(this.container.getDocument().body);
var position = this.element.getStyle('position');
if (position=='static') position = 'absolute';
if ([this.element.getStyle('left'), this.element.getStyle('top')].contains('auto')) this.element.position(this.element.getPosition(this.element.offsetParent));
this.element.setStyle('position', position);
this.addEvent('start', this.checkDroppables, true);
this.overed = null;
},
start: function(event){
if (this.container){
var ccoo = this.container.getCoordinates(this.element.getOffsetParent()), cbs = {}, ems = {};
['top', 'right', 'bottom', 'left'].each(function(pad){
cbs[pad] = this.container.getStyle('border-' + pad).toInt();
ems[pad] = this.element.getStyle('margin-' + pad).toInt();
}, this);
var width = this.element.offsetWidth + ems.left + ems.right;
var height = this.element.offsetHeight + ems.top + ems.bottom;
if (this.options.includeMargins) {
$each(ems, function(value, key) {
ems[key] = 0;
});
}
if (this.container == this.element.getOffsetParent()) {
this.options.limit = {
x: [0 - ems.left, ccoo.right - cbs.left - cbs.right - width + ems.right],
y: [0 - ems.top, ccoo.bottom - cbs.top - cbs.bottom - height + ems.bottom]
};
} else {
this.options.limit = {
x: [ccoo.left + cbs.left - ems.left, ccoo.right - cbs.right - width + ems.right],
y: [ccoo.top + cbs.top - ems.top, ccoo.bottom - cbs.bottom - height + ems.bottom]
};
}
}
if (this.options.precalculate){
this.positions = this.droppables.map(function(el) {
return el.getCoordinates();
});
}
this.parent(event);
},
checkAgainst: function(el, i){
el = (this.positions) ? this.positions[i] : el.getCoordinates();
var now = this.mouse.now;
return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
},
checkDroppables: function(){
var overed = this.droppables.filter(this.checkAgainst, this).getLast();
if (this.overed != overed){
if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
if (overed) this.fireEvent('enter', [this.element, overed]);
this.overed = overed;
}
},
drag: function(event){
this.parent(event);
if (this.options.checkDroppables && this.droppables.length) this.checkDroppables();
},
stop: function(event){
this.checkDroppables();
this.fireEvent('drop', [this.element, this.overed, event]);
this.overed = null;
return this.parent(event);
}
});
Element.implement({
makeDraggable: function(options){
var drag = new Drag.Move(this, options);
this.store('dragger', drag);
return drag;
}
});