From 63c36ffb6fb6fef75e08a38159e501ac051660b1 Mon Sep 17 00:00:00 2001 From: jos Date: Fri, 13 Jun 2014 10:57:26 +0200 Subject: [PATCH] Fixed vertical drag issue while pinching --- src/timeline/Range.js | 51 ++++++++++++++++++--------------------- src/timeline/Timeline.js | 35 ++++++++++++++++++++------- test/timeline.html | 6 ++--- test/timeline_groups.html | 8 +++--- 4 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/timeline/Range.js b/src/timeline/Range.js index 250de3b5..f2f8212e 100644 --- a/src/timeline/Range.js +++ b/src/timeline/Range.js @@ -27,6 +27,10 @@ function Range(body, options) { }; this.options = util.extend({}, this.defaultOptions); + this.props = { + touch: {} + }; + // drag listeners for dragging this.body.emitter.on('dragstart', this._onDragStart.bind(this)); this.body.emitter.on('drag', this._onDrag.bind(this)); @@ -260,9 +264,6 @@ Range.conversion = function (start, end, width) { } }; -// global (private) object to store drag params -var touchParams = {}; - /** * Start dragging horizontally or vertically * @param {Event} event @@ -274,10 +275,10 @@ Range.prototype._onDragStart = function(event) { // refuse to drag when we where pinching to prevent the timeline make a jump // when releasing the fingers in opposite order from the touch screen - if (touchParams.ignore) return; + if (!this.props.touch.allowDragging) return; - touchParams.start = this.start; - touchParams.end = this.end; + this.props.touch.start = this.start; + this.props.touch.end = this.end; if (this.body.dom.root) { this.body.dom.root.style.cursor = 'move'; @@ -298,14 +299,15 @@ Range.prototype._onDrag = function (event) { // refuse to drag when we where pinching to prevent the timeline make a jump // when releasing the fingers in opposite order from the touch screen - if (touchParams.ignore) return; + if (!this.props.touch.allowDragging) return; + console.log('onDrag range'); var delta = (direction == 'horizontal') ? event.gesture.deltaX : event.gesture.deltaY, - interval = (touchParams.end - touchParams.start), + interval = (this.props.touch.end - this.props.touch.start), width = (direction == 'horizontal') ? this.body.domProps.center.width : this.body.domProps.center.height, diffRange = -delta / width * interval; - this._applyRange(touchParams.start + diffRange, touchParams.end + diffRange); + this._applyRange(this.props.touch.start + diffRange, this.props.touch.end + diffRange); this.body.emitter.emit('rangechange', { start: new Date(this.start), @@ -324,7 +326,7 @@ Range.prototype._onDragEnd = function (event) { // refuse to drag when we where pinching to prevent the timeline make a jump // when releasing the fingers in opposite order from the touch screen - if (touchParams.ignore) return; + if (!this.props.touch.allowDragging) return; if (this.body.dom.root) { this.body.dom.root.style.cursor = 'auto'; @@ -391,17 +393,10 @@ Range.prototype._onMouseWheel = function(event) { * @private */ Range.prototype._onTouch = function (event) { - touchParams.start = this.start; - touchParams.end = this.end; - touchParams.ignore = false; - touchParams.center = null; - - // don't move the range when dragging a selected event - // TODO: it's not so neat to have to know about ItemSet here - var item = ItemSet.itemFromTarget(event); - if (item && item.selected && this.options.editable) { - touchParams.ignore = true; - } + this.props.touch.start = this.start; + this.props.touch.end = this.end; + this.props.touch.allowDragging = true; + this.props.touch.center = null; }; /** @@ -409,7 +404,7 @@ Range.prototype._onTouch = function (event) { * @private */ Range.prototype._onHold = function () { - touchParams.ignore = true; + this.props.touch.allowDragging = false; }; /** @@ -421,19 +416,19 @@ Range.prototype._onPinch = function (event) { // only allow zooming when configured as zoomable and moveable if (!(this.options.zoomable && this.options.moveable)) return; - touchParams.ignore = true; + this.props.touch.allowDragging = false; if (event.gesture.touches.length > 1) { - if (!touchParams.center) { - touchParams.center = getPointer(event.gesture.center, this.body.dom.center); + if (!this.props.touch.center) { + this.props.touch.center = getPointer(event.gesture.center, this.body.dom.center); } var scale = 1 / event.gesture.scale, - initDate = this._pointerToDate(touchParams.center); + initDate = this._pointerToDate(this.props.touch.center); // calculate new start and end - var newStart = parseInt(initDate + (touchParams.start - initDate) * scale); - var newEnd = parseInt(initDate + (touchParams.end - initDate) * scale); + var newStart = parseInt(initDate + (this.props.touch.start - initDate) * scale); + var newEnd = parseInt(initDate + (this.props.touch.end - initDate) * scale); // apply new range this.setRange(newStart, newEnd); diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js index 2b68a5e5..dc88373e 100644 --- a/src/timeline/Timeline.js +++ b/src/timeline/Timeline.js @@ -135,6 +135,8 @@ Timeline.prototype._create = function (container) { this.on('rangechange', this.redraw.bind(this)); this.on('change', this.redraw.bind(this)); + this.on('touch', this._onTouch.bind(this)); + this.on('pinch', this._onPinch.bind(this)); this.on('dragstart', this._onDragStart.bind(this)); this.on('drag', this._onDrag.bind(this)); @@ -147,7 +149,7 @@ Timeline.prototype._create = function (container) { var me = this; var events = [ - 'pinch', + 'touch', 'pinch', 'tap', 'doubletap', 'hold', 'dragstart', 'drag', 'dragend', 'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox @@ -176,6 +178,7 @@ Timeline.prototype._create = function (container) { border: {}, scrollTop: 0 }; + this.touch = {}; // store state information needed for touch events // attach the root panel to the provided container if (!container) throw new Error('No container provided'); @@ -688,13 +691,31 @@ Timeline.prototype._stopAutoResize = function () { // TODO: remove event listener on window.resize }; +/** + * Start moving the timeline vertically + * @param {Event} event + * @private + */ +Timeline.prototype._onTouch = function (event) { + this.touch.allowDragging = true; +}; + +/** + * Start moving the timeline vertically + * @param {Event} event + * @private + */ +Timeline.prototype._onPinch = function (event) { + this.touch.allowDragging = false; +}; + /** * Start moving the timeline vertically * @param {Event} event * @private */ Timeline.prototype._onDragStart = function (event) { - touchParams.initialScrollTop = this.props.scrollTop; + this.touch.initialScrollTop = this.props.scrollTop; }; /** @@ -703,15 +724,14 @@ Timeline.prototype._onDragStart = function (event) { * @private */ Timeline.prototype._onDrag = function (event) { -/* TODO: no dragging when pinching // refuse to drag when we where pinching to prevent the timeline make a jump // when releasing the fingers in opposite order from the touch screen - if (touchParams.pinching) return; -*/ + if (!this.touch.allowDragging) return; + var delta = event.gesture.deltaY; var oldScrollTop = this._getScrollTop(); - var newScrollTop = this._setScrollTop(touchParams.initialScrollTop + delta); + var newScrollTop = this._setScrollTop(this.touch.initialScrollTop + delta); if (newScrollTop != oldScrollTop) { this.redraw(); // TODO: this causes two redraws when dragging, the other is triggered by rangechange already @@ -750,6 +770,3 @@ Timeline.prototype._setScrollTop = function (scrollTop) { Timeline.prototype._getScrollTop = function () { return this.props.scrollTop; }; - -// global (private) object to store drag params -var touchParams = {}; diff --git a/test/timeline.html b/test/timeline.html index 83e49b32..f28dcfa7 100644 --- a/test/timeline.html +++ b/test/timeline.html @@ -28,10 +28,10 @@ diff --git a/test/timeline_groups.html b/test/timeline_groups.html index 7e7b78f0..e2a5f2e8 100644 --- a/test/timeline_groups.html +++ b/test/timeline_groups.html @@ -31,10 +31,10 @@ @@ -79,7 +79,7 @@ updateGroup: true }, //stack: false, - //height: 200, + height: 200, groupOrder: 'content' };