[2] | 1 | // This is an extension to jQuery UI draggable |
---|
| 2 | // When dragging move the parent element ("panel") relative to its parent |
---|
| 3 | // ("viewport") so that the draggable is always visible. |
---|
| 4 | |
---|
| 5 | $.ui.plugin.add("draggable", "scrollPanel", { |
---|
| 6 | drag: function(e, ui) { |
---|
| 7 | var instance = $(this).data("draggable"); |
---|
| 8 | clearTimeout( instance.timeout ); |
---|
| 9 | var o = ui.options, |
---|
| 10 | element = instance.element, |
---|
| 11 | panel = o.panel, |
---|
| 12 | panel_pos = panel.position(), |
---|
| 13 | panel_w = panel.width(), |
---|
| 14 | panel_h = panel.height() |
---|
| 15 | viewport = panel.parent(); |
---|
| 16 | viewport_w = viewport.width(), |
---|
| 17 | viewport_h = viewport.height(), |
---|
| 18 | element_w = element.width(), |
---|
| 19 | element_h = element.height(), |
---|
| 20 | moved = false, |
---|
| 21 | close_dist = 5, |
---|
| 22 | nudge = 23, |
---|
| 23 | // Legal panel range |
---|
| 24 | p_min_x = - ( panel_w - viewport_w ), |
---|
| 25 | p_min_y = - ( panel_h - viewport_h ), |
---|
| 26 | p_max_x = 0, |
---|
| 27 | p_max_y = 0, |
---|
| 28 | // Visible |
---|
| 29 | min_vis_x = - panel_pos.left, |
---|
| 30 | max_vis_x = min_vis_x + viewport_w, |
---|
| 31 | min_vis_y = - panel_pos.top, |
---|
| 32 | max_vis_y = min_vis_y + viewport_h, |
---|
| 33 | // Mouse |
---|
| 34 | mouse_x = ui.position.left + instance.offset.click.left; |
---|
| 35 | mouse_y = ui.position.top + instance.offset.click.top; |
---|
| 36 | // Move it |
---|
| 37 | if ( ( panel_pos.left < p_max_x ) && ( mouse_x - close_dist < min_vis_x ) ) { |
---|
| 38 | var t = Math.min( nudge, p_max_x - panel_pos.left ); |
---|
| 39 | panel.css( "left", panel_pos.left + t ); |
---|
| 40 | moved = true; |
---|
| 41 | instance.offset.parent.left += t; |
---|
| 42 | ui.position.left -= t |
---|
| 43 | } |
---|
| 44 | if ( ( ! moved ) && ( panel_pos.left > p_min_x ) && ( mouse_x + close_dist > max_vis_x ) ) { |
---|
| 45 | var t = Math.min( nudge, panel_pos.left - p_min_x ); |
---|
| 46 | panel.css( "left", panel_pos.left - t ); |
---|
| 47 | moved = true; |
---|
| 48 | instance.offset.parent.left -= t; |
---|
| 49 | ui.position.left += t; |
---|
| 50 | } |
---|
| 51 | if ( ( ! moved ) && ( panel_pos.top < p_max_y ) && ( mouse_y - close_dist < min_vis_y ) ) { |
---|
| 52 | var t = Math.min( nudge, p_max_y - panel_pos.top ); |
---|
| 53 | panel.css( "top", panel_pos.top + t ); |
---|
| 54 | // Firefox sometimes moves by less, so we need to check. Yuck. |
---|
| 55 | var amount_moved = panel.position().top - panel_pos.top; |
---|
| 56 | instance.offset.parent.top += amount_moved; |
---|
| 57 | ui.position.top -= amount_moved; |
---|
| 58 | moved = true; |
---|
| 59 | } |
---|
| 60 | if ( ( ! moved ) && ( panel_pos.top > p_min_y ) && ( mouse_y + close_dist > max_vis_y ) ) { |
---|
| 61 | var t = Math.min( nudge, panel_pos.top - p_min_x ); |
---|
| 62 | panel.css( "top", ( panel_pos.top - t ) + "px" ); |
---|
| 63 | // Firefox sometimes moves by less, so we need to check. Yuck. |
---|
| 64 | var amount_moved = panel_pos.top - panel.position().top; |
---|
| 65 | instance.offset.parent.top -= amount_moved; |
---|
| 66 | ui.position.top += amount_moved; |
---|
| 67 | moved = true; |
---|
| 68 | } |
---|
| 69 | // Still contain in panel |
---|
| 70 | ui.position.left = Math.max( ui.position.left, 0 ); |
---|
| 71 | ui.position.top = Math.max( ui.position.top, 0 ); |
---|
| 72 | ui.position.left = Math.min( ui.position.left, panel_w - element_w ); |
---|
| 73 | ui.position.top = Math.min( ui.position.top, panel_h - element_h ); |
---|
| 74 | // Update offsets |
---|
| 75 | if ( moved ) { |
---|
| 76 | $.ui.ddmanager.prepareOffsets( instance, e ); |
---|
| 77 | } |
---|
| 78 | // Keep moving even if mouse doesn't move |
---|
| 79 | if ( moved ) { |
---|
| 80 | instance.old_e = e; |
---|
| 81 | instance.timeout = setTimeout( function() { instance.mouseMove( e ) }, 50 ); |
---|
| 82 | } |
---|
| 83 | }, |
---|
| 84 | stop: function( e, ui ) { |
---|
| 85 | var instance = $(this).data("draggable"); |
---|
| 86 | clearTimeout( instance.timeout ); |
---|
| 87 | } |
---|
| 88 | }); |
---|