1 /* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
2 * full list of contributors). Published under the 2-clause BSD license.
3 * See license.txt in the OpenLayers distribution or repository for the
4 * full text of the license. */
8 * @requires OpenLayers/Control/PanZoom.js
12 * Class: OpenLayers.Control.PanZoomBar
13 * The PanZoomBar is a visible control composed of a
14 * <OpenLayers.Control.PanPanel> and a <OpenLayers.Control.ZoomBar>.
15 * By default it is displayed in the upper left corner of the map as 4
16 * directional arrows above a vertical slider.
19 * - <OpenLayers.Control.PanZoom>
21 OpenLayers.Control.SimplePanZoom = OpenLayers.Class(OpenLayers.Control.PanZoom, {
24 * APIProperty: zoomStopWidth
29 * APIProperty: zoomStopHeight
39 * Property: sliderEvents
40 * {<OpenLayers.Events>}
45 * Property: zoombarDiv
51 * APIProperty: zoomWorldIcon
57 * APIProperty: panIcons
58 * {Boolean} Set this property to false not to display the pan icons. If
59 * false the zoom world icon is placed under the zoom bar. Defaults to
65 * APIProperty: forceFixedZoomLevel
66 * {Boolean} Force a fixed zoom level even though the map has
69 forceFixedZoomLevel: false,
72 * Property: mouseDragStart
73 * {<OpenLayers.Pixel>}
79 * {Number} The cumulative vertical pixel offset during a zoom bar drag.
85 * {<OpenLayers.Pixel>}
90 * Constructor: OpenLayers.Control.PanZoomBar
99 this._removeZoomBar();
102 "changebaselayer": this.redraw,
103 "updatesize": this.redraw,
107 OpenLayers.Control.PanZoom.prototype.destroy.apply(this, arguments);
109 delete this.mouseDragStart;
110 delete this.zoomStart;
117 * map - {<OpenLayers.Map>}
119 setMap: function(map) {
120 OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments);
122 "changebaselayer": this.redraw,
123 "updatesize": this.redraw,
130 * clear the div and start over.
133 if (this.div !== null) {
134 this.removeButtons();
135 this._removeZoomBar();
144 * px - {<OpenLayers.Pixel>}
147 // initialize our internal div
148 OpenLayers.Control.prototype.draw.apply(this, arguments);
149 px = this.position.clone();
151 // place the controls
153 var ids = ['panup', 'panleft', 'panright', 'pandown', 'zoomout', 'zoomin'];
155 for (var i = 0; i < ids.length; i++) {
156 var b = document.createElement('div');
159 b.className = 'button olButton';
160 this.div.appendChild(b);
161 this.buttons.push(b);
169 * Method: _addZoomBar
172 * centered - {<OpenLayers.Pixel>} where zoombar drawing is to start.
174 _addZoomBar:function() {
175 var id = this.id + "_" + this.map.id;
176 var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom();
177 var slider = document.createElement('div');
178 slider.id = 'slider';
179 slider.className = 'button';
180 slider.style.cursor = 'move';
181 this.slider = slider;
183 this.sliderEvents = new OpenLayers.Events(this, slider, null, true,
184 { includeXY: true });
185 this.sliderEvents.on({
186 "touchstart": this.zoomBarDown,
187 "touchmove": this.zoomBarDrag,
188 "touchend": this.zoomBarUp,
189 "mousedown": this.zoomBarDown,
190 "mousemove": this.zoomBarDrag,
191 "mouseup": this.zoomBarUp
194 var height = this.zoomStopHeight * (this.map.getNumZoomLevels());
196 // this is the background image
197 var div = document.createElement('div');
198 div.className = 'button olButton';
200 this.zoombarDiv = div;
202 this.div.appendChild(div);
204 this.div.appendChild(slider);
206 this.map.events.register("zoomend", this, this.moveZoomBar);
210 * Method: _removeZoomBar
212 _removeZoomBar: function() {
213 this.sliderEvents.un({
214 "touchstart": this.zoomBarDown,
215 "touchmove": this.zoomBarDrag,
216 "touchend": this.zoomBarUp,
217 "mousedown": this.zoomBarDown,
218 "mousemove": this.zoomBarDrag,
219 "mouseup": this.zoomBarUp
221 this.sliderEvents.destroy();
223 this.div.removeChild(this.zoombarDiv);
224 this.zoombarDiv = null;
225 this.div.removeChild(this.slider);
228 this.map.events.unregister("zoomend", this, this.moveZoomBar);
232 * Method: onButtonClick
237 onButtonClick: function(evt) {
238 OpenLayers.Control.PanZoom.prototype.onButtonClick.apply(this, arguments);
239 if (evt.buttonElement === this.zoombarDiv) {
240 var levels = evt.buttonXY.y / this.zoomStopHeight;
241 if (this.forceFixedZoomLevel || !this.map.fractionalZoom) {
242 levels = Math.floor(levels);
244 var zoom = (this.map.getNumZoomLevels() - 1) - levels;
245 zoom = Math.min(Math.max(zoom, 0), this.map.getNumZoomLevels() - 1);
246 this.map.zoomTo(zoom);
251 * Method: passEventToSlider
252 * This function is used to pass events that happen on the div, or the map,
253 * through to the slider, which then does its moving thing.
256 * evt - {<OpenLayers.Event>}
258 passEventToSlider:function(evt) {
259 this.sliderEvents.handleBrowserEvent(evt);
263 * Method: zoomBarDown
264 * event listener for clicks on the slider
267 * evt - {<OpenLayers.Event>}
269 zoomBarDown:function(evt) {
270 if (!OpenLayers.Event.isLeftClick(evt) && !OpenLayers.Event.isSingleTouch(evt)) {
274 "touchmove": this.passEventToSlider,
275 "mousemove": this.passEventToSlider,
276 "mouseup": this.passEventToSlider,
279 this.mouseDragStart = evt.xy.clone();
280 this.zoomStart = evt.xy.clone();
281 this.div.style.cursor = "move";
282 // reset the div offsets just in case the div moved
283 this.zoombarDiv.offsets = null;
284 OpenLayers.Event.stop(evt);
288 * Method: zoomBarDrag
289 * This is what happens when a click has occurred, and the client is
290 * dragging. Here we must ensure that the slider doesn't go beyond the
291 * bottom/top of the zoombar div, as well as moving the slider to its new
295 * evt - {<OpenLayers.Event>}
297 zoomBarDrag: function(evt) {
298 if (this.mouseDragStart !== null) {
299 var deltaY = this.mouseDragStart.y - evt.xy.y;
300 var offsets = OpenLayers.Util.pagePosition(this.zoombarDiv);
301 if ((evt.clientY - offsets[1]) > 0 &&
302 (evt.clientY - offsets[1]) < 140) {
303 var newTop = parseInt(this.slider.style.top, 10) - deltaY;
304 this.slider.style.top = newTop + "px";
305 this.mouseDragStart = evt.xy.clone();
307 // set cumulative displacement
308 this.deltaY = this.zoomStart.y - evt.xy.y;
309 OpenLayers.Event.stop(evt);
315 * Perform cleanup when a mouseup event is received -- discover new zoom
316 * level and switch to it.
319 * evt - {<OpenLayers.Event>}
321 zoomBarUp: function(evt) {
322 if (!OpenLayers.Event.isLeftClick(evt) && evt.type !== "touchend") {
325 if (this.mouseDragStart) {
326 this.div.style.cursor = "";
328 "touchmove": this.passEventToSlider,
329 "mouseup": this.passEventToSlider,
330 "mousemove": this.passEventToSlider,
333 var zoomLevel = this.map.zoom;
334 zoomLevel += this.deltaY/this.zoomStopHeight;
335 zoomLevel = Math.max(Math.round(zoomLevel), 0);
336 this.map.zoomTo(zoomLevel);
337 this.mouseDragStart = null;
338 this.zoomStart = null;
340 OpenLayers.Event.stop(evt);
345 * Method: moveZoomBar
346 * Change the location of the slider to match the current zoom level.
348 moveZoomBar:function() {
350 ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) *
351 this.zoomStopHeight + this.startTop;
352 this.slider.style.top = newTop + "px";
354 CLASS_NAME: "OpenLayers.Control.SimplePanZoom"