Skip to content

Commit ae4921b

Browse files
committed
feat(draggable): support horizontal scrolling while dragging
1 parent 2988e7d commit ae4921b

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

src/jquery.draggable.js

+56-36
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@
2525
};
2626

2727
var $window = $(window);
28+
var dir_map = { x : 'left', y : 'top' };
2829
var isTouch = !!('ontouchstart' in window);
2930
var pointer_events = {
3031
start: isTouch ? 'touchstart.gridster-draggable' : 'mousedown.gridster-draggable',
3132
move: isTouch ? 'touchmove.gridster-draggable' : 'mousemove.gridster-draggable',
3233
end: isTouch ? 'touchend.gridster-draggable' : 'mouseup.gridster-draggable'
3334
};
3435

36+
var capitalize = function(str) {
37+
return str.charAt(0).toUpperCase() + str.slice(1);
38+
};
39+
3540
/**
3641
* Basic drag implementation for DOM elements inside a container.
3742
* Provide start/stop/drag callbacks.
@@ -123,9 +128,10 @@
123128
mouse_actual_pos.left - this.mouse_init_pos.left);
124129
var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top);
125130

126-
var left = Math.round(this.el_init_offset.left + diff_x - this.baseX);
127-
var top = Math.round(
128-
this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset);
131+
var left = Math.round(this.el_init_offset.left +
132+
diff_x - this.baseX + this.scroll_offset_x);
133+
var top = Math.round(this.el_init_offset.top +
134+
diff_y - this.baseY + this.scroll_offset_y);
129135

130136
if (this.options.limit) {
131137
if (left > this.player_max_left) {
@@ -143,8 +149,8 @@
143149
pointer: {
144150
left: mouse_actual_pos.left,
145151
top: mouse_actual_pos.top,
146-
diff_left: diff_x,
147-
diff_top: diff_y + this.scrollOffset
152+
diff_left: diff_x + this.scroll_offset_x,
153+
diff_top: diff_y + this.scroll_offset_y
148154
}
149155
};
150156
};
@@ -159,42 +165,57 @@
159165
};
160166

161167

162-
fn.manage_scroll = function(data) {
163-
/* scroll document */
164-
var nextScrollTop;
165-
var scrollTop = $window.scrollTop();
166-
var min_window_y = scrollTop;
167-
var max_window_y = min_window_y + this.window_height;
168-
169-
var mouse_down_zone = max_window_y - 50;
170-
var mouse_up_zone = min_window_y + 50;
171-
172-
var abs_mouse_left = data.pointer.left;
173-
var abs_mouse_top = min_window_y + data.pointer.top;
174-
175-
var max_player_y = (this.doc_height - this.window_height +
176-
this.player_height);
177-
178-
if (abs_mouse_top >= mouse_down_zone) {
179-
nextScrollTop = scrollTop + 30;
180-
if (nextScrollTop < max_player_y) {
181-
$window.scrollTop(nextScrollTop);
182-
this.scrollOffset = this.scrollOffset + 30;
168+
fn.scroll_in = function(axis, data) {
169+
var dir_prop = dir_map[axis];
170+
171+
var area_size = 50;
172+
var scroll_inc = 30;
173+
174+
var is_x = axis === 'x';
175+
var window_size = is_x ? this.window_width : this.window_height;
176+
var doc_size = is_x ? $(document).width() : $(document).height();
177+
var player_size = is_x ? this.$player.width() : this.$player.height();
178+
179+
var next_scroll;
180+
var scroll_offset = $window['scroll' + capitalize(dir_prop)]();
181+
var min_window_pos = scroll_offset;
182+
var max_window_pos = min_window_pos + window_size;
183+
184+
var mouse_next_zone = max_window_pos - area_size; // down/right
185+
var mouse_prev_zone = min_window_pos + area_size; // up/left
186+
187+
var abs_mouse_pos = min_window_pos + data.pointer[dir_prop];
188+
189+
var max_player_pos = (doc_size - window_size + player_size);
190+
191+
if (abs_mouse_pos >= mouse_next_zone) {
192+
next_scroll = scroll_offset + scroll_inc;
193+
if (next_scroll < max_player_pos) {
194+
$window['scroll' + capitalize(dir_prop)](next_scroll);
195+
this['scroll_offset_' + axis] += scroll_inc;
183196
}
184197
}
185198

186-
if (abs_mouse_top <= mouse_up_zone) {
187-
nextScrollTop = scrollTop - 30;
188-
if (nextScrollTop > 0) {
189-
$window.scrollTop(nextScrollTop);
190-
this.scrollOffset = this.scrollOffset - 30;
199+
if (abs_mouse_pos <= mouse_prev_zone) {
200+
next_scroll = scroll_offset - scroll_inc;
201+
if (next_scroll > 0) {
202+
$window['scroll' + capitalize(dir_prop)](next_scroll);
203+
this['scroll_offset_' + axis] -= scroll_inc;
191204
}
192205
}
206+
207+
return this;
193208
};
194209

195210

196211
fn.calculate_positions = function(e) {
212+
fn.manage_scroll = function(data) {
213+
this.scroll_in('x', data);
214+
this.scroll_in('y', data);
215+
};
216+
197217
this.window_height = $window.height();
218+
this.window_width = $window.width();
198219
};
199220

200221

@@ -254,7 +275,7 @@
254275
var offset = this.$container.offset();
255276
this.baseX = Math.round(offset.left);
256277
this.baseY = Math.round(offset.top);
257-
this.doc_height = $(document).height();
278+
this.initial_container_width = this.options.container_width || this.$container.width();
258279

259280
if (this.options.helper === 'clone') {
260281
this.$helper = this.$player.clone()
@@ -264,14 +285,13 @@
264285
this.helper = false;
265286
}
266287

267-
this.scrollOffset = 0;
288+
this.scroll_offset_y = 0;
289+
this.scroll_offset_x = 0;
268290
this.el_init_offset = this.$player.offset();
269291
this.player_width = this.$player.width();
270292
this.player_height = this.$player.height();
271293

272-
var container_width = this.options.container_width || this.$container.width();
273-
this.player_max_left = (container_width - this.player_width +
274-
this.options.offset_left);
294+
this.set_limits(this.options.container_width);
275295

276296
if (this.options.start) {
277297
this.options.start.call(this.$player, e, this.get_drag_data(e));

0 commit comments

Comments
 (0)