From cadeaa9dc1e37a528443a41e9907cf0b402b56e4 Mon Sep 17 00:00:00 2001 From: Zach Wise Date: Mon, 2 Jul 2012 13:00:11 -0500 Subject: [PATCH] Rewrote DragSlider. Much, much better now. Includes scrolling and constraints --- source/js/Slider/VMM.DragSlider.js | 270 +++++++++++++++++------------ source/js/VMM.Timeline.TimeNav.js | 49 ++++-- 2 files changed, 196 insertions(+), 123 deletions(-) diff --git a/source/js/Slider/VMM.DragSlider.js b/source/js/Slider/VMM.DragSlider.js index 87d14d0..ab7e619 100644 --- a/source/js/Slider/VMM.DragSlider.js +++ b/source/js/Slider/VMM.DragSlider.js @@ -3,145 +3,201 @@ if(typeof VMM != 'undefined' && typeof VMM.DragSlider == 'undefined') { // VMM.DragSlider.createSlidePanel(drag_object, move_object, w, padding, sticky); // VMM.DragSlider.cancelSlide(); - VMM.DragSlider = { - createPanel: function(drag_object, move_object, w, padding, sticky) { - + VMM.DragSlider = function() { + var drag = { + element: "", + element_move: "", + constraint: "", + sliding: false, + pagex: { + start: 0, + end: 0 + }, + left: { + start: 0, + end: 0 + }, + time: { + start: 0, + end: 0 + }, + touch: false + }, + dragevent = { + down: "mousedown", + up: "mouseup", + leave: "mouseleave", + move: "mousemove" + }, + mousedrag = { + down: "mousedown", + up: "mouseup", + leave: "mouseleave", + move: "mousemove" + }, + touchdrag = { + down: "touchstart", + up: "touchend", + leave: "mouseleave", + move: "touchmove" + }; + + this.createPanel = function(drag_object, move_object, constraint, touch) { + drag.element = drag_object; + drag.element_move = move_object; - var x = padding; - VMM.DragSlider.width = w; - VMM.DragSlider.makeDraggable(drag_object, move_object); - VMM.DragSlider.drag_elem = drag_object; - /* - if (sticky != null && sticky != "") { - VMM.TouchSlider.sticky = sticky; + if ( constraint != null && constraint != "") { + drag.constraint = constraint; } else { - VMM.TouchSlider.sticky = false; + drag.constraint = false; } - */ - VMM.DragSlider.sticky = sticky; - }, - makeDraggable: function(drag_object, move_object) { - VMM.bindEvent(drag_object, VMM.DragSlider.onDragStart, "mousedown", {element: move_object, delement: drag_object}); - //VMM.bindEvent(drag_object, VMM.DragSlider.onDragMove, "mousemove", {element: move_object}); - VMM.bindEvent(drag_object, VMM.DragSlider.onDragEnd, "mouseup", {element: move_object, delement: drag_object}); - VMM.bindEvent(drag_object, VMM.DragSlider.onDragLeave, "mouseleave", {element: move_object, delement: drag_object}); - }, - cancelSlide: function(e) { - VMM.unbindEvent(VMM.DragSlider.drag_elem, VMM.DragSlider.onDragMove, "mousemove"); - //VMM.DragSlider.drag_elem.preventDefault(); - //VMM.DragSlider.drag_elem.stopPropagation(); + if ( touch) { + drag.touch = touch; + } else { + drag.touch = false; + } + trace("TOUCH" + drag.touch); + if (drag.touch) { + dragevent = touchdrag; + } else { + dragevent = mousedrag; + } + + makeDraggable(drag.element, drag.element_move); + } + + this.updateConstraint = function(constraint) { + trace("updateConstraint"); + drag.constraint = constraint; + } + + var makeDraggable = function(drag_object, move_object) { + + VMM.bindEvent(drag_object, onDragStart, dragevent.down, {element: move_object, delement: drag_object}); + VMM.bindEvent(drag_object, onDragEnd, dragevent.up, {element: move_object, delement: drag_object}); + VMM.bindEvent(drag_object, onDragLeave, dragevent.leave, {element: move_object, delement: drag_object}); + + } + this.cancelSlide = function(e) { + VMM.unbindEvent(drag.element, onDragMove, dragevent.move); return true; - }, - onDragLeave: function(e) { - - VMM.unbindEvent(e.data.delement, VMM.DragSlider.onDragMove, "mousemove"); + } + var onDragLeave = function(e) { + VMM.unbindEvent(e.data.delement, onDragMove, dragevent.move); e.preventDefault(); e.stopPropagation(); - return true; - }, - onDragStart: function(e) { - VMM.DragSlider.dragStart(e.data.element, e.data.delement, e); - + if (drag.sliding) { + drag.sliding = false; + dragEnd(e.data.element, e.data.delement, e); + return false; + } else { + return true; + } + } + + var onDragStart = function(e) { + dragStart(e.data.element, e.data.delement, e); e.preventDefault(); e.stopPropagation(); return true; - }, - onDragEnd: function(e) { + } + + var onDragEnd = function(e) { e.preventDefault(); e.stopPropagation(); - - if (VMM.DragSlider.sliding) { - VMM.DragSlider.sliding = false; - VMM.DragSlider.dragEnd(e.data.element, e.data.delement, e); + if (drag.sliding) { + drag.sliding = false; + dragEnd(e.data.element, e.data.delement, e); return false; } else { return true; } - - }, - onDragMove: function(e) { - VMM.DragSlider.dragMove(e.data.element, e); + } + var onDragMove = function(e) { + dragMove(e.data.element, e); e.preventDefault(); e.stopPropagation(); return false; - }, - dragStart: function(elem, delem, e) { - - VMM.DragSlider.startX = e.pageX; - - VMM.DragSlider.startLeft = VMM.DragSlider.getLeft(elem); - VMM.DragSlider.dragStartTime = new Date().getTime(); - VMM.DragSlider.dragWidth = VMM.Lib.width(delem); - - // CANCEL CURRENT ANIMATION IF ANIMATING - var _newx = Math.round(VMM.DragSlider.startX - e.pageX - VMM.DragSlider.startLeft); + } + var dragStart = function(elem, delem, e) { + if (drag.touch) { + trace("IS TOUCH") + VMM.Lib.css(elem, '-webkit-transition-duration', '0'); + drag.pagex.start = e.originalEvent.touches[0].screenX; + } else { + drag.pagex.start = e.pageX; + } + drag.left.start = getLeft(elem); + drag.time.start = new Date().getTime(); VMM.Lib.stop(elem); - VMM.bindEvent(delem, VMM.DragSlider.onDragMove, "mousemove", {element: elem}); + VMM.bindEvent(delem, onDragMove, dragevent.move, {element: elem}); - }, - dragEnd: function(elem, delem, e) { - VMM.unbindEvent(delem, VMM.DragSlider.onDragMove, "mousemove"); - //VMM.DragSlider.dragMomentum(elem, e); - if (VMM.DragSlider.getLeft(elem) > 0) { - //(VMM.DragSlider.dragWidth/2) - //This means they dragged to the right past the first item - //VMM.Lib.animate(elem, 1000, "linear", {"left": 0}); - - //VMM.fireEvent(elem, "DRAGUPDATE", [0]); + } + var dragEnd = function(elem, delem, e) { + VMM.unbindEvent(delem, onDragMove, dragevent.move); + dragMomentum(elem, e); + } + var dragMove = function(elem, e) { + drag.sliding = true; + if (drag.touch) { + drag.pagex.end = e.originalEvent.touches[0].screenX; } else { - //This means they were just dragging within the bounds of the grid and we just need to handle the momentum and snap to the grid. - VMM.DragSlider.dragMomentum(elem, e); - } - }, - dragMove: function(elem, e) { - if (!VMM.DragSlider.sliding) { - //elem.parent().addClass('sliding'); + drag.pagex.end = e.pageX; } + drag.left.end = getLeft(elem); + VMM.Lib.css(elem, 'left', -(drag.pagex.start - drag.pagex.end - drag.left.start)); + } + var dragMomentum = function(elem, e) { + var drag_info = { + left: drag.left.end, + left_adjust: 0, + change: { + x: 0 + }, + time: (new Date().getTime() - drag.time.start) * 10, + time_adjust: (new Date().getTime() - drag.time.start) * 10 + }, + ease = "easeOutExpo"; + + drag_info.change.x = 6000 * (Math.abs(drag.pagex.end) - Math.abs(drag.pagex.start)); - VMM.DragSlider.sliding = true; - if (VMM.DragSlider.startX > e.pageX) { - //Sliding to the left - VMM.Lib.css(elem, 'left', -(VMM.DragSlider.startX - e.pageX - VMM.DragSlider.startLeft)); - VMM.DragSlider.slidingLeft = true; - } else { - //Sliding to the right - var left = (e.pageX - VMM.DragSlider.startX + VMM.DragSlider.startLeft); - VMM.Lib.css(elem, 'left', -(VMM.DragSlider.startX - e.pageX - VMM.DragSlider.startLeft)); - VMM.DragSlider.slidingLeft = false; - } - }, - dragMomentum: function(elem, e) { - var slideAdjust = (new Date().getTime() - VMM.DragSlider.dragStartTime) * 10; - var timeAdjust = slideAdjust; - var left = VMM.DragSlider.getLeft(elem); - - var changeX = 6000 * (Math.abs(VMM.DragSlider.startLeft) - Math.abs(left)); - //var changeX = 6000 * (VMM.DragSlider.startLeft - left); - slideAdjust = Math.round(changeX / slideAdjust); - var newLeft = left + slideAdjust; + drag_info.left_adjust = Math.round(drag_info.change.x / drag_info.time); + + drag_info.left = Math.min(drag_info.left + drag_info.left_adjust); - var t = newLeft % VMM.DragSlider.width; - //left: Math.min(0, newLeft), - var _r_object = { - left: Math.min(newLeft), - time: timeAdjust + if (drag.constraint) { + if (drag_info.left > drag.constraint.left) { + drag_info.left = drag.constraint.left; + if (drag_info.time > 5000) { + drag_info.time = 5000; + } + } else if (drag_info.left < drag.constraint.right) { + drag_info.left = drag.constraint.right; + if (drag_info.time > 5000) { + drag_info.time = 5000; + } + } } - VMM.fireEvent(elem, "DRAGUPDATE", [_r_object]); - var _ease = "easeOutExpo"; - if (_r_object.time > 0) { - VMM.Lib.animate(elem, _r_object.time, _ease, {"left": _r_object.left}); - }; + VMM.fireEvent(elem, "DRAGUPDATE", [drag_info]); + if (drag_info.time > 0) { + if (drag.touch) { + VMM.Lib.css(elem, '-webkit-transition-property', 'left'); + VMM.Lib.css(elem, '-webkit-transition-duration', drag_info.time); + VMM.Lib.css(elem, 'left', drag_info.left); + + } else { + VMM.Lib.animate(elem, drag_info.time, ease, {"left": drag_info.left}); + } + } - //VMM.DragSlider.startX = null; - }, - getLeft: function(elem) { + } + var getLeft = function(elem) { return parseInt(VMM.Lib.css(elem, 'left').substring(0, VMM.Lib.css(elem, 'left').length - 2), 10); } - } } \ No newline at end of file diff --git a/source/js/VMM.Timeline.TimeNav.js b/source/js/VMM.Timeline.TimeNav.js index be8d65a..480bfbd 100644 --- a/source/js/VMM.Timeline.TimeNav.js +++ b/source/js/VMM.Timeline.TimeNav.js @@ -32,7 +32,7 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin } }, $timenav, $content, $time, $timeintervalminor, $timeinterval, $timeintervalmajor, $timebackground, - $timeintervalbackground, $timenavline, $timenavindicator, $timeintervalminor_minor, $toolbar, $zoomin, $zoomout; + $timeintervalbackground, $timenavline, $timenavindicator, $timeintervalminor_minor, $toolbar, $zoomin, $zoomout, $dragslide; @@ -124,8 +124,10 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin }; function reSize(firstrun) { - config.nav.contstraint.left = (config.width/2); - config.nav.contstraint.right = config.nav.contstraint.right_min - (config.width/2); + config.nav.constraint.left = (config.width/2); + config.nav.constraint.right = config.nav.constraint.right_min - (config.width/2); + $dragslide.updateConstraint(config.nav.constraint); + VMM.Lib.css($timenavline, "left", Math.round(config.width/2)+2); VMM.Lib.css($timenavindicator, "left", Math.round(config.width/2)-8); goToMarker(config.current_slide, config.ease, config.duration, true, firstrun); @@ -136,7 +138,8 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin } function onZoomIn() { - VMM.DragSlider.cancelSlide(); + + $dragslide.cancelSlide(); if (config.nav.multiplier.current > config.nav.multiplier.min) { if (config.nav.multiplier.current <= 1) { config.nav.multiplier.current = config.nav.multiplier.current - .25; @@ -160,7 +163,7 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin } function onZoomOut() { - VMM.DragSlider.cancelSlide(); + $dragslide.cancelSlide(); if (config.nav.multiplier.current < config.nav.multiplier.max) { if (config.nav.multiplier.current > 4) { if (config.nav.multiplier.current > 16) { @@ -180,7 +183,7 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin } function onBackHome(e) { - VMM.DragSlider.cancelSlide(); + $dragslide.cancelSlide(); goToMarker(0); upDate(); } @@ -212,10 +215,10 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin // Stop from scrolling too far scroll_to = VMM.Lib.position($timenav).left + delta; - if (scroll_to > config.nav.contstraint.left) { + if (scroll_to > config.nav.constraint.left) { scroll_to = config.width/2; - } else if (scroll_to < config.nav.contstraint.right) { - scroll_to = config.nav.contstraint.right; + } else if (scroll_to < config.nav.constraint.right) { + scroll_to = config.nav.constraint.right; } VMM.Lib.stop($timenav); @@ -229,12 +232,15 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin positionEras(true); positionInterval($timeinterval, interval_array, true, true); positionInterval($timeintervalmajor, interval_major_array, true); + config.nav.constraint.left = (config.width/2); + config.nav.constraint.right = config.nav.constraint.right_min - (config.width/2); + $dragslide.updateConstraint(config.nav.constraint); }; /* MARKER EVENTS ================================================== */ function onMarkerClick(e) { - VMM.DragSlider.cancelSlide(); + $dragslide.cancelSlide(); goToMarker(e.data.number); upDate(); }; @@ -985,13 +991,18 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin if (pos > config.nav.minor_width) { config.nav.minor_width = pos; + //config.nav.constraint.right_min = -pos; + //config.nav.constraint.right = config.nav.constraint.right_min + (config.width/2); + } if (pos < config.nav.minor_left) { config.nav.minor_left = pos; - config.nav.contstraint.right_min = pos; - config.nav.contstraint.right = config.nav.contstraint.right_min - (config.width/2); + //config.nav.constraint.right_min = pos; + //config.nav.constraint.right = config.nav.constraint.right_min + (config.width/2); + + } } @@ -1004,6 +1015,10 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin } } + + + config.nav.constraint.right_min = -(config.nav.minor_width)+(config.width); + config.nav.constraint.right = config.nav.constraint.right_min + (config.width/2); VMM.Lib.css($timeintervalminor_minor, "left", config.nav.minor_left - (config.width)/2); VMM.Lib.width($timeintervalminor_minor, (config.nav.minor_width)+(config.width) + Math.abs(config.nav.minor_left) ); @@ -1276,15 +1291,17 @@ if(typeof VMM.Timeline != 'undefined' && typeof VMM.Timeline.TimeNav == 'undefin $toolbar.tooltip({selector: "div[rel=tooltip]", placement: "right"}) - // MAKE TIMELINE TOUCHABLE + // MAKE TIMELINE DRAGGABLE/TOUCHABLE + $dragslide = new VMM.DragSlider; if (VMM.Browser.device == "mobile" || VMM.Browser.device == "tablet") { - VMM.TouchSlider.createPanel($timebackground, $timenav, config.width, config.spacing, false); - VMM.bindEvent($timenav, onTouchUpdate, "TOUCHUPDATE"); + $dragslide.createPanel(layout, $timenav, config.nav.constraint, true); } else { - VMM.DragSlider.createPanel(layout, $timenav, config.width, config.spacing, false); + $dragslide.createPanel(layout, $timenav, config.nav.constraint); } + + VMM.bindEvent(".zoom-in", onZoomIn, "click"); VMM.bindEvent(".zoom-out", onZoomOut, "click"); VMM.bindEvent(layout, onMouseScroll, 'DOMMouseScroll');