UNPKG

@h21-map/google-zoom-box

Version:
246 lines (203 loc) 8.91 kB
var ZoomBox = function () { try { google; } catch (e) { throw Error('Google Map JS API is not ready yet!'); } this.extend(ZoomBox, google.maps.OverlayView); this.opts = { zoomType: 0, strokeWeight: 1, }; this._isOpen = true; this._fDiv = null; this._div = null; } ZoomBox.prototype.extend = function (obj1, obj2) { return (function (object) { var property; for (property in object.prototype) { this.prototype[property] = object.prototype[property]; } return this; }).apply(obj1, [obj2]); }; ZoomBox.prototype._bind = function () { var me = this; if (!me._isOpen) { return; } }; ZoomBox.prototype.onAdd = function () { var me = this; me._map = this.getMap(); me.mousem = null; me.mouseup = null; this._isOpen = true; if (!this._div) { let div = this.container = document.createElement('div'); div.style.borderStyle = 'none'; div.style.borderWidth = '0px'; div.style.position = 'absolute'; let size = {} size.width = me._map.getDiv().offsetWidth; size.height = me._map.getDiv().offsetHeight; div.style.cssText = "z-index: 1; position:absolute; width:" + size.width + "px;height:" + size.height + "px"; this.getPanes().overlayMouseTarget.appendChild(div); this._div = div; } let beginDrawRect = function (e) { e = window.event || e; if (e.button != 2) { return; } if (!me._isOpen) { return; } me._bind.isZooming = true; this._isBeginDrawBinded = true; me._bind.mx = e.layerX || e.offsetX || 0; me._bind.my = e.layerY || e.offsetY || 0; me._bind.ix = e.pageX || e.clientX || 0; me._bind.iy = e.pageY || e.clientY || 0; if (!me._fDiv) { me._fDiv = document.createElement("div"); me._fDiv.style.opacity = 0.69; me._fDiv.style.backgroundColor = "#a5b8e35e"; me._fDiv.style.cursor = "crosshair"; me._fDiv.style.zIndex = 999999; me._fDiv.style.position = 'absolute'; me._fDiv.style.width = 0; me._fDiv.style.height = 0; me._fDiv.style.border = " 2px solid #0051FF"; me._map.getDiv().appendChild(me._fDiv); me._fDiv.style.width = "0"; me._fDiv.style.height = "0"; me._fDiv.style.left = me._bind.mx + "px"; me._fDiv.style.top = me._bind.my + "px"; me.mousem = google.maps.event.addDomListener(me._map.getDiv(), "mousemove", drawingRect); me.mouseup = google.maps.event.addDomListener(me._map.getDiv(), "mouseup", endDrawRect); } }; let drawingRect = function (e) { if (me._isOpen == true && me._bind.isZooming == true) { var e = window.event || e; var curX = e.pageX || e.clientX || 0; var curY = e.pageY || e.clientY || 0; var dx = me._bind.dx = curX - me._bind.ix; var dy = me._bind.dy = curY - me._bind.iy; var tw = Math.abs(dx) - me.opts.strokeWeight; var th = Math.abs(dy) - me.opts.strokeWeight; me._fDiv.style.width = (tw < 0 ? 0 : tw) + "px"; me._fDiv.style.height = (th < 0 ? 0 : th) + "px"; var mapSize = [me._map.getDiv().clientWidth, me._map.getDiv().clientHeight]; if (dx >= 0) { me._fDiv.style.right = "auto"; me._fDiv.style.left = me._bind.mx + "px"; if (me._bind.mx + dx >= mapSize[0] - 2 * me.opts.strokeWeight) { me._fDiv.style.width = mapSize[0] - me._bind.mx - 2 * me.opts.strokeWeight + "px"; } } else { me._fDiv.style.left = "auto"; me._fDiv.style.right = mapSize[0] - me._bind.mx + "px"; if (me._bind.mx + dx <= 2 * me.opts.strokeWeight) { me._fDiv.style.width = me._bind.mx - 2 * me.opts.strokeWeight + "px"; } } if (dy >= 0) { me._fDiv.style.bottom = "auto"; me._fDiv.style.top = me._bind.my + "px"; if (me._bind.my + dy >= mapSize[1] - 2 * me.opts.strokeWeight) { me._fDiv.style.height = mapSize[1] - me._bind.my - 2 * me.opts.strokeWeight + "px"; } } else { me._fDiv.style.top = "auto"; me._fDiv.style.bottom = mapSize[1] - me._bind.my + "px"; if (me._bind.my + dy <= 2 * me.opts.strokeWeight) { me._fDiv.style.height = me._bind.my - 2 * me.opts.strokeWeight + "px"; } } } }; let endDrawRect = function () { if (me._isOpen == true) { google.maps.event.removeListener(me.mousem); google.maps.event.removeListener(me.mouseup); var centerX = parseInt(me._fDiv.style.left) + parseInt(me._fDiv.style.width) / 2; var centerY = parseInt(me._fDiv.style.top) + parseInt(me._fDiv.style.height) / 2; var mapSize = [me._map.getDiv().clientWidth, me._map.getDiv().clientHeight]; if (isNaN(centerX)) { centerX = mapSize[0] - parseInt(me._fDiv.style.right) - parseInt(me._fDiv.style.width) / 2; } if (isNaN(centerY)) { centerY = mapSize[1] - parseInt(me._fDiv.style.bottom) - parseInt(me._fDiv.style.height) / 2; } var ratio = Math.min(mapSize[0] / Math.abs(me._bind.dx), mapSize[1] / Math.abs(me._bind.dy)); ratio = Math.floor(ratio); delete me._bind.dx; delete me._bind.dy; delete me._bind.ix; delete me._bind.iy; if (!isNaN(ratio)) { targetZoomLv = Math.round(me._map.getZoom() + (Math.log(ratio) / Math.log(2))); if (targetZoomLv < me._map.getZoom()) { targetZoomLv = me._map.getZoom(); } } else { targetZoomLv = me._map.getZoom() + (me.opts.zoomType == 0 ? 1 : -1); } var ne = me._map.getBounds().getNorthEast(); var sw = me._map.getBounds().getSouthWest(); var projection = me._map.getProjection(); var topRight = projection.fromLatLngToPoint(ne); var bottomLeft = projection.fromLatLngToPoint(sw); var scale = 1 << me._map.getZoom(); var newLatlng = projection.fromPointToLatLng(new google.maps.Point(centerX / scale + bottomLeft.x, centerY / scale + topRight.y)); if(ratio < 450){ me._map.setCenter(newLatlng); me._map.setZoom(targetZoomLv); } me._bind.isZooming = false; me._map.setOptions({ draggable: true, draggableCursor: 'default', }); me._fDiv.parentNode.removeChild(me._fDiv); me._fDiv = null; } rect = null; }; if (!this._isBeginDrawBinded) { google.maps.event.addDomListener(me._div, "mousedown", (e) => { if (e.which === 3) { this._isBeginDrawBinded = true; document.oncontextmenu = function () { return false }; google.maps.event.clearListeners(me._map.getDiv(), 'mousemove'); me._map.setOptions({ draggable: false, draggableCursor: 'crosshair' }); beginDrawRect(e); } }); } }; ZoomBox.prototype.draw = function () { const bounds = this.getMap().getBounds(); const projection = this.getProjection(); const topRight = projection.fromLatLngToDivPixel(bounds.getNorthEast()); const bottomLeft = projection.fromLatLngToDivPixel(bounds.getSouthWest()); this.container.width = Math.round(topRight.x - bottomLeft.x) + "px"; this.container.style.height = Math.round(bottomLeft.y - topRight.y) + "px"; this.container.style.left = bottomLeft.x + "px"; this.container.style.top = topRight.y + "px"; }; ZoomBox.prototype.onRemove = function () { me = this; if (!this._isOpen) { return; } me._div.parentNode.removeChild(me._div); me._div = null; google.maps.event.clearListeners(me._map.getDiv(), 'mousemove'); google.maps.event.clearListeners(me._map.getDiv(), 'mousedown'); }; if (typeof module == 'object') { module.exports = { default: ZoomBox, ZoomBox: ZoomBox }; };