From ab467a94ab9071fa112463d6d48851d83f488bf8 Mon Sep 17 00:00:00 2001 From: Norbert Renner Date: Fri, 2 Aug 2019 19:39:47 +0200 Subject: [PATCH] Improve opacity slider (#215) - adopt horizontal styles - common font size for layers tab - adopt to layer switcher layout with slider as child of label element - separate slider wrapper from control, as overlay slider is none - migrate localStorage legacy key --- css/style.css | 25 +++++++----- index.html | 18 +++------ js/control/LayersTab.js | 4 +- js/control/OpacitySlider.js | 59 ++++++--------------------- js/control/OpacitySliderControl.js | 64 ++++++++++++++++++++++++++++++ js/index.js | 3 +- 6 files changed, 103 insertions(+), 70 deletions(-) create mode 100644 js/control/OpacitySliderControl.js diff --git a/css/style.css b/css/style.css index 3abcbad..dd96a07 100644 --- a/css/style.css +++ b/css/style.css @@ -236,22 +236,34 @@ https://css-tricks.com/svg-line-animation-works/ .control-slider { background: #fff; border-radius: 10px; - padding-top: 10px; - padding-bottom: 10px; +} + +.slider#overlay { + display: block; } .slider.slider-vertical { height: 80px; + margin: 10px 0; +} +.slider.slider-horizontal { + width: 180px; + margin: 0 10px; } /* invert track and selection styles to get partial gradient for "selection" */ -.slider .slider-track { +.slider.slider-vertical .slider-track { width: 8px; margin-left: 1px; background-image: linear-gradient(to right, #f0f0f0 0%, #e9e9e9 100%); box-shadow: inset -1px -0px 1px rgba(55, 55, 55, 0.3), inset 1px 0px 1px rgba(230, 230, 230, 1); } +.slider.slider-horizontal .slider-track { + background-image: linear-gradient(to bottom, #f0f0f0 0%, #e9e9e9 100%); + box-shadow: inset -0px -1px 1px rgba(55, 55, 55, 0.3), + inset 0px 1px 1px rgba(230, 230, 230, 1); +} .control-slider:hover #route .slider-track, .control-slider:active #route .slider-track { @@ -319,10 +331,6 @@ button.btn { line-height: 30px; } -#leaflet-control-layers-overlays-opacity-slider .leaflet-bar { - box-shadow: none; -} - /* smaller tab height */ .nav > li > a { padding: 2px 15px; @@ -431,8 +439,7 @@ table.dataTable.display tbody tr.even:hover { } /* layers control as sidebar tab */ -#layers-control-wrapper label, -#optional-layers-tree { +#tab_layers_control { font-size: 0.9rem; line-height: normal; } diff --git a/index.html b/index.html index d74bfa7..2539e3e 100644 --- a/index.html +++ b/index.html @@ -821,18 +821,12 @@
-
-

- Overlay transparency - -

+
+
diff --git a/js/control/LayersTab.js b/js/control/LayersTab.js index e1e78b5..ae94b45 100644 --- a/js/control/LayersTab.js +++ b/js/control/LayersTab.js @@ -66,10 +66,10 @@ BR.LayersTab = BR.ControlLayers.extend({ self._layers[i].layer.setOpacity(opacity); } } - }).onAdd(map); + }); L.DomUtil.get( 'leaflet-control-layers-overlays-opacity-slider' - ).appendChild(overlayOpacitySlider); + ).appendChild(overlayOpacitySlider.getElement()); }, initButtons: function() { diff --git a/js/control/OpacitySlider.js b/js/control/OpacitySlider.js index c2293e2..eaf8820 100644 --- a/js/control/OpacitySlider.js +++ b/js/control/OpacitySlider.js @@ -1,19 +1,19 @@ -BR.OpacitySlider = L.Control.extend({ +BR.OpacitySlider = L.Class.extend({ options: { id: '', - position: 'topleft', reversed: true, orientation: 'vertical', defaultValue: BR.conf.defaultOpacity, - title: i18next.t('map.opacity-slider'), + title: '', callback: function(opacity) {} }, - onAdd: function(map) { - var container = L.DomUtil.create('div', 'leaflet-bar control-slider'), - input = $( + initialize: function(options) { + L.setOptions(this, options); + + var input = (this.input = $( '' - ), + )), item = BR.Util.localStorageAvailable() ? localStorage['opacitySliderValue' + this.options.id] : null, @@ -24,25 +24,6 @@ BR.OpacitySlider = L.Control.extend({ value = minOpacity; } - // prevent also dragging map in Chrome - L.DomEvent.disableClickPropagation(container); - - var stopClickAfterSlide = function(evt) { - L.DomEvent.stop(evt); - removeStopClickListeners(); - }; - var removeStopClickListeners = function() { - document.removeEventListener('click', stopClickAfterSlide, true); - document.removeEventListener( - 'mousedown', - removeStopClickListeners, - true - ); - }; - - $(container).html(input); - $(container).attr('title', this.options.title); - input .slider({ id: this.options.id, @@ -55,10 +36,6 @@ BR.OpacitySlider = L.Control.extend({ selection: this.options.reversed ? 'before' : 'after', // inverted, serves as track style, see css tooltip: 'hide' }) - .on('slideStart', function(evt) { - // dragging beyond slider control selects zoom control +/- text in Firefox - L.DomUtil.disableTextSelection(); - }) .on('slide slideStop', { self: this }, function(evt) { evt.data.self.options.callback(evt.value / 100); }) @@ -68,24 +45,14 @@ BR.OpacitySlider = L.Control.extend({ 'opacitySliderValue' + evt.data.self.options.id ] = evt.value; } - - L.DomUtil.enableTextSelection(); - - // When dragging outside slider and over map, click event after mouseup - // adds marker when active on Chromium. So disable click (not needed) - // once after sliding. - document.addEventListener('click', stopClickAfterSlide, true); - // Firefox does not fire click event in this case, so make sure stop listener - // is always removed on next mousedown. - document.addEventListener( - 'mousedown', - removeStopClickListeners, - true - ); }); - this.options.callback(value / 100); + this.getElement().title = this.options.title; - return container; + this.options.callback(value / 100); + }, + + getElement: function() { + return this.input.slider('getElement'); } }); diff --git a/js/control/OpacitySliderControl.js b/js/control/OpacitySliderControl.js new file mode 100644 index 0000000..7fb17ed --- /dev/null +++ b/js/control/OpacitySliderControl.js @@ -0,0 +1,64 @@ +BR.OpacitySliderControl = L.Control.extend({ + options: { + position: 'topleft' + }, + + onAdd: function(map) { + var container = L.DomUtil.create('div', 'leaflet-bar control-slider'); + + // prevent also dragging map in Chrome + L.DomEvent.disableClickPropagation(container); + + // migrate legacy value + if (BR.Util.localStorageAvailable()) { + var value = localStorage.getItem('opacitySliderValue'); + if (value !== null) { + localStorage.setItem( + 'opacitySliderValue' + this.options.id, + value + ); + localStorage.removeItem('opacitySliderValue'); + } + } + + var slider = new BR.OpacitySlider(this.options); + container.appendChild(slider.getElement()); + + var stopClickAfterSlide = function(evt) { + L.DomEvent.stop(evt); + removeStopClickListeners(); + }; + + var removeStopClickListeners = function() { + document.removeEventListener('click', stopClickAfterSlide, true); + document.removeEventListener( + 'mousedown', + removeStopClickListeners, + true + ); + }; + + slider.input + .on('slideStart', function(evt) { + // dragging beyond slider control selects zoom control +/- text in Firefox + L.DomUtil.disableTextSelection(); + }) + .on('slideStop', { self: this }, function(evt) { + L.DomUtil.enableTextSelection(); + + // When dragging outside slider and over map, click event after mouseup + // adds marker when active on Chromium. So disable click (not needed) + // once after sliding. + document.addEventListener('click', stopClickAfterSlide, true); + // Firefox does not fire click event in this case, so make sure stop listener + // is always removed on next mousedown. + document.addEventListener( + 'mousedown', + removeStopClickListeners, + true + ); + }); + + return container; + } +}); diff --git a/js/index.js b/js/index.js index abb19f1..805968d 100644 --- a/js/index.js +++ b/js/index.js @@ -282,8 +282,9 @@ } map.addControl( - new BR.OpacitySlider({ + new BR.OpacitySliderControl({ id: 'route', + title: i18next.t('map.opacity-slider'), callback: L.bind(routing.setOpacity, routing) }) );