diff options
Diffstat (limited to 'chimere/static/openlayers/SimplePanZoom.js')
-rw-r--r-- | chimere/static/openlayers/SimplePanZoom.js | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/chimere/static/openlayers/SimplePanZoom.js b/chimere/static/openlayers/SimplePanZoom.js new file mode 100644 index 0000000..45619c3 --- /dev/null +++ b/chimere/static/openlayers/SimplePanZoom.js @@ -0,0 +1,366 @@ +/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for + * full list of contributors). Published under the 2-clause BSD license. + * See license.txt in the OpenLayers distribution or repository for the + * full text of the license. */ + + +/** + * @requires OpenLayers/Control/PanZoom.js + */ + +/** + * Class: OpenLayers.Control.PanZoomBar + * The PanZoomBar is a visible control composed of a + * <OpenLayers.Control.PanPanel> and a <OpenLayers.Control.ZoomBar>. + * By default it is displayed in the upper left corner of the map as 4 + * directional arrows above a vertical slider. + * + * Inherits from: + * - <OpenLayers.Control.PanZoom> + */ +OpenLayers.Control.SimplePanZoom = OpenLayers.Class(OpenLayers.Control.PanZoom, { + + /** + * APIProperty: zoomStopWidth + */ + zoomStopWidth: 18, + + /** + * APIProperty: zoomStopHeight + */ + zoomStopHeight: 7, + + /** + * Property: slider + */ + slider: null, + + /** + * Property: sliderEvents + * {<OpenLayers.Events>} + */ + sliderEvents: null, + + /** + * Property: zoombarDiv + * {DOMElement} + */ + zoombarDiv: null, + + /** + * APIProperty: zoomWorldIcon + * {Boolean} + */ + zoomWorldIcon: false, + + /** + * APIProperty: panIcons + * {Boolean} Set this property to false not to display the pan icons. If + * false the zoom world icon is placed under the zoom bar. Defaults to + * true. + */ + panIcons: true, + + /** + * APIProperty: forceFixedZoomLevel + * {Boolean} Force a fixed zoom level even though the map has + * fractionalZoom + */ + forceFixedZoomLevel: false, + + /** + * Property: mouseDragStart + * {<OpenLayers.Pixel>} + */ + mouseDragStart: null, + + /** + * Property: deltaY + * {Number} The cumulative vertical pixel offset during a zoom bar drag. + */ + deltaY: null, + + /** + * Property: zoomStart + * {<OpenLayers.Pixel>} + */ + zoomStart: null, + + /** + * Constructor: OpenLayers.Control.PanZoomBar + */ + buttons: null, + + /** + * Top position of the slider: change if the Y position of the slider have change + */ + startTop: 75, + + /** + * APIMethod: destroy + */ + destroy: function() { + + this._removeZoomBar(); + + this.map.events.un({ + "changebaselayer": this.redraw, + "updatesize": this.redraw, + scope: this + }); + + OpenLayers.Control.PanZoom.prototype.destroy.apply(this, arguments); + + delete this.mouseDragStart; + delete this.zoomStart; + }, + + /** + * Method: setMap + * + * Parameters: + * map - {<OpenLayers.Map>} + */ + setMap: function(map) { + OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments); + this.map.events.on({ + "changebaselayer": this.redraw, + "updatesize": this.redraw, + scope: this + }); + }, + + /** + * Method: redraw + * clear the div and start over. + */ + redraw: function() { + if (this.div !== null) { + this.removeButtons(); + this._removeZoomBar(); + } + this.draw(); + }, + + /** + * Method: draw + * + * Parameters: + * px - {<OpenLayers.Pixel>} + */ + draw: function(px) { + // initialize our internal div + OpenLayers.Control.prototype.draw.apply(this, arguments); + px = this.position.clone(); + + // place the controls + this.buttons = []; + var ids = ['panup', 'panleft', 'panright', 'pandown', 'zoomout', 'zoomin']; + + for (var i = 0; i < ids.length; i++) { + var b = document.createElement('div'); + b.id = ids[i]; + b.action = ids[i]; + b.className = 'button olButton'; + this.div.appendChild(b); + this.buttons.push(b); + } + + this._addZoomBar(); + return this.div; + }, + + /** + * Method: _addZoomBar + * + * Parameters: + * centered - {<OpenLayers.Pixel>} where zoombar drawing is to start. + */ + _addZoomBar:function() { + var id = this.id + "_" + this.map.id; + var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom(); + var slider = document.createElement('div'); + slider.id = 'slider'; + slider.className = 'button'; + slider.style.cursor = 'move'; + this.slider = slider; + + this.sliderEvents = new OpenLayers.Events(this, slider, null, true, + { includeXY: true }); + this.sliderEvents.on({ + "touchstart": this.zoomBarDown, + "touchmove": this.zoomBarDrag, + "touchend": this.zoomBarUp, + "mousedown": this.zoomBarDown, + "mousemove": this.zoomBarDrag, + "mouseup": this.zoomBarUp + }); + + var height = this.zoomStopHeight * (this.map.getNumZoomLevels()); + + // this is the background image + var div = document.createElement('div'); + div.className = 'button'; + div.id = 'zoombar'; + this.zoombarDiv = div; + + this.div.appendChild(div); + this.div.appendChild(slider); + + this.map.events.register("zoomend", this, this.moveZoomBar); + }, + + /** + * Method: _removeZoomBar + */ + _removeZoomBar: function() { + this.sliderEvents.un({ + "touchstart": this.zoomBarDown, + "touchmove": this.zoomBarDrag, + "touchend": this.zoomBarUp, + "mousedown": this.zoomBarDown, + "mousemove": this.zoomBarDrag, + "mouseup": this.zoomBarUp + }); + this.sliderEvents.destroy(); + + this.div.removeChild(this.zoombarDiv); + this.zoombarDiv = null; + this.div.removeChild(this.slider); + this.slider = null; + + this.map.events.unregister("zoomend", this, this.moveZoomBar); + }, + + /** + * Method: onButtonClick + * + * Parameters: + * evt - {Event} + */ + onButtonClick: function(evt) { + OpenLayers.Control.PanZoom.prototype.onButtonClick.apply(this, arguments); + if (evt.buttonElement === this.zoombarDiv) { + var levels = evt.buttonXY.y / this.zoomStopHeight; + if (this.forceFixedZoomLevel || !this.map.fractionalZoom) { + levels = Math.floor(levels); + } + var zoom = (this.map.getNumZoomLevels() - 1) - levels; + zoom = Math.min(Math.max(zoom, 0), this.map.getNumZoomLevels() - 1); + this.map.zoomTo(zoom); + } + }, + + /** + * Method: passEventToSlider + * This function is used to pass events that happen on the div, or the map, + * through to the slider, which then does its moving thing. + * + * Parameters: + * evt - {<OpenLayers.Event>} + */ + passEventToSlider:function(evt) { + this.sliderEvents.handleBrowserEvent(evt); + }, + + /* + * Method: zoomBarDown + * event listener for clicks on the slider + * + * Parameters: + * evt - {<OpenLayers.Event>} + */ + zoomBarDown:function(evt) { + if (!OpenLayers.Event.isLeftClick(evt) && !OpenLayers.Event.isSingleTouch(evt)) { + return; + } + this.map.events.on({ + "touchmove": this.passEventToSlider, + "mousemove": this.passEventToSlider, + "mouseup": this.passEventToSlider, + scope: this + }); + this.mouseDragStart = evt.xy.clone(); + this.zoomStart = evt.xy.clone(); + this.div.style.cursor = "move"; + // reset the div offsets just in case the div moved + this.zoombarDiv.offsets = null; + OpenLayers.Event.stop(evt); + }, + + /* + * Method: zoomBarDrag + * This is what happens when a click has occurred, and the client is + * dragging. Here we must ensure that the slider doesn't go beyond the + * bottom/top of the zoombar div, as well as moving the slider to its new + * visual location + * + * Parameters: + * evt - {<OpenLayers.Event>} + */ + zoomBarDrag: function(evt) { + if (this.mouseDragStart !== null) { + var deltaY = this.mouseDragStart.y - evt.xy.y; + var offsets = OpenLayers.Util.pagePosition(this.zoombarDiv); + if ((evt.clientY - offsets[1]) > 0 && + (evt.clientY - offsets[1]) < 140) { + var newTop = parseInt(this.slider.style.top, 10) - deltaY; + this.slider.style.top = newTop + "px"; + this.mouseDragStart = evt.xy.clone(); + } + // set cumulative displacement + this.deltaY = this.zoomStart.y - evt.xy.y; + OpenLayers.Event.stop(evt); + } + }, + + /* + * Method: zoomBarUp + * Perform cleanup when a mouseup event is received -- discover new zoom + * level and switch to it. + * + * Parameters: + * evt - {<OpenLayers.Event>} + */ + zoomBarUp: function(evt) { + if (!OpenLayers.Event.isLeftClick(evt) && evt.type !== "touchend") { + return; + } + if (this.mouseDragStart) { + this.div.style.cursor=""; + this.map.events.un({ + "touchmove": this.passEventToSlider, + "mouseup": this.passEventToSlider, + "mousemove": this.passEventToSlider, + scope: this + }); + var zoomLevel = this.map.zoom; + if (!this.forceFixedZoomLevel && this.map.fractionalZoom) { + zoomLevel += this.deltaY/this.zoomStopHeight; + zoomLevel = Math.min(Math.max(zoomLevel, 0), + this.map.getNumZoomLevels() - 1); + } else { + zoomLevel += this.deltaY/this.zoomStopHeight; + zoomLevel = Math.max(Math.round(zoomLevel), 0); + } + this.map.zoomTo(zoomLevel); + this.mouseDragStart = null; + this.zoomStart = null; + this.deltaY = 0; + OpenLayers.Event.stop(evt); + } + }, + + /* + * Method: moveZoomBar + * Change the location of the slider to match the current zoom level. + */ + moveZoomBar:function() { + var newTop = + ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) * + this.zoomStopHeight + this.startTop; + this.slider.style.top = newTop + "px"; + }, + + CLASS_NAME: "OpenLayers.Control.SimplePanZoom" +}); |