add opacity slider (bootstrap-slider) for route track and markers

This commit is contained in:
Norbert Renner 2015-05-21 20:16:04 +02:00
parent 0b22a75d18
commit d30684b6c8
6 changed files with 143 additions and 4 deletions

View file

@ -0,0 +1,52 @@
BR.OpacitySlider = L.Control.extend({
options: {
position: 'topleft',
callback: function(opacity) {}
},
onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-bar control-slider'),
input = $('<input id="slider" type="text"/>'),
item = localStorage.opacitySliderValue,
value = item ? parseInt(item) : 100;
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', 'Set transparency of route track and markers');
input.slider({
min: 0,
max: 100,
step: 1,
value: value,
orientation: 'vertical',
reversed : true,
selection: 'before', // inverted, serves as track style, see css
tooltip: 'hide'
}).on('slide slideStop', { self: this }, function (evt) {
evt.data.self.options.callback(evt.value / 100);
}).on('slideStop', function (evt) {
localStorage.opacitySliderValue = evt.value;
// 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);
return container;
}
});

View file

@ -217,6 +217,7 @@
trackCasing: {
weight: 8,
color: 'white',
// assumed to be same as track, see setOpacity
opacity: 1
},
nodata: {
@ -276,6 +277,9 @@
nogos.addTo(map);
routing.addTo(map);
map.addControl(new BR.OpacitySlider({
callback: L.bind(routing.setOpacity, routing)
}));
// initial option settings (after controls are added and initialized with onAdd, before permalink)
router.setOptions(nogos.getOptions());
@ -293,7 +297,7 @@
profile: profile
}).addTo(map);
}
initMap();
initApp();

View file

@ -1,12 +1,14 @@
BR.Routing = L.Routing.extend({
options: {
position: 'topright',
icons: {
/* not implemented yet
start: new L.Icon.Default({iconUrl: 'bower_components/leaflet-gpx/pin-icon-start.png'}),
end: new L.Icon.Default(),
normal: new L.Icon.Default()
*/
draw: false
draw: false,
opacity: 1
},
snapping: null,
zIndexOffset: -2000
@ -20,6 +22,8 @@ BR.Routing = L.Routing.extend({
this._segments.on('layeradd', this._addSegmentCasing, this);
this._segments.on('layerremove', this._removeSegmentCasing, this);
this._waypoints.on('layeradd', this._setMarkerOpacity, this);
// turn line mouse marker off while over waypoint marker
this.on('waypoint:mouseover', function(e) {
// L.Routing.Edit._segmentOnMouseout without firing 'segment:mouseout' (enables draw)
@ -102,6 +106,33 @@ BR.Routing = L.Routing.extend({
this._segmentsCasing.removeLayer(e.layer._casing);
}
,setOpacity: function(opacity) {
// Due to the second Polyline layer for casing, the combined opacity is less
// transparent than with a single layer and the slider is non-linear. The
// inverted formula is used to get the same result as with a single layer.
// SVG simple alpha compositing: Ca' = 1 - (1 - Ea) * (1 - Ca)
// http://www.w3.org/TR/SVG11/masking.html#SimpleAlphaBlending
var sourceOpacity = 1 - Math.sqrt(1 - opacity);
this.options.styles.track.opacity = sourceOpacity;
this.options.styles.trackCasing.opacity = sourceOpacity;
this.options.icons.opacity = opacity;
this._segments.setStyle({
opacity: sourceOpacity
});
this._segmentsCasing.setStyle({
opacity: sourceOpacity
});
this._waypoints.eachLayer(function(marker) {
marker.setOpacity(opacity);
});
}
,_setMarkerOpacity: function(e) {
e.layer.setOpacity(this.options.icons.opacity);
}
,_removeMarkerEvents: function(marker) {
marker.off('mouseover', this._fireWaypointEvent, this);
marker.off('mouseout' , this._fireWaypointEvent, this);
@ -186,7 +217,8 @@ BR.Routing = L.Routing.extend({
// animate dashed trailer as loading indicator
if (m1 && m2) {
loadingTrailer = new L.Polyline([m1.getLatLng(), m2.getLatLng()], {
opacity: 0.6,
color: this.options.styles.track.color,
opacity: this.options.styles.trailer.opacity,
dashArray: [10, 10],
className: 'loading-trailer'
});