From e494514406a96641bc2152520b7c1487f7b44ff7 Mon Sep 17 00:00:00 2001 From: Veaceslav Grimalschi Date: Thu, 20 Jul 2017 20:31:18 +0200 Subject: [PATCH] Bidirectional scrolling in timeline - make horizontalScroll and verticalScroll work together (#3162) * Bidirectional scrolling. Make horizontalScroll and verticalScroll work together. * Fix delta variable declaration Using ?: operator * Remove notice about vertical and horizontal scroll conflict There is no sense considering #3162 --- docs/timeline/index.html | 2 +- lib/timeline/Core.js | 63 +++++++++++++++++++++++++++++----------- lib/timeline/Range.js | 18 ------------ 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/docs/timeline/index.html b/docs/timeline/index.html index 2bd2a8c4..48571cb0 100644 --- a/docs/timeline/index.html +++ b/docs/timeline/index.html @@ -732,7 +732,7 @@ function (option, path) { Boolean false This option allows you to scroll horizontally to move backwards and forwards in the time range. - Only applicable when option zoomCtrl is defined or zoomable is false. Notice that defining this option as true will override verticalScroll scroll event but not eliminate the vertical scrollbar. + Only applicable when option zoomCtrl is defined or zoomable is false. diff --git a/lib/timeline/Core.js b/lib/timeline/Core.js index 386cd986..68cfa07c 100644 --- a/lib/timeline/Core.js +++ b/lib/timeline/Core.js @@ -173,8 +173,29 @@ Core.prototype._create = function (container) { this.emit('mousewheel', event); } - // prevent scrolling if not specified explicitly or when horizontalScroll is true - if (!this.options.verticalScroll || this.options.horizontalScroll) return; + // deltaX and deltaY normalization from jquery.mousewheel.js + var deltaX = 0; + var deltaY = 0; + + // Old school scrollwheel delta + if ( 'detail' in event ) { deltaY = event.detail * -1; } + if ( 'wheelDelta' in event ) { deltaY = event.wheelDelta; } + if ( 'wheelDeltaY' in event ) { deltaY = event.wheelDeltaY; } + if ( 'wheelDeltaX' in event ) { deltaX = event.wheelDeltaX * -1; } + + // Firefox < 17 horizontal scrolling related to DOMMouseScroll event + if ( 'axis' in event && event.axis === event.HORIZONTAL_AXIS ) { + deltaX = deltaY * -1; + deltaY = 0; + } + + // New school wheel delta (wheel event) + if ( 'deltaY' in event ) { + deltaY = event.deltaY * -1; + } + if ( 'deltaX' in event ) { + deltaX = event.deltaX; + } // prevent scrolling when zoomKey defined or activated if (!this.options.zoomKey || event[this.options.zoomKey]) return; @@ -183,22 +204,30 @@ Core.prototype._create = function (container) { // (else the page and timeline both scroll) event.preventDefault(); - var delta = 0; - if (event.wheelDelta) { /* IE/Opera. */ - delta = event.wheelDelta / 120; - } else if (event.detail) { /* Mozilla case. */ - // In Mozilla, sign of delta is different than in IE. - // Also, delta is multiple of 3. - delta = -event.detail / 3; - } - - var current = this.props.scrollTop; - var adjusted = current + delta * 120; + if (this.options.verticalScroll && Math.abs(deltaY) >= Math.abs(deltaX)) { + var current = this.props.scrollTop; + var adjusted = current + deltaY; - if (this.isActive()) { - this._setScrollTop(adjusted); - this._redraw(); - this.emit('scroll', event); + if (this.isActive()) { + this._setScrollTop(adjusted); + this._redraw(); + this.emit('scroll', event); + } + } else if (this.options.horizontalScroll) { + var delta = Math.abs(deltaX) >= Math.abs(deltaY) ? deltaX : deltaY; + + // calculate a single scroll jump relative to the range scale + var diff = (delta / 120) * (this.range.end - this.range.start) / 20; + // calculate new start and end + var newStart = this.range.start + diff; + var newEnd = this.range.end + diff; + + var options = { + animation: false, + byUser: true, + event: event + } + this.range.setRange(newStart, newEnd, options); } } diff --git a/lib/timeline/Range.js b/lib/timeline/Range.js index 38ddd317..dab601d5 100644 --- a/lib/timeline/Range.js +++ b/lib/timeline/Range.js @@ -614,24 +614,6 @@ Range.prototype._onMouseWheel = function(event) { // don't allow zoom when the according key is pressed and the zoomKey option or not zoomable but movable if ((this.options.zoomKey && !event[this.options.zoomKey] && this.options.zoomable) || (!this.options.zoomable && this.options.moveable)) { - if (this.options.horizontalScroll) { - // Prevent default actions caused by mouse wheel - // (else the page and timeline both scroll) - event.preventDefault(); - - // calculate a single scroll jump relative to the range scale - var diff = delta * (this.end - this.start) / 20; - // calculate new start and end - var newStart = this.start - diff; - var newEnd = this.end - diff; - - var options = { - animation: false, - byUser: true, - event: event - } - this.setRange(newStart, newEnd, options); - } return; }