From b16d8c1f5d512d72155e5efa0944bccd144b561e Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 17 Sep 2021 12:44:15 -0700 Subject: [PATCH 01/23] WIP: implementing map option scroll zoom blocker --- debug/scroll_zoom_blocker.html | 32 ++++++++++++++++ src/css/mapbox-gl.css | 22 +++++++++++ src/ui/handler/scroll_zoom.js | 69 +++++++++++++++++++++++++++++++++- 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 debug/scroll_zoom_blocker.html diff --git a/debug/scroll_zoom_blocker.html b/debug/scroll_zoom_blocker.html new file mode 100644 index 00000000000..b57952e096a --- /dev/null +++ b/debug/scroll_zoom_blocker.html @@ -0,0 +1,32 @@ + + + + Scroll Zoom Blocker Control + + + + + + + +
+ +
+ + + + + diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index e16509ee8d7..31c250d7f1d 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -769,3 +769,25 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { display: none; } } + +.mapboxgl-scroll-zoom-blocker-control { + color: #fff; + font-family: "Roboto", Arial, sans-serif; + font-size: 100%; + justify-content: center; + position: absolute; + display: flex; + align-items: center; + padding: 15px; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + visibility: hidden; + opacity: 0; + z-index: 461; + transition: none !important; +} + +.mapboxgl-scroll-zoom-blocker-control-fade { + transition: opacity 0.75s ease-in-out !important; +} diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index e7e6f232b51..2525a9c57d8 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -60,6 +60,9 @@ class ScrollZoomHandler { _defaultZoomRate: number; _wheelZoomRate: number; + _requireCtrl: boolean; + _container: HTMLElement; + /** * @private */ @@ -73,7 +76,8 @@ class ScrollZoomHandler { this._defaultZoomRate = defaultZoomRate; this._wheelZoomRate = wheelZoomRate; - bindAll(['_onTimeout'], this); + bindAll(['_onTimeout', '_addScrollZoomBlocker', '_showBlockerAlert', '_fadeOutBlockerAlert'], this); + } /** @@ -134,11 +138,16 @@ class ScrollZoomHandler { * map.scrollZoom.enable(); * @example * map.scrollZoom.enable({around: 'center'}); + * map.scrollZoom.enable({requireCtrl: true}); */ enable(options: any) { if (this.isEnabled()) return; this._enabled = true; - this._aroundCenter = options && options.around === 'center'; + this._aroundCenter = !!options && options.around === 'center'; + this._requireCtrl = !!options && options.requireCtrl === true; + if (this._requireCtrl) { + this._addScrollZoomBlocker(); + } } /** @@ -155,6 +164,17 @@ class ScrollZoomHandler { wheel(e: WheelEvent) { if (!this.isEnabled()) return; + if (this._requireCtrl && !e.ctrlKey && !this.isZooming()) { + this._showBlockerAlert(); + this._fadeOutBlockerAlert(); + return; + } + + if (this._container.style.visibility === 'visible') { + // immediately hide alert if it is visible when metakey or ctrl are pressed while scroll zooming. + this._container.style.visibility = 'hidden'; + } + // Remove `any` cast when https://github.com/facebook/flow/issues/4879 is fixed. let value = e.deltaMode === (window.WheelEvent: any).DOM_DELTA_LINE ? e.deltaY * 40 : e.deltaY; const now = browser.now(), @@ -248,6 +268,7 @@ class ScrollZoomHandler { this._frameId = null; if (!this.isActive()) return; + const tr = this._map.transform; const startingZoom = () => { @@ -356,6 +377,50 @@ class ScrollZoomHandler { reset() { this._active = false; } + + /** + * Returns the scroll zoom blocker alert's HTML element. + * + * @example + * // Change the scroll zoom blocker element's font size + * map.scrollZoom.getScrollZoomBlockerElement(); + * scrollZoomBlockerElem.style.fontSize = "25px"; + * @returns {HTMLElement} Returns container element. + */ + + getScrollZoomBlockerElement() { + if (this._container) { + return this._container; + } + } + + _addScrollZoomBlocker() { + if (!this._map) { return; } + if (!this._container) { + this._container = DOM.create('div', 'mapboxgl-scroll-zoom-blocker-control', this._map._container); + const frag = window.document.createTextNode('CTRL + zoom to scroll the map'); + this._container.appendChild(frag); + } + } + + _showBlockerAlert() { + const scrollZoomBlockerEl = this.getScrollZoomBlockerElement(); + console.log(scrollZoomBlockerEl.classList) + scrollZoomBlockerEl.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); + this._container.style.opacity = '1'; + this._container.style.visibility = 'visible'; + + } + + _fadeOutBlockerAlert() { + setTimeout(() => { + const scrollZoomBlockerEl = this.getScrollZoomBlockerElement(); + console.log(scrollZoomBlockerEl.classList) + scrollZoomBlockerEl.classList.add('mapboxgl-scroll-zoom-blocker-control-fade'); + this._container.style.opacity = '0'; + }, 2000); + } + } export default ScrollZoomHandler; From f2c5064e528e7c3a813491ea368d7b5bed00d407 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 17 Sep 2021 12:56:53 -0700 Subject: [PATCH 02/23] fixed lint issues --- src/ui/handler/scroll_zoom.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 2525a9c57d8..9730c72ba33 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -404,19 +404,14 @@ class ScrollZoomHandler { } _showBlockerAlert() { - const scrollZoomBlockerEl = this.getScrollZoomBlockerElement(); - console.log(scrollZoomBlockerEl.classList) - scrollZoomBlockerEl.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); + this._container.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); this._container.style.opacity = '1'; this._container.style.visibility = 'visible'; - } _fadeOutBlockerAlert() { setTimeout(() => { - const scrollZoomBlockerEl = this.getScrollZoomBlockerElement(); - console.log(scrollZoomBlockerEl.classList) - scrollZoomBlockerEl.classList.add('mapboxgl-scroll-zoom-blocker-control-fade'); + this._container.classList.add('mapboxgl-scroll-zoom-blocker-control-fade'); this._container.style.opacity = '0'; }, 2000); } From eb039ca605e8291f8a2fdb807555b2cebc2524d0 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 17 Sep 2021 13:24:38 -0700 Subject: [PATCH 03/23] fixed issue with repeating wheel events --- src/css/mapbox-gl.css | 6 ++++-- src/ui/handler/scroll_zoom.js | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index 31c250d7f1d..899e69045fd 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -778,13 +778,15 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { position: absolute; display: flex; align-items: center; - padding: 15px; + top: 0; + left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); visibility: hidden; opacity: 0; - z-index: 461; + z-index: 3; + pointer-events: none; transition: none !important; } diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 9730c72ba33..c71b0197cda 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -171,7 +171,7 @@ class ScrollZoomHandler { } if (this._container.style.visibility === 'visible') { - // immediately hide alert if it is visible when metakey or ctrl are pressed while scroll zooming. + // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. this._container.style.visibility = 'hidden'; } From 030b1d3c4612ddd5c402190bbc16e0b379fd750a Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 17 Sep 2021 13:34:34 -0700 Subject: [PATCH 04/23] fixed unit tests fail by checking if container exists --- src/ui/handler/scroll_zoom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index c71b0197cda..b073a68720d 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -170,7 +170,7 @@ class ScrollZoomHandler { return; } - if (this._container.style.visibility === 'visible') { + if (this._container && this._container.style.visibility === 'visible') { // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. this._container.style.visibility = 'hidden'; } From 14b71a9594cfa27fc3107d7a89a31254255d2b56 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 17 Sep 2021 13:58:53 -0700 Subject: [PATCH 05/23] added in locale string for alert message --- src/ui/default_locale.js | 3 ++- src/ui/handler/scroll_zoom.js | 35 ++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/ui/default_locale.js b/src/ui/default_locale.js index 92c548d4504..a8da9fa48b2 100644 --- a/src/ui/default_locale.js +++ b/src/ui/default_locale.js @@ -15,7 +15,8 @@ const defaultLocale = { 'ScaleControl.Meters': 'm', 'ScaleControl.Kilometers': 'km', 'ScaleControl.Miles': 'mi', - 'ScaleControl.NauticalMiles': 'nm' + 'ScaleControl.NauticalMiles': 'nm', + 'ScrollZoomBlocker.Message': 'CTRL + zoom to scroll the map' }; diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index b073a68720d..7638baedcc4 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -76,7 +76,7 @@ class ScrollZoomHandler { this._defaultZoomRate = defaultZoomRate; this._wheelZoomRate = wheelZoomRate; - bindAll(['_onTimeout', '_addScrollZoomBlocker', '_showBlockerAlert', '_fadeOutBlockerAlert'], this); + bindAll(['_onTimeout', '_addScrollZoomBlocker', '_getBlockerAlertMessage', '_showBlockerAlert', '_fadeOutBlockerAlert'], this); } @@ -142,12 +142,12 @@ class ScrollZoomHandler { */ enable(options: any) { if (this.isEnabled()) return; + this._enabled = true; this._aroundCenter = !!options && options.around === 'center'; this._requireCtrl = !!options && options.requireCtrl === true; - if (this._requireCtrl) { - this._addScrollZoomBlocker(); - } + + if (this._requireCtrl) this._addScrollZoomBlocker(); } /** @@ -164,15 +164,15 @@ class ScrollZoomHandler { wheel(e: WheelEvent) { if (!this.isEnabled()) return; - if (this._requireCtrl && !e.ctrlKey && !this.isZooming()) { - this._showBlockerAlert(); - this._fadeOutBlockerAlert(); - return; - } - - if (this._container && this._container.style.visibility === 'visible') { - // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. - this._container.style.visibility = 'hidden'; + if (this._requireCtrl) { + if (!e.ctrlKey && !this.isZooming()) { + this._showBlockerAlert(); + this._fadeOutBlockerAlert(); + return; + } else if (this._container && this._container.style.visibility === 'visible') { + // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. + this._container.style.visibility = 'hidden'; + } } // Remove `any` cast when https://github.com/facebook/flow/issues/4879 is fixed. @@ -398,11 +398,16 @@ class ScrollZoomHandler { if (!this._map) { return; } if (!this._container) { this._container = DOM.create('div', 'mapboxgl-scroll-zoom-blocker-control', this._map._container); - const frag = window.document.createTextNode('CTRL + zoom to scroll the map'); - this._container.appendChild(frag); + const alertMessage = this._getBlockerAlertMessage(); + const textNode = window.document.createTextNode(alertMessage); + this._container.appendChild(textNode); } } + _getBlockerAlertMessage() { + return this._map._getUIString('ScrollZoomBlocker.Message'); + } + _showBlockerAlert() { this._container.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); this._container.style.opacity = '1'; From 28c179ff5c818acd269a3bab04e231427162e1af Mon Sep 17 00:00:00 2001 From: avpeery Date: Mon, 20 Sep 2021 08:58:02 -0700 Subject: [PATCH 06/23] add transition effect without using setTimeout, issue with Flow --- src/css/mapbox-gl.css | 8 ++++---- src/ui/handler/scroll_zoom.js | 24 +++++++++--------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index 899e69045fd..0e825def4d1 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -772,7 +772,7 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { .mapboxgl-scroll-zoom-blocker-control { color: #fff; - font-family: "Roboto", Arial, sans-serif; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; font-size: 100%; justify-content: center; position: absolute; @@ -783,13 +783,13 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); - visibility: hidden; opacity: 0; z-index: 3; pointer-events: none; - transition: none !important; + transition: opacity 0.1s ease-in-out; } .mapboxgl-scroll-zoom-blocker-control-fade { - transition: opacity 0.75s ease-in-out !important; + transition: opacity 0.75s ease-in-out; + transition-delay: 1s; } diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 7638baedcc4..426381e720a 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -133,6 +133,7 @@ class ScrollZoomHandler { * * @param {Object} [options] Options object. * @param {string} [options.around] If "center" is passed, map will zoom around center of map. + * @param {boolean} [options.requireCtrl] If set to true, ctrl key must be pressed while scrolling to zoom. * * @example * map.scrollZoom.enable(); @@ -142,11 +143,9 @@ class ScrollZoomHandler { */ enable(options: any) { if (this.isEnabled()) return; - this._enabled = true; - this._aroundCenter = !!options && options.around === 'center'; - this._requireCtrl = !!options && options.requireCtrl === true; - + this._aroundCenter = options && options.around === 'center'; + this._requireCtrl = options && options.requireCtrl === true; if (this._requireCtrl) this._addScrollZoomBlocker(); } @@ -167,9 +166,8 @@ class ScrollZoomHandler { if (this._requireCtrl) { if (!e.ctrlKey && !this.isZooming()) { this._showBlockerAlert(); - this._fadeOutBlockerAlert(); return; - } else if (this._container && this._container.style.visibility === 'visible') { + } else if (this._container && this._container.classList.contains('mapboxgl-scroll-zoom-blocker-control-fade')) { // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. this._container.style.visibility = 'hidden'; } @@ -389,13 +387,11 @@ class ScrollZoomHandler { */ getScrollZoomBlockerElement() { - if (this._container) { - return this._container; - } + if (this._container) return this._container; } _addScrollZoomBlocker() { - if (!this._map) { return; } + if (!this._map) return; if (!this._container) { this._container = DOM.create('div', 'mapboxgl-scroll-zoom-blocker-control', this._map._container); const alertMessage = this._getBlockerAlertMessage(); @@ -409,16 +405,14 @@ class ScrollZoomHandler { } _showBlockerAlert() { + if (this._container.style.visibility === 'hidden') this._container.style.visibility = 'visible'; this._container.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); this._container.style.opacity = '1'; - this._container.style.visibility = 'visible'; - } - _fadeOutBlockerAlert() { - setTimeout(() => { + this._container.ontransitionend = () => { this._container.classList.add('mapboxgl-scroll-zoom-blocker-control-fade'); this._container.style.opacity = '0'; - }, 2000); + }; } } From ca4677def7e25002a56eeb5374cd6d1afc7faeb6 Mon Sep 17 00:00:00 2001 From: avpeery Date: Tue, 21 Sep 2021 14:05:44 -0700 Subject: [PATCH 07/23] changes requests for CSS and removal of getElement method --- src/css/mapbox-gl.css | 2 +- src/ui/handler/scroll_zoom.js | 24 +++--------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index 0e825def4d1..43ed5382cbd 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -775,6 +775,7 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; font-size: 100%; justify-content: center; + text-align: center; position: absolute; display: flex; align-items: center; @@ -784,7 +785,6 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { height: 100%; background: rgba(0, 0, 0, 0.5); opacity: 0; - z-index: 3; pointer-events: none; transition: opacity 0.1s ease-in-out; } diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 426381e720a..84ddf66ed87 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -139,6 +139,7 @@ class ScrollZoomHandler { * map.scrollZoom.enable(); * @example * map.scrollZoom.enable({around: 'center'}); + * @example * map.scrollZoom.enable({requireCtrl: true}); */ enable(options: any) { @@ -376,34 +377,15 @@ class ScrollZoomHandler { this._active = false; } - /** - * Returns the scroll zoom blocker alert's HTML element. - * - * @example - * // Change the scroll zoom blocker element's font size - * map.scrollZoom.getScrollZoomBlockerElement(); - * scrollZoomBlockerElem.style.fontSize = "25px"; - * @returns {HTMLElement} Returns container element. - */ - - getScrollZoomBlockerElement() { - if (this._container) return this._container; - } - _addScrollZoomBlocker() { - if (!this._map) return; - if (!this._container) { + if (this._map && !this._container) { this._container = DOM.create('div', 'mapboxgl-scroll-zoom-blocker-control', this._map._container); - const alertMessage = this._getBlockerAlertMessage(); + const alertMessage = this._map._getUIString('ScrollZoomBlocker.Message'); const textNode = window.document.createTextNode(alertMessage); this._container.appendChild(textNode); } } - _getBlockerAlertMessage() { - return this._map._getUIString('ScrollZoomBlocker.Message'); - } - _showBlockerAlert() { if (this._container.style.visibility === 'hidden') this._container.style.visibility = 'visible'; this._container.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); From 6bd9658bafe1b4f1d6c4b85d8f2f4abecdacb9b9 Mon Sep 17 00:00:00 2001 From: avpeery Date: Tue, 21 Sep 2021 14:55:45 -0700 Subject: [PATCH 08/23] changed alpha in css background to .7 for better readability --- src/css/mapbox-gl.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index 43ed5382cbd..e84296fccdf 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -783,7 +783,7 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { left: 0; width: 100%; height: 100%; - background: rgba(0, 0, 0, 0.5); + background: rgba(0, 0, 0, 0.7); opacity: 0; pointer-events: none; transition: opacity 0.1s ease-in-out; From fcb56ca7625c07b2df4a2dd931339d4a5e1a5d49 Mon Sep 17 00:00:00 2001 From: avpeery Date: Tue, 21 Sep 2021 14:57:21 -0700 Subject: [PATCH 09/23] removed binded methods that were deleted --- src/ui/handler/scroll_zoom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 84ddf66ed87..2bb69f0b8af 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -76,7 +76,7 @@ class ScrollZoomHandler { this._defaultZoomRate = defaultZoomRate; this._wheelZoomRate = wheelZoomRate; - bindAll(['_onTimeout', '_addScrollZoomBlocker', '_getBlockerAlertMessage', '_showBlockerAlert', '_fadeOutBlockerAlert'], this); + bindAll(['_onTimeout', '_addScrollZoomBlocker', '_showBlockerAlert'], this); } From 2ae06a60d54e75bd5a47fff48d5a1ae93302c413 Mon Sep 17 00:00:00 2001 From: avpeery Date: Tue, 21 Sep 2021 16:24:29 -0700 Subject: [PATCH 10/23] changed ontransitionend to addEventListener('transitionend') to fix flow issue --- src/ui/handler/scroll_zoom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 2bb69f0b8af..6ac9f8cf9b0 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -391,10 +391,10 @@ class ScrollZoomHandler { this._container.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); this._container.style.opacity = '1'; - this._container.ontransitionend = () => { + this._container.addEventListener('transitionend', () => { this._container.classList.add('mapboxgl-scroll-zoom-blocker-control-fade'); this._container.style.opacity = '0'; - }; + }); } } From cd7384c5ef9a66962506f959bb5f63e1ef3b00a9 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 24 Sep 2021 08:44:22 -0700 Subject: [PATCH 11/23] added some unit tests, added ability to use meta key, transition not working as expected on firefox or safari --- src/css/mapbox-gl.css | 13 ++--- src/ui/default_locale.js | 4 +- src/ui/handler/scroll_zoom.js | 26 ++++++---- test/unit/ui/handler/scroll_zoom.test.js | 65 ++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index e84296fccdf..c70f83e0805 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -770,10 +770,10 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { } } -.mapboxgl-scroll-zoom-blocker-control { +.mapboxgl-scroll-zoom-blocker { color: #fff; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 100%; + font-size: 110%; justify-content: center; text-align: center; position: absolute; @@ -786,10 +786,11 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { background: rgba(0, 0, 0, 0.7); opacity: 0; pointer-events: none; - transition: opacity 0.1s ease-in-out; -} - -.mapboxgl-scroll-zoom-blocker-control-fade { transition: opacity 0.75s ease-in-out; transition-delay: 1s; } + +.mapboxgl-scroll-zoom-blocker-show { + opacity: 1; + transition: opacity 0.1s ease-in-out; +} diff --git a/src/ui/default_locale.js b/src/ui/default_locale.js index a8da9fa48b2..ccafbc15245 100644 --- a/src/ui/default_locale.js +++ b/src/ui/default_locale.js @@ -16,8 +16,8 @@ const defaultLocale = { 'ScaleControl.Kilometers': 'km', 'ScaleControl.Miles': 'mi', 'ScaleControl.NauticalMiles': 'nm', - 'ScrollZoomBlocker.Message': 'CTRL + zoom to scroll the map' - + 'ScrollZoomBlocker.CtrlMessage': 'ctrl + scroll to zoom the map', + 'ScrollZoomBlocker.CmdMessage': '⌘ + scroll to zoom the map' }; export default defaultLocale; diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 6ac9f8cf9b0..8a363e1010d 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -133,7 +133,7 @@ class ScrollZoomHandler { * * @param {Object} [options] Options object. * @param {string} [options.around] If "center" is passed, map will zoom around center of map. - * @param {boolean} [options.requireCtrl] If set to true, ctrl key must be pressed while scrolling to zoom. + * @param {boolean} [options.requireCtrl] If set to true, ctrl (or ⌘ in OS devices) must be pressed while scrolling to zoom. * * @example * map.scrollZoom.enable(); @@ -159,16 +159,17 @@ class ScrollZoomHandler { disable() { if (!this.isEnabled()) return; this._enabled = false; + if (this._requireCtrl) this._container.remove(); } wheel(e: WheelEvent) { if (!this.isEnabled()) return; if (this._requireCtrl) { - if (!e.ctrlKey && !this.isZooming()) { + if (!e.ctrlKey && !e.metaKey && !this.isZooming()) { this._showBlockerAlert(); return; - } else if (this._container && this._container.classList.contains('mapboxgl-scroll-zoom-blocker-control-fade')) { + } else if (this._container) { // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. this._container.style.visibility = 'hidden'; } @@ -379,8 +380,15 @@ class ScrollZoomHandler { _addScrollZoomBlocker() { if (this._map && !this._container) { - this._container = DOM.create('div', 'mapboxgl-scroll-zoom-blocker-control', this._map._container); - const alertMessage = this._map._getUIString('ScrollZoomBlocker.Message'); + this._container = DOM.create('div', 'mapboxgl-scroll-zoom-blocker', this._map._container); + let alertMessage = ''; + + if (/(Mac|iPad)/i.test(window.navigator.userAgent)) { + alertMessage = this._map._getUIString('ScrollZoomBlocker.CmdMessage'); + } else { + alertMessage = this._map._getUIString('ScrollZoomBlocker.CtrlMessage'); + } + const textNode = window.document.createTextNode(alertMessage); this._container.appendChild(textNode); } @@ -388,13 +396,11 @@ class ScrollZoomHandler { _showBlockerAlert() { if (this._container.style.visibility === 'hidden') this._container.style.visibility = 'visible'; - this._container.classList.remove('mapboxgl-scroll-zoom-blocker-control-fade'); - this._container.style.opacity = '1'; + this._container.classList.add('mapboxgl-scroll-zoom-blocker-show'); this._container.addEventListener('transitionend', () => { - this._container.classList.add('mapboxgl-scroll-zoom-blocker-control-fade'); - this._container.style.opacity = '0'; - }); + this._container.classList.remove('mapboxgl-scroll-zoom-blocker-show'); + }, {once: true}); } } diff --git a/test/unit/ui/handler/scroll_zoom.test.js b/test/unit/ui/handler/scroll_zoom.test.js index 84d62e88646..ffb68d8fec6 100644 --- a/test/unit/ui/handler/scroll_zoom.test.js +++ b/test/unit/ui/handler/scroll_zoom.test.js @@ -24,6 +24,15 @@ function createMap(t) { }); } +function createMapWithRequireCtrl(t) { + t.stub(Map.prototype, '_detectMissingCSS'); + t.stub(Map.prototype, '_authenticate'); + return new Map({ + container: DOM.create('div', '', window.document.body), + scrollZoom: {requireCtrl: true}, + }); +} + test('ScrollZoomHandler', (t) => { const browserNow = t.stub(browser, 'now'); let now = 1555555555555; @@ -366,3 +375,59 @@ test('ScrollZoomHandler', (t) => { t.end(); }); + +test('When requireCtrl option is set to true, a .mapboxgl-scroll-zoom-blocker element is added to map', (t) => { + const map = createMapWithRequireCtrl(t); + + t.equal(map.getContainer().querySelectorAll('.mapboxgl-scroll-zoom-blocker').length, 1); + t.end(); +}); + +test('When requireCtrl option is set to true, scroll zoom is prevented when the ctrl key or meta key is not pressed during wheel event', (t) => { + const map = createMapWithRequireCtrl(t); + + const zoomSpy = t.spy(); + map.on('zoom', zoomSpy); + + simulate.wheel(map.getCanvas(), {type: 'wheel', deltaY: -simulate.magicWheelZoomDelta}); + + t.equal(zoomSpy.callCount, 0); + t.end(); +}); + +test('When requireCtrl option is set to true, scroll zoom is activated when ctrl key is pressed during wheel event', (t) => { + const map = createMapWithRequireCtrl(t); + + const zoomSpy = t.spy(); + map.on('zoom', zoomSpy); + + simulate.wheel(map.getCanvas(), {type: 'wheel', deltaY: -simulate.magicWheelZoomDelta, ctrlKey: true}); + + map._renderTaskQueue.run(); + + t.equal(zoomSpy.callCount, 1); + t.end(); +}); + +test('When requireCtrl option is set to true, scroll zoom is activated when meta key is pressed during wheel event', (t) => { + const map = createMapWithRequireCtrl(t); + + const zoomSpy = t.spy(); + map.on('zoom', zoomSpy); + + simulate.wheel(map.getCanvas(), {type: 'wheel', deltaY: -simulate.magicWheelZoomDelta, metaKey: true}); + + map._renderTaskQueue.run(); + + t.equal(zoomSpy.callCount, 1); + t.end(); +}); + +test('Disabling scrollZoom removes scroll zoom blocker container', (t) => { + const map = createMapWithRequireCtrl(t); + + map.scrollZoom.disable(); + + t.equal(map.getContainer().querySelectorAll('.mapboxgl-scroll-zoom-blocker').length, 0); + t.end(); +}); From 480e2de75fca2c6da6340d46f6c2c18f7cf51b5f Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 24 Sep 2021 15:25:38 -0700 Subject: [PATCH 12/23] reverted to setTimeout, transitionend event listener does not work in safari or firefox --- src/ui/handler/scroll_zoom.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 8a363e1010d..e15bd3553f0 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -398,9 +398,10 @@ class ScrollZoomHandler { if (this._container.style.visibility === 'hidden') this._container.style.visibility = 'visible'; this._container.classList.add('mapboxgl-scroll-zoom-blocker-show'); - this._container.addEventListener('transitionend', () => { + setTimeout(() => { this._container.classList.remove('mapboxgl-scroll-zoom-blocker-show'); - }, {once: true}); + }, 200) + } } From 3ccfc6f1eeb8834cd345ebe48e3b67af769a9bf8 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 24 Sep 2021 15:39:15 -0700 Subject: [PATCH 13/23] fixed lint issue --- src/ui/handler/scroll_zoom.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index e15bd3553f0..444c4a8387f 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -400,8 +400,7 @@ class ScrollZoomHandler { setTimeout(() => { this._container.classList.remove('mapboxgl-scroll-zoom-blocker-show'); - }, 200) - + }, 200); } } From 286c9572626d76500ccec5a27b802955419eed99 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 24 Sep 2021 16:29:57 -0700 Subject: [PATCH 14/23] renamed this._container for clarity --- src/css/mapbox-gl.css | 2 +- src/ui/handler/scroll_zoom.js | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index c70f83e0805..fcd37b3156a 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -773,7 +773,7 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { .mapboxgl-scroll-zoom-blocker { color: #fff; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 110%; + font-size: 100%; justify-content: center; text-align: center; position: absolute; diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 444c4a8387f..94989f8f04a 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -61,7 +61,7 @@ class ScrollZoomHandler { _wheelZoomRate: number; _requireCtrl: boolean; - _container: HTMLElement; + _alertContainer: HTMLElement; /** * @private @@ -159,7 +159,7 @@ class ScrollZoomHandler { disable() { if (!this.isEnabled()) return; this._enabled = false; - if (this._requireCtrl) this._container.remove(); + if (this._requireCtrl) this._alertContainer.remove(); } wheel(e: WheelEvent) { @@ -169,9 +169,9 @@ class ScrollZoomHandler { if (!e.ctrlKey && !e.metaKey && !this.isZooming()) { this._showBlockerAlert(); return; - } else if (this._container) { + } else if (this._alertContainer) { // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. - this._container.style.visibility = 'hidden'; + this._alertContainer.style.visibility = 'hidden'; } } @@ -379,8 +379,8 @@ class ScrollZoomHandler { } _addScrollZoomBlocker() { - if (this._map && !this._container) { - this._container = DOM.create('div', 'mapboxgl-scroll-zoom-blocker', this._map._container); + if (this._map && !this._alertContainer) { + this._alertContainer = DOM.create('div', 'mapboxgl-scroll-zoom-blocker', this._map._container); let alertMessage = ''; if (/(Mac|iPad)/i.test(window.navigator.userAgent)) { @@ -389,17 +389,16 @@ class ScrollZoomHandler { alertMessage = this._map._getUIString('ScrollZoomBlocker.CtrlMessage'); } - const textNode = window.document.createTextNode(alertMessage); - this._container.appendChild(textNode); + this._alertContainer.textContent = alertMessage; } } _showBlockerAlert() { - if (this._container.style.visibility === 'hidden') this._container.style.visibility = 'visible'; - this._container.classList.add('mapboxgl-scroll-zoom-blocker-show'); + if (this._alertContainer.style.visibility === 'hidden') this._alertContainer.style.visibility = 'visible'; + this._alertContainer.classList.add('mapboxgl-scroll-zoom-blocker-show'); setTimeout(() => { - this._container.classList.remove('mapboxgl-scroll-zoom-blocker-show'); + this._alertContainer.classList.remove('mapboxgl-scroll-zoom-blocker-show'); }, 200); } From be393b9f824c9788283274c39da7836466be74f6 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 24 Sep 2021 16:34:38 -0700 Subject: [PATCH 15/23] added use to alert messages --- src/ui/default_locale.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/default_locale.js b/src/ui/default_locale.js index ccafbc15245..520109bf1a0 100644 --- a/src/ui/default_locale.js +++ b/src/ui/default_locale.js @@ -16,8 +16,8 @@ const defaultLocale = { 'ScaleControl.Kilometers': 'km', 'ScaleControl.Miles': 'mi', 'ScaleControl.NauticalMiles': 'nm', - 'ScrollZoomBlocker.CtrlMessage': 'ctrl + scroll to zoom the map', - 'ScrollZoomBlocker.CmdMessage': '⌘ + scroll to zoom the map' + 'ScrollZoomBlocker.CtrlMessage': 'Use ctrl + scroll to zoom the map', + 'ScrollZoomBlocker.CmdMessage': 'Use ⌘ + scroll to zoom the map' }; export default defaultLocale; From 2624e4aab6f78bbaf5d7ce5c641cc3acf1268924 Mon Sep 17 00:00:00 2001 From: avpeery Date: Mon, 27 Sep 2021 13:51:55 -0700 Subject: [PATCH 16/23] dynamically set font size on adding scroll zoom blocker alert to map --- src/css/mapbox-gl.css | 2 +- src/ui/handler/scroll_zoom.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index fcd37b3156a..819ada35298 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -773,7 +773,7 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { .mapboxgl-scroll-zoom-blocker { color: #fff; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - font-size: 100%; + /* font-size: 100%; */ justify-content: center; text-align: center; position: absolute; diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 94989f8f04a..0534d4a35f1 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -60,8 +60,8 @@ class ScrollZoomHandler { _defaultZoomRate: number; _wheelZoomRate: number; - _requireCtrl: boolean; - _alertContainer: HTMLElement; + _requireCtrl: boolean; // used to require pressing meta key or ctrl key with scroll to scroll zoom + _alertContainer: HTMLElement; // used to display the scroll zoom blocker alert /** * @private @@ -381,15 +381,15 @@ class ScrollZoomHandler { _addScrollZoomBlocker() { if (this._map && !this._alertContainer) { this._alertContainer = DOM.create('div', 'mapboxgl-scroll-zoom-blocker', this._map._container); - let alertMessage = ''; if (/(Mac|iPad)/i.test(window.navigator.userAgent)) { - alertMessage = this._map._getUIString('ScrollZoomBlocker.CmdMessage'); + this._alertContainer.textContent = this._map._getUIString('ScrollZoomBlocker.CmdMessage'); } else { - alertMessage = this._map._getUIString('ScrollZoomBlocker.CtrlMessage'); + this._alertContainer.textContent = this._map._getUIString('ScrollZoomBlocker.CtrlMessage'); } - this._alertContainer.textContent = alertMessage; + // dynamically set the font size of the scroll zoom blocker alert message + this._alertContainer.style.fontSize = `${Math.max(10, Math.min(30, Math.floor(this._el.clientWidth * 0.045)))}px`; } } From d52d26bdd72507c9e1bb0db4de5075fdc2c623fd Mon Sep 17 00:00:00 2001 From: avpeery Date: Mon, 27 Sep 2021 13:54:00 -0700 Subject: [PATCH 17/23] removed comment in css --- src/css/mapbox-gl.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/css/mapbox-gl.css b/src/css/mapbox-gl.css index 819ada35298..62dbfd5142d 100644 --- a/src/css/mapbox-gl.css +++ b/src/css/mapbox-gl.css @@ -773,7 +773,6 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact { .mapboxgl-scroll-zoom-blocker { color: #fff; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; - /* font-size: 100%; */ justify-content: center; text-align: center; position: absolute; From 9940254d54fa468d98ea6b1509822998ccba668d Mon Sep 17 00:00:00 2001 From: avpeery Date: Mon, 27 Sep 2021 13:59:01 -0700 Subject: [PATCH 18/23] changed max font from 30 to 24 --- src/ui/handler/scroll_zoom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 0534d4a35f1..eb59d2725f1 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -389,7 +389,7 @@ class ScrollZoomHandler { } // dynamically set the font size of the scroll zoom blocker alert message - this._alertContainer.style.fontSize = `${Math.max(10, Math.min(30, Math.floor(this._el.clientWidth * 0.045)))}px`; + this._alertContainer.style.fontSize = `${Math.max(10, Math.min(24, Math.floor(this._el.clientWidth * 0.045)))}px`; } } From e594cc667a9b2849f12b5702f99d8669a1a695f2 Mon Sep 17 00:00:00 2001 From: avpeery Date: Tue, 28 Sep 2021 13:20:20 -0700 Subject: [PATCH 19/23] prevent scroll zoom blocker in the case that the map is full screen --- debug/scroll_zoom_blocker.html | 3 +++ src/ui/handler/scroll_zoom.js | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/debug/scroll_zoom_blocker.html b/debug/scroll_zoom_blocker.html index b57952e096a..7f8785d65d9 100644 --- a/debug/scroll_zoom_blocker.html +++ b/debug/scroll_zoom_blocker.html @@ -27,6 +27,9 @@ scrollZoom: {requireCtrl: true} }); +const fullscreen = new mapboxgl.FullscreenControl(); +map.addControl(fullscreen); + diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index eb59d2725f1..eee5694413c 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -12,6 +12,7 @@ import Point from '@mapbox/point-geometry'; import type Map from '../map.js'; import type HandlerManager from '../handler_manager.js'; import MercatorCoordinate from '../../geo/mercator_coordinate.js'; +import FullscreenControl from '../control/fullscreen_control.js'; // deltaY value for mouse scroll wheel identification const wheelZoomDelta = 4.000244140625; @@ -166,7 +167,7 @@ class ScrollZoomHandler { if (!this.isEnabled()) return; if (this._requireCtrl) { - if (!e.ctrlKey && !e.metaKey && !this.isZooming()) { + if (!e.ctrlKey && !e.metaKey && !this.isZooming() && !this._checkIfFullscreen()) { this._showBlockerAlert(); return; } else if (this._alertContainer) { @@ -393,6 +394,13 @@ class ScrollZoomHandler { } } + _checkIfFullscreen() { + // scroll zoom blocker should be prevented if map is fullscreen + for (const control of this._map._controls) { + if (control instanceof FullscreenControl) return control._fullscreen; + } + } + _showBlockerAlert() { if (this._alertContainer.style.visibility === 'hidden') this._alertContainer.style.visibility = 'visible'; this._alertContainer.classList.add('mapboxgl-scroll-zoom-blocker-show'); From 57bef2066f2e6c4c54f5626159f23353ac53edb2 Mon Sep 17 00:00:00 2001 From: avpeery Date: Tue, 28 Sep 2021 13:27:34 -0700 Subject: [PATCH 20/23] cleaned up the debug html --- debug/scroll_zoom_blocker.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/debug/scroll_zoom_blocker.html b/debug/scroll_zoom_blocker.html index 7f8785d65d9..f380fd9b6bb 100644 --- a/debug/scroll_zoom_blocker.html +++ b/debug/scroll_zoom_blocker.html @@ -27,8 +27,7 @@ scrollZoom: {requireCtrl: true} }); -const fullscreen = new mapboxgl.FullscreenControl(); -map.addControl(fullscreen); +map.addControl(new mapboxgl.FullscreenControl()); From c4de95953a00ec6819caa49d2e44054f432b39a0 Mon Sep 17 00:00:00 2001 From: avpeery Date: Wed, 29 Sep 2021 11:16:19 -0700 Subject: [PATCH 21/23] changed method name to isFullscreen, bumped up dynamically set font size --- src/ui/handler/scroll_zoom.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index eee5694413c..71c550f3b72 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -77,7 +77,7 @@ class ScrollZoomHandler { this._defaultZoomRate = defaultZoomRate; this._wheelZoomRate = wheelZoomRate; - bindAll(['_onTimeout', '_addScrollZoomBlocker', '_showBlockerAlert'], this); + bindAll(['_onTimeout', '_addScrollZoomBlocker', '_showBlockerAlert', '_isFullscreen'], this); } @@ -167,7 +167,7 @@ class ScrollZoomHandler { if (!this.isEnabled()) return; if (this._requireCtrl) { - if (!e.ctrlKey && !e.metaKey && !this.isZooming() && !this._checkIfFullscreen()) { + if (!e.ctrlKey && !e.metaKey && !this.isZooming() && !this._isFullscreen()) { this._showBlockerAlert(); return; } else if (this._alertContainer) { @@ -390,11 +390,11 @@ class ScrollZoomHandler { } // dynamically set the font size of the scroll zoom blocker alert message - this._alertContainer.style.fontSize = `${Math.max(10, Math.min(24, Math.floor(this._el.clientWidth * 0.045)))}px`; + this._alertContainer.style.fontSize = `${Math.max(10, Math.min(24, Math.floor(this._el.clientWidth * 0.05)))}px`; } } - _checkIfFullscreen() { + _isFullscreen() { // scroll zoom blocker should be prevented if map is fullscreen for (const control of this._map._controls) { if (control instanceof FullscreenControl) return control._fullscreen; From bab2baaa4d560935140544f54692330a05eb721f Mon Sep 17 00:00:00 2001 From: avpeery Date: Thu, 30 Sep 2021 17:09:30 -0700 Subject: [PATCH 22/23] replaced requireCtrl scrollZoom option with gestureHandling map option --- debug/scroll_zoom_blocker.html | 2 +- src/ui/handler/scroll_zoom.js | 11 +++-------- src/ui/map.js | 5 +++++ test/unit/ui/handler/scroll_zoom.test.js | 22 +++++++++++----------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/debug/scroll_zoom_blocker.html b/debug/scroll_zoom_blocker.html index f380fd9b6bb..5bb785705db 100644 --- a/debug/scroll_zoom_blocker.html +++ b/debug/scroll_zoom_blocker.html @@ -24,7 +24,7 @@ zoom: 12.5, center: [-77.01866, 38.888], style: 'mapbox://styles/mapbox/streets-v10', - scrollZoom: {requireCtrl: true} + gestureHandling: true }); map.addControl(new mapboxgl.FullscreenControl()); diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 71c550f3b72..1e8dbd086fe 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -61,7 +61,6 @@ class ScrollZoomHandler { _defaultZoomRate: number; _wheelZoomRate: number; - _requireCtrl: boolean; // used to require pressing meta key or ctrl key with scroll to scroll zoom _alertContainer: HTMLElement; // used to display the scroll zoom blocker alert /** @@ -134,21 +133,17 @@ class ScrollZoomHandler { * * @param {Object} [options] Options object. * @param {string} [options.around] If "center" is passed, map will zoom around center of map. - * @param {boolean} [options.requireCtrl] If set to true, ctrl (or ⌘ in OS devices) must be pressed while scrolling to zoom. * * @example * map.scrollZoom.enable(); * @example * map.scrollZoom.enable({around: 'center'}); - * @example - * map.scrollZoom.enable({requireCtrl: true}); */ enable(options: any) { if (this.isEnabled()) return; this._enabled = true; this._aroundCenter = options && options.around === 'center'; - this._requireCtrl = options && options.requireCtrl === true; - if (this._requireCtrl) this._addScrollZoomBlocker(); + if (this._map._gestureHandling) this._addScrollZoomBlocker(); } /** @@ -160,13 +155,13 @@ class ScrollZoomHandler { disable() { if (!this.isEnabled()) return; this._enabled = false; - if (this._requireCtrl) this._alertContainer.remove(); + if (this._map._gestureHandling) this._alertContainer.remove(); } wheel(e: WheelEvent) { if (!this.isEnabled()) return; - if (this._requireCtrl) { + if (this._map._gestureHandling) { if (!e.ctrlKey && !e.metaKey && !this.isZooming() && !this._isFullscreen()) { this._showBlockerAlert(); return; diff --git a/src/ui/map.js b/src/ui/map.js index eee0bbef0e0..c633a88ffd5 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -106,6 +106,7 @@ type MapOptions = { doubleClickZoom?: boolean, touchZoomRotate?: boolean, touchPitch?: boolean, + gestureHandling?: boolean, trackResize?: boolean, center?: LngLatLike, zoom?: number, @@ -148,6 +149,7 @@ const defaultOptions = { doubleClickZoom: true, touchZoomRotate: true, touchPitch: true, + gestureHandling: false, bearingSnap: 7, clickTolerance: 3, @@ -234,6 +236,7 @@ const defaultOptions = { * @param {boolean} [options.doubleClickZoom=true] If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}). * @param {boolean | Object} [options.touchZoomRotate=true] If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}. * @param {boolean | Object} [options.touchPitch=true] If `true`, the "drag to pitch" interaction is enabled. An `Object` value is passed as options to {@link TouchPitchHandler#enable}. + * @param {boolean} [options.gestureHandling=true] If `true`, scroll zoom will require pressing ctrl or ⌘ keys while scrolling to zoom map. * @param {boolean} [options.trackResize=true] If `true`, the map will automatically resize when the browser window resizes. * @param {LngLatLike} [options.center=[0, 0]] The inital geographical centerpoint of the map. If `center` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON. * @param {number} [options.zoom=0] The initial zoom level of the map. If `zoom` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. @@ -342,6 +345,7 @@ class Map extends Camera { _removed: boolean; _speedIndexTiming: boolean; _clickTolerance: number; + _gestureHandling: boolean; _silenceAuthErrors: boolean; _averageElevationLastSampledAt: number; _averageElevation: EasedVariable; @@ -442,6 +446,7 @@ class Map extends Camera { this._mapId = uniqueId(); this._locale = extend({}, defaultLocale, options.locale); this._clickTolerance = options.clickTolerance; + this._gestureHandling = options.gestureHandling; this._averageElevationLastSampledAt = -Infinity; this._averageElevation = new EasedVariable(0); diff --git a/test/unit/ui/handler/scroll_zoom.test.js b/test/unit/ui/handler/scroll_zoom.test.js index ffb68d8fec6..3fabc22e563 100644 --- a/test/unit/ui/handler/scroll_zoom.test.js +++ b/test/unit/ui/handler/scroll_zoom.test.js @@ -24,12 +24,12 @@ function createMap(t) { }); } -function createMapWithRequireCtrl(t) { +function createMapWithGestureHandling(t) { t.stub(Map.prototype, '_detectMissingCSS'); t.stub(Map.prototype, '_authenticate'); return new Map({ container: DOM.create('div', '', window.document.body), - scrollZoom: {requireCtrl: true}, + gestureHandling: true }); } @@ -376,15 +376,15 @@ test('ScrollZoomHandler', (t) => { t.end(); }); -test('When requireCtrl option is set to true, a .mapboxgl-scroll-zoom-blocker element is added to map', (t) => { - const map = createMapWithRequireCtrl(t); +test('When gestureHandling option is set to true, a .mapboxgl-scroll-zoom-blocker element is added to map', (t) => { + const map = createMapWithGestureHandling(t); t.equal(map.getContainer().querySelectorAll('.mapboxgl-scroll-zoom-blocker').length, 1); t.end(); }); -test('When requireCtrl option is set to true, scroll zoom is prevented when the ctrl key or meta key is not pressed during wheel event', (t) => { - const map = createMapWithRequireCtrl(t); +test('When gestureHandling option is set to true, scroll zoom is prevented when the ctrl key or meta key is not pressed during wheel event', (t) => { + const map = createMapWithGestureHandling(t); const zoomSpy = t.spy(); map.on('zoom', zoomSpy); @@ -395,8 +395,8 @@ test('When requireCtrl option is set to true, scroll zoom is prevented when the t.end(); }); -test('When requireCtrl option is set to true, scroll zoom is activated when ctrl key is pressed during wheel event', (t) => { - const map = createMapWithRequireCtrl(t); +test('When gestureHandling option is set to true, scroll zoom is activated when ctrl key is pressed during wheel event', (t) => { + const map = createMapWithGestureHandling(t); const zoomSpy = t.spy(); map.on('zoom', zoomSpy); @@ -409,8 +409,8 @@ test('When requireCtrl option is set to true, scroll zoom is activated when ctrl t.end(); }); -test('When requireCtrl option is set to true, scroll zoom is activated when meta key is pressed during wheel event', (t) => { - const map = createMapWithRequireCtrl(t); +test('When gestureHandling option is set to true, scroll zoom is activated when meta key is pressed during wheel event', (t) => { + const map = createMapWithGestureHandling(t); const zoomSpy = t.spy(); map.on('zoom', zoomSpy); @@ -424,7 +424,7 @@ test('When requireCtrl option is set to true, scroll zoom is activated when meta }); test('Disabling scrollZoom removes scroll zoom blocker container', (t) => { - const map = createMapWithRequireCtrl(t); + const map = createMapWithGestureHandling(t); map.scrollZoom.disable(); From 6a7adff03e4218d95a68663ad63311cef18fd196 Mon Sep 17 00:00:00 2001 From: avpeery Date: Fri, 1 Oct 2021 13:25:10 -0700 Subject: [PATCH 23/23] set isFullscreen to check window fullscreen instead of control, and set clear timeout --- src/ui/handler/scroll_zoom.js | 16 ++++++++-------- src/ui/map.js | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ui/handler/scroll_zoom.js b/src/ui/handler/scroll_zoom.js index 1e8dbd086fe..74084468297 100644 --- a/src/ui/handler/scroll_zoom.js +++ b/src/ui/handler/scroll_zoom.js @@ -12,7 +12,6 @@ import Point from '@mapbox/point-geometry'; import type Map from '../map.js'; import type HandlerManager from '../handler_manager.js'; import MercatorCoordinate from '../../geo/mercator_coordinate.js'; -import FullscreenControl from '../control/fullscreen_control.js'; // deltaY value for mouse scroll wheel identification const wheelZoomDelta = 4.000244140625; @@ -62,6 +61,7 @@ class ScrollZoomHandler { _wheelZoomRate: number; _alertContainer: HTMLElement; // used to display the scroll zoom blocker alert + _alertTimer: TimeoutID; /** * @private @@ -165,9 +165,10 @@ class ScrollZoomHandler { if (!e.ctrlKey && !e.metaKey && !this.isZooming() && !this._isFullscreen()) { this._showBlockerAlert(); return; - } else if (this._alertContainer) { - // immediately hide alert if it is visible when ctrl is pressed while scroll zooming. + } else if (this._alertContainer.style.visibility !== 'hidden') { + // immediately hide alert if it is visible when ctrl or ⌘ is pressed while scroll zooming. this._alertContainer.style.visibility = 'hidden'; + clearTimeout(this._alertTimer); } } @@ -390,17 +391,16 @@ class ScrollZoomHandler { } _isFullscreen() { - // scroll zoom blocker should be prevented if map is fullscreen - for (const control of this._map._controls) { - if (control instanceof FullscreenControl) return control._fullscreen; - } + return window.document.fullscreenElement !== null; } _showBlockerAlert() { if (this._alertContainer.style.visibility === 'hidden') this._alertContainer.style.visibility = 'visible'; this._alertContainer.classList.add('mapboxgl-scroll-zoom-blocker-show'); - setTimeout(() => { + clearTimeout(this._alertTimer); + + this._alertTimer = setTimeout(() => { this._alertContainer.classList.remove('mapboxgl-scroll-zoom-blocker-show'); }, 200); } diff --git a/src/ui/map.js b/src/ui/map.js index c633a88ffd5..da183a2d39b 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -236,7 +236,7 @@ const defaultOptions = { * @param {boolean} [options.doubleClickZoom=true] If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}). * @param {boolean | Object} [options.touchZoomRotate=true] If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}. * @param {boolean | Object} [options.touchPitch=true] If `true`, the "drag to pitch" interaction is enabled. An `Object` value is passed as options to {@link TouchPitchHandler#enable}. - * @param {boolean} [options.gestureHandling=true] If `true`, scroll zoom will require pressing ctrl or ⌘ keys while scrolling to zoom map. + * @param {boolean} [options.gestureHandling=false] If `true`, scroll zoom will require pressing the ctrl or ⌘ key while scrolling to zoom map. * @param {boolean} [options.trackResize=true] If `true`, the map will automatically resize when the browser window resizes. * @param {LngLatLike} [options.center=[0, 0]] The inital geographical centerpoint of the map. If `center` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON. * @param {number} [options.zoom=0] The initial zoom level of the map. If `zoom` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.