UNPKG

hammerjs

Version:

A javascript library for multi-touch gestures

210 lines (188 loc) 6.02 kB
/** * @module gestures */ /** * Move with x fingers (default 1) around on the page. * Preventing the default browser behavior is a good way to improve feel and working. * ```` * hammertime.on("drag", function(ev) { * console.log(ev); * ev.gesture.preventDefault(); * }); * ```` * * @class Drag * @static */ /** * @event drag * @param {Object} ev */ /** * @event dragstart * @param {Object} ev */ /** * @event dragend * @param {Object} ev */ /** * @event drapleft * @param {Object} ev */ /** * @event dragright * @param {Object} ev */ /** * @event dragup * @param {Object} ev */ /** * @event dragdown * @param {Object} ev */ (function(name) { var triggered = false; function dragGesture(ev, inst) { var cur = Detection.current; // max touches if(inst.options.drag_max_touches > 0 && ev.touches.length > inst.options.drag_max_touches) { return; } switch(ev.eventType) { case EVENT_START: triggered = false; break; case EVENT_MOVE: // when the distance we moved is too small we skip this gesture // or we can be already in dragging if(ev.distance < inst.options.drag_min_distance && cur.name != name) { return; } var startCenter = cur.startEvent.center; // we are dragging! if(cur.name != name) { cur.name = name; if(inst.options.correct_for_drag_min_distance && ev.distance > 0) { // When a drag is triggered, set the event center to drag_min_distance pixels from the original event center. // Without this correction, the dragged distance would jumpstart at drag_min_distance pixels instead of at 0. // It might be useful to save the original start point somewhere var factor = Math.abs(inst.options.drag_min_distance / ev.distance); startCenter.pageX += ev.deltaX * factor; startCenter.pageY += ev.deltaY * factor; startCenter.clientX += ev.deltaX * factor; startCenter.clientY += ev.deltaY * factor; // recalculate event data using new start point ev = Detection.extendEventData(ev); } } // lock drag to axis? if(cur.lastEvent.drag_locked_to_axis || ( inst.options.drag_lock_to_axis && inst.options.drag_lock_min_distance <= ev.distance )) { ev.drag_locked_to_axis = true; } var last_direction = cur.lastEvent.direction; if(ev.drag_locked_to_axis && last_direction !== ev.direction) { // keep direction on the axis that the drag gesture started on if(Utils.isVertical(last_direction)) { ev.direction = (ev.deltaY < 0) ? DIRECTION_UP : DIRECTION_DOWN; } else { ev.direction = (ev.deltaX < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT; } } // first time, trigger dragstart event if(!triggered) { inst.trigger(name + 'start', ev); triggered = true; } // trigger events inst.trigger(name, ev); inst.trigger(name + ev.direction, ev); var is_vertical = Utils.isVertical(ev.direction); // block the browser events if((inst.options.drag_block_vertical && is_vertical) || (inst.options.drag_block_horizontal && !is_vertical)) { ev.preventDefault(); } break; case EVENT_RELEASE: if(triggered && ev.changedLength <= inst.options.drag_max_touches) { inst.trigger(name + 'end', ev); triggered = false; } break; case EVENT_END: triggered = false; break; } } Hammer.gestures.Drag = { name: name, index: 50, handler: dragGesture, defaults: { /** * minimal movement that have to be made before the drag event gets triggered * @property drag_min_distance * @type {Number} * @default 10 */ drag_min_distance: 10, /** * Set correct_for_drag_min_distance to true to make the starting point of the drag * be calculated from where the drag was triggered, not from where the touch started. * Useful to avoid a jerk-starting drag, which can make fine-adjustments * through dragging difficult, and be visually unappealing. * @property correct_for_drag_min_distance * @type {Boolean} * @default true */ correct_for_drag_min_distance: true, /** * set 0 for unlimited, but this can conflict with transform * @property drag_max_touches * @type {Number} * @default 1 */ drag_max_touches: 1, /** * prevent default browser behavior when dragging occurs * be careful with it, it makes the element a blocking element * when you are using the drag gesture, it is a good practice to set this true * @property drag_block_horizontal * @type {Boolean} * @default false */ drag_block_horizontal: false, /** * same as `drag_block_horizontal`, but for vertical movement * @property drag_block_vertical * @type {Boolean} * @default false */ drag_block_vertical: false, /** * drag_lock_to_axis keeps the drag gesture on the axis that it started on, * It disallows vertical directions if the initial direction was horizontal, and vice versa. * @property drag_lock_to_axis * @type {Boolean} * @default false */ drag_lock_to_axis: false, /** * drag lock only kicks in when distance > drag_lock_min_distance * This way, locking occurs only when the distance has become large enough to reliably determine the direction * @property drag_lock_min_distance * @type {Number} * @default 25 */ drag_lock_min_distance: 25 } }; })('drag');