1 L.Control.Zoomslider = (function () {
3 var Knob = L.Draggable.extend({
4 initialize: function (element, stepHeight, knobHeight) {
5 L.Draggable.prototype.initialize.call(this, element, element);
6 this._element = element;
8 this._stepHeight = stepHeight;
9 this._knobHeight = knobHeight;
11 this.on('predrag', function () {
13 this._newPos.y = this._adjust(this._newPos.y);
17 _adjust: function (y) {
18 var value = Math.round(this._toValue(y));
19 value = Math.max(0, Math.min(this._maxValue, value));
20 return this._toY(value);
24 _toY: function (value) {
25 return this._k * value + this._m;
28 _toValue: function (y) {
29 return (y - this._m) / this._k;
32 setSteps: function (steps) {
33 var sliderHeight = steps * this._stepHeight;
34 this._maxValue = steps - 1;
36 // conversion parameters
37 // the conversion is just a common linear function.
38 this._k = -this._stepHeight;
39 this._m = sliderHeight - (this._stepHeight + this._knobHeight) / 2;
42 setPosition: function (y) {
43 L.DomUtil.setPosition(this._element,
44 L.point(0, this._adjust(y)));
47 setValue: function (v) {
48 this.setPosition(this._toY(v));
51 getValue: function () {
52 return this._toValue(L.DomUtil.getPosition(this._element).y);
56 var Zoomslider = L.Control.extend({
59 // Height of zoom-slider.png in px
61 // Height of the knob div in px
63 styleNS: 'leaflet-control-zoomslider'
66 onAdd: function (map) {
67 var container = L.DomUtil.create('div', this.options.styleNS + ' leaflet-bar');
69 L.DomEvent.disableClickPropagation(container);
73 this._zoomInButton = this._createZoomButton(
74 'in', 'top', container, this._zoomIn);
76 this._sliderElem = L.DomUtil.create(
78 this.options.styleNS + "-slider leaflet-bar-part",
81 this._zoomOutButton = this._createZoomButton(
82 'out', 'bottom', container, this._zoomOut);
84 map .on('zoomlevelschange', this._refresh, this)
85 .on("zoomend", this._updateKnob, this)
86 .on("zoomend", this._updateDisabled, this)
87 .whenReady(this._createSlider, this)
88 .whenReady(this._createKnob, this)
89 .whenReady(this._refresh, this);
94 onRemove: function (map) {
95 map .off("zoomend", this._updateKnob)
96 .off("zoomend", this._updateDisabled)
97 .off('zoomlevelschange', this._refresh);
100 _refresh: function () {
101 var zoomLevels = this._zoomLevels();
102 if (zoomLevels < Infinity && this._knob && this._sliderBody) {
103 this._setSteps(zoomLevels);
105 this._updateDisabled();
108 _zoomLevels: function () {
109 return this._map.getMaxZoom() - this._map.getMinZoom() + 1;
112 _createSlider: function () {
113 this._sliderBody = L.DomUtil.create('div',
114 this.options.styleNS + '-slider-body',
116 L.DomEvent.on(this._sliderBody, 'click', this._onSliderClick, this);
119 _createKnob: function () {
120 var knobElem = L.DomUtil.create('div', this.options.styleNS + '-slider-knob',
122 L.DomEvent.disableClickPropagation(knobElem);
124 this._knob = new Knob(knobElem,
125 this.options.stepHeight,
126 this.options.knobHeight)
127 .on('dragend', this._updateZoom, this);
131 _onSliderClick: function (e) {
132 var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e);
133 var y = L.DomEvent.getMousePosition(first).y
134 - L.DomUtil.getViewportOffset(this._sliderBody).y; // Cache this?
135 this._knob.setPosition(y);
139 _zoomIn: function (e) {
140 this._map.zoomIn(e.shiftKey ? 3 : 1);
142 _zoomOut: function (e) {
143 this._map.zoomOut(e.shiftKey ? 3 : 1);
146 _createZoomButton: function (zoomDir, end, container, fn) {
147 var barPart = 'leaflet-bar-part',
148 classDef = this.options.styleNS + '-' + zoomDir
150 + ' ' + barPart + '-' + end,
151 title = 'Zoom ' + zoomDir,
152 link = L.DomUtil.create('a', classDef, container);
157 .on(link, 'click', L.DomEvent.preventDefault)
158 .on(link, 'click', fn, this);
162 _toZoomLevel: function (value) {
163 return value + this._map.getMinZoom();
165 _toValue: function (zoomLevel) {
166 return zoomLevel - this._map.getMinZoom();
168 _setSteps: function (zoomLevels) {
169 this._sliderBody.style.height
170 = (this.options.stepHeight * zoomLevels) + "px";
171 this._knob.setSteps(zoomLevels);
173 _updateZoom: function () {
174 this._map.setZoom(this._toZoomLevel(this._knob.getValue()));
176 _updateKnob: function () {
178 this._knob.setValue(this._toValue(this._map.getZoom()));
181 _updateDisabled: function () {
183 className = this.options.styleNS + '-disabled';
185 L.DomUtil.removeClass(this._zoomInButton, className);
186 L.DomUtil.removeClass(this._zoomOutButton, className);
188 if (map.getZoom() === map.getMinZoom()) {
189 L.DomUtil.addClass(this._zoomOutButton, className);
191 if (map.getZoom() === map.getMaxZoom()) {
192 L.DomUtil.addClass(this._zoomInButton, className);
201 zoomsliderControl: true
204 L.Map.addInitHook(function () {
205 if (this.options.zoomsliderControl) {
206 this.zoomsliderControl = new L.Control.Zoomslider();
207 this.addControl(this.zoomsliderControl);
211 L.control.zoomslider = function (options) {
212 return new L.Control.Zoomslider(options);