Update Leaflet.zoomslider
This commit is contained in:
parent
cec2253b82
commit
15423c2130
2 changed files with 264 additions and 246 deletions
412
vendor/assets/leaflet/leaflet.zoom.js
vendored
412
vendor/assets/leaflet/leaflet.zoom.js
vendored
|
@ -1,199 +1,213 @@
|
|||
L.Control.Zoomslider = L.Control.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
// height in px of zoom-slider.png
|
||||
stepHeight: 9
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var className = 'leaflet-control-zoomslider',
|
||||
container = L.DomUtil.create('div', className);
|
||||
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
this._map = map;
|
||||
|
||||
this._zoomInButton = this._createButton('Zoom in', className + '-in'
|
||||
, container, this._zoomIn , this);
|
||||
this._createSlider(className + '-slider', container, map);
|
||||
this._zoomOutButton = this._createButton('Zoom out', className + '-out'
|
||||
, container, this._zoomOut, this);
|
||||
|
||||
map.on('layeradd layerremove', this._refresh, this);
|
||||
|
||||
map.whenReady(function(){
|
||||
this._snapToSliderValue();
|
||||
map.on('zoomend', this._snapToSliderValue, this);
|
||||
}, this);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
onRemove: function(map){
|
||||
map.off('zoomend', this._snapToSliderValue);
|
||||
map.off('layeradd layerremove', this._refresh);
|
||||
},
|
||||
|
||||
_refresh: function(){
|
||||
this._map
|
||||
.removeControl(this)
|
||||
.addControl(this);
|
||||
},
|
||||
|
||||
_createSlider: function (className, container, map) {
|
||||
var zoomLevels = map.getMaxZoom() - map.getMinZoom();
|
||||
// This means we have no tilelayers (or that they are setup in a strange way).
|
||||
// Either way we don't want to add a slider here.
|
||||
if(zoomLevels == Infinity){
|
||||
return undefined;
|
||||
}
|
||||
this._sliderHeight = this.options.stepHeight * zoomLevels;
|
||||
|
||||
var wrapper = L.DomUtil.create('div', className + '-wrap', container);
|
||||
wrapper.style.height = (this._sliderHeight + 5) + "px";
|
||||
var slider = L.DomUtil.create('div', className, wrapper);
|
||||
this._knob = L.DomUtil.create('div', className + '-knob', slider);
|
||||
|
||||
this._draggable = this._createDraggable();
|
||||
this._draggable.enable();
|
||||
|
||||
L.DomEvent.on(slider, 'click', this._onSliderClick, this);
|
||||
|
||||
return slider;
|
||||
},
|
||||
|
||||
_zoomIn: function (e) {
|
||||
this._map.zoomIn(e.shiftKey ? 3 : 1);
|
||||
},
|
||||
|
||||
_zoomOut: function (e) {
|
||||
this._map.zoomOut(e.shiftKey ? 3 : 1);
|
||||
},
|
||||
|
||||
_createButton: function (title, className, container, fn, context) {
|
||||
var link = L.DomUtil.create('a', className, container);
|
||||
link.href = '#';
|
||||
link.title = title;
|
||||
|
||||
L.DomEvent
|
||||
.on(link, 'click', L.DomEvent.preventDefault)
|
||||
.on(link, 'click', fn, context);
|
||||
|
||||
return link;
|
||||
},
|
||||
|
||||
_createDraggable: function() {
|
||||
L.DomUtil.setPosition(this._knob, L.point(0, 0));
|
||||
L.DomEvent.disableClickPropagation(this._knob);
|
||||
|
||||
var bounds = new L.Bounds(
|
||||
L.point(0, 0),
|
||||
L.point(0, this._sliderHeight)
|
||||
);
|
||||
var draggable = new L.BoundedDraggable(this._knob,
|
||||
this._knob,
|
||||
bounds)
|
||||
.on('drag', this._snap, this)
|
||||
.on('dragend', this._setZoom, this);
|
||||
|
||||
return draggable;
|
||||
},
|
||||
|
||||
_snap : function(){
|
||||
this._snapToSliderValue(this._posToSliderValue());
|
||||
},
|
||||
_setZoom: function() {
|
||||
this._map.setZoom(this._toZoomLevel(this._posToSliderValue()));
|
||||
},
|
||||
|
||||
_onSliderClick: function(e){
|
||||
var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e);
|
||||
var offset = first.offsetY
|
||||
? first.offsetY
|
||||
: L.DomEvent.getMousePosition(first).y
|
||||
- L.DomUtil.getViewportOffset(this._knob).y;
|
||||
var value = this._posToSliderValue(offset - this._knob.offsetHeight / 2);
|
||||
this._snapToSliderValue(value);
|
||||
this._map.setZoom(this._toZoomLevel(value));
|
||||
},
|
||||
|
||||
_posToSliderValue: function(pos) {
|
||||
pos = isNaN(pos)
|
||||
? L.DomUtil.getPosition(this._knob).y
|
||||
: pos;
|
||||
return Math.round( (this._sliderHeight - pos) / this.options.stepHeight);
|
||||
},
|
||||
|
||||
_snapToSliderValue: function(sliderValue) {
|
||||
this._updateDisabled();
|
||||
if(this._knob) {
|
||||
sliderValue = isNaN(sliderValue)
|
||||
? this._getSliderValue()
|
||||
: sliderValue;
|
||||
var y = this._sliderHeight
|
||||
- (sliderValue * this.options.stepHeight);
|
||||
L.DomUtil.setPosition(this._knob, L.point(0, y));
|
||||
}
|
||||
},
|
||||
_toZoomLevel: function(sliderValue) {
|
||||
return sliderValue + this._map.getMinZoom();
|
||||
},
|
||||
_toSliderValue: function(zoomLevel) {
|
||||
return zoomLevel - this._map.getMinZoom();
|
||||
},
|
||||
_getSliderValue: function(){
|
||||
return this._toSliderValue(this._map.getZoom());
|
||||
},
|
||||
|
||||
_updateDisabled: function () {
|
||||
var map = this._map,
|
||||
className = 'leaflet-control-zoomslider-disabled';
|
||||
|
||||
L.DomUtil.removeClass(this._zoomInButton, className);
|
||||
L.DomUtil.removeClass(this._zoomOutButton, className);
|
||||
|
||||
if (map.getZoom() === map.getMinZoom()) {
|
||||
L.DomUtil.addClass(this._zoomOutButton, className);
|
||||
}
|
||||
if (map.getZoom() === map.getMaxZoom()) {
|
||||
L.DomUtil.addClass(this._zoomInButton, className);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.mergeOptions({
|
||||
zoomControl: false,
|
||||
zoomsliderControl: true
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.zoomsliderControl) {
|
||||
L.control.zoomslider().addTo(this);
|
||||
}
|
||||
});
|
||||
|
||||
L.control.zoomslider = function (options) {
|
||||
return new L.Control.Zoomslider(options);
|
||||
};
|
||||
|
||||
|
||||
L.BoundedDraggable = L.Draggable.extend({
|
||||
initialize: function(element, dragStartTarget, bounds) {
|
||||
L.Draggable.prototype.initialize.call(this, element, dragStartTarget);
|
||||
this._bounds = bounds;
|
||||
this.on('predrag', function() {
|
||||
if(!this._bounds.contains(this._newPos)){
|
||||
this._newPos = this._fitPoint(this._newPos);
|
||||
}
|
||||
}, this);
|
||||
},
|
||||
_fitPoint: function(point){
|
||||
var closest = L.point(
|
||||
Math.min(point.x, this._bounds.max.x),
|
||||
Math.min(point.y, this._bounds.max.y)
|
||||
);
|
||||
closest.x = Math.max(closest.x, this._bounds.min.x);
|
||||
closest.y = Math.max(closest.y, this._bounds.min.y);
|
||||
return closest;
|
||||
}
|
||||
});
|
||||
L.Control.Zoomslider = (function () {
|
||||
|
||||
var Knob = L.Draggable.extend({
|
||||
initialize: function (element, stepHeight, knobHeight) {
|
||||
L.Draggable.prototype.initialize.call(this, element, element);
|
||||
this._element = element;
|
||||
|
||||
this._stepHeight = stepHeight;
|
||||
this._knobHeight = knobHeight;
|
||||
|
||||
this.on('predrag', function () {
|
||||
this._newPos.x = 0;
|
||||
this._newPos.y = this._adjust(this._newPos.y);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_adjust: function (y) {
|
||||
var value = Math.round(this._toValue(y));
|
||||
value = Math.max(0, Math.min(this._maxValue, value));
|
||||
return this._toY(value);
|
||||
},
|
||||
|
||||
// y = k*v + m
|
||||
_toY: function (value) {
|
||||
return this._k * value + this._m;
|
||||
},
|
||||
// v = (y - m) / k
|
||||
_toValue: function (y) {
|
||||
return (y - this._m) / this._k;
|
||||
},
|
||||
|
||||
setSteps: function (steps) {
|
||||
var sliderHeight = steps * this._stepHeight;
|
||||
this._maxValue = steps - 1;
|
||||
|
||||
// conversion parameters
|
||||
// the conversion is just a common linear function.
|
||||
this._k = -this._stepHeight;
|
||||
this._m = sliderHeight - (this._stepHeight + this._knobHeight) / 2;
|
||||
},
|
||||
|
||||
setPosition: function (y) {
|
||||
L.DomUtil.setPosition(this._element,
|
||||
L.point(0, this._adjust(y)));
|
||||
},
|
||||
|
||||
setValue: function (v) {
|
||||
this.setPosition(this._toY(v));
|
||||
},
|
||||
|
||||
getValue: function () {
|
||||
return this._toValue(L.DomUtil.getPosition(this._element).y);
|
||||
}
|
||||
});
|
||||
|
||||
var Zoomslider = L.Control.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
// Height of zoom-slider.png in px
|
||||
stepHeight: 9,
|
||||
// Height of the knob div in px
|
||||
knobHeight: 5,
|
||||
styleNS: 'leaflet-control-zoomslider'
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var container = L.DomUtil.create('div', this.options.styleNS + ' leaflet-bar');
|
||||
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
this._map = map;
|
||||
|
||||
this._zoomInButton = this._createZoomButton(
|
||||
'in', 'top', container, this._zoomIn);
|
||||
|
||||
this._sliderElem = L.DomUtil.create(
|
||||
'div',
|
||||
this.options.styleNS + "-slider leaflet-bar-part",
|
||||
container);
|
||||
|
||||
this._zoomOutButton = this._createZoomButton(
|
||||
'out', 'bottom', container, this._zoomOut);
|
||||
|
||||
map .on('zoomlevelschange', this._refresh, this)
|
||||
.on("zoomend", this._updateKnob, this)
|
||||
.on("zoomend", this._updateDisabled, this)
|
||||
.whenReady(this._createSlider, this)
|
||||
.whenReady(this._createKnob, this)
|
||||
.whenReady(this._refresh, this);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
map .off("zoomend", this._updateKnob)
|
||||
.off("zoomend", this._updateDisabled)
|
||||
.off('zoomlevelschange', this._refresh);
|
||||
},
|
||||
|
||||
_refresh: function () {
|
||||
var zoomLevels = this._zoomLevels();
|
||||
if (zoomLevels < Infinity && this._knob && this._sliderBody) {
|
||||
this._setSteps(zoomLevels);
|
||||
this._updateKnob();
|
||||
this._updateDisabled();
|
||||
}
|
||||
},
|
||||
_zoomLevels: function () {
|
||||
return this._map.getMaxZoom() - this._map.getMinZoom() + 1;
|
||||
},
|
||||
|
||||
_createSlider: function () {
|
||||
this._sliderBody = L.DomUtil.create('div',
|
||||
this.options.styleNS + '-slider-body',
|
||||
this._sliderElem);
|
||||
L.DomEvent.on(this._sliderBody, 'click', this._onSliderClick, this);
|
||||
},
|
||||
|
||||
_createKnob: function () {
|
||||
var knobElem = L.DomUtil.create('div', this.options.styleNS + '-slider-knob',
|
||||
this._sliderBody);
|
||||
L.DomEvent.disableClickPropagation(knobElem);
|
||||
|
||||
this._knob = new Knob(knobElem,
|
||||
this.options.stepHeight,
|
||||
this.options.knobHeight)
|
||||
.on('dragend', this._updateZoom, this);
|
||||
this._knob.enable();
|
||||
},
|
||||
|
||||
_onSliderClick: function (e) {
|
||||
var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e);
|
||||
var y = L.DomEvent.getMousePosition(first).y
|
||||
- L.DomUtil.getViewportOffset(this._sliderBody).y; // Cache this?
|
||||
this._knob.setPosition(y);
|
||||
this._updateZoom();
|
||||
},
|
||||
|
||||
_zoomIn: function (e) {
|
||||
this._map.zoomIn(e.shiftKey ? 3 : 1);
|
||||
},
|
||||
_zoomOut: function (e) {
|
||||
this._map.zoomOut(e.shiftKey ? 3 : 1);
|
||||
},
|
||||
|
||||
_createZoomButton: function (zoomDir, end, container, fn) {
|
||||
var barPart = 'leaflet-bar-part',
|
||||
classDef = this.options.styleNS + '-' + zoomDir
|
||||
+ ' ' + barPart
|
||||
+ ' ' + barPart + '-' + end,
|
||||
title = 'Zoom ' + zoomDir,
|
||||
link = L.DomUtil.create('a', classDef, container);
|
||||
link.href = '#';
|
||||
link.title = title;
|
||||
|
||||
L.DomEvent
|
||||
.on(link, 'click', L.DomEvent.preventDefault)
|
||||
.on(link, 'click', fn, this);
|
||||
|
||||
return link;
|
||||
},
|
||||
_toZoomLevel: function (value) {
|
||||
return value + this._map.getMinZoom();
|
||||
},
|
||||
_toValue: function (zoomLevel) {
|
||||
return zoomLevel - this._map.getMinZoom();
|
||||
},
|
||||
_setSteps: function (zoomLevels) {
|
||||
this._sliderBody.style.height
|
||||
= (this.options.stepHeight * zoomLevels) + "px";
|
||||
this._knob.setSteps(zoomLevels);
|
||||
},
|
||||
_updateZoom: function () {
|
||||
this._map.setZoom(this._toZoomLevel(this._knob.getValue()));
|
||||
},
|
||||
_updateKnob: function () {
|
||||
if (this._knob) {
|
||||
this._knob.setValue(this._toValue(this._map.getZoom()));
|
||||
}
|
||||
},
|
||||
_updateDisabled: function () {
|
||||
var map = this._map,
|
||||
className = this.options.styleNS + '-disabled';
|
||||
|
||||
L.DomUtil.removeClass(this._zoomInButton, className);
|
||||
L.DomUtil.removeClass(this._zoomOutButton, className);
|
||||
|
||||
if (map.getZoom() === map.getMinZoom()) {
|
||||
L.DomUtil.addClass(this._zoomOutButton, className);
|
||||
}
|
||||
if (map.getZoom() === map.getMaxZoom()) {
|
||||
L.DomUtil.addClass(this._zoomInButton, className);
|
||||
}
|
||||
}
|
||||
});
|
||||
return Zoomslider;
|
||||
})();
|
||||
|
||||
L.Map.mergeOptions({
|
||||
zoomControl: false,
|
||||
zoomsliderControl: true
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.zoomsliderControl) {
|
||||
this.zoomsliderControl = new L.Control.Zoomslider();
|
||||
this.addControl(this.zoomsliderControl);
|
||||
}
|
||||
});
|
||||
|
||||
L.control.zoomslider = function (options) {
|
||||
return new L.Control.Zoomslider(options);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue