@h21-map/yandex-zoom-box
Version:
A library of Yandex Map JS API
194 lines (162 loc) • 6.54 kB
JavaScript
function ZoomBox() {
try {
ymaps;
} catch (e) {
throw Error('Ymaps Map JS API is not ready yet!');
}
this.opts = {
zoomType: 0,
strokeWeight: 1,
};
ZoomBox.prototype._bind = function () {
var me = this;
if (!me._isOpen) {
return;
}
};
ZoomBox.prototype.setMap = function (map) {
var me = this
me._map = map;
this._isOpen = true;
this._isOpen = true;
this._fDiv = null;
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.61;
me._fDiv.style.backgroundColor = "#e4e9f4";
me._fDiv.style.cursor = "crosshair";
me._fDiv.style.zIndex = 999;
me._fDiv.style.position = 'absolute';
me._fDiv.style.width = 0;
me._fDiv.style.height = 0;
me._fDiv.style.border = " 2px solid #0051FF";
map.container.getElement().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._map.events.add('mousemove', drawingRect);
me._map.events.add('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.container.getElement().clientWidth, me._map.container.getElement().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 () {
me._map.container.getElement().style.cursor = 'default';
me._map.events.remove('mousemove', drawingRect);
me._map.events.remove('mouseup', endDrawRect);
if (me._isOpen == true) {
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.container.getElement().clientWidth, me._map.container.getElement().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);
}
if (ratio < 450) {
let projection = me._map.options.get('projection');
let lat = projection.fromGlobalPixels(
me._map.converter.pageToGlobal([centerX, centerY]), me._map.getZoom());
let opt = {
center: lat,
zoom: targetZoomLv,
checkZoomRange: true,
duration: 500,
timingFunction: "ease-out"
}
me._map.action.execute(new ymaps.map.action.Single(opt));
}
me._bind.isZooming = false;
me._fDiv.parentNode.removeChild(me._fDiv);
me._fDiv = null;
}
};
if (!this._isBeginDrawBinded) {
me._map.events.add('mousedown', (e) => {
e = window.event || e;
if (e.button != 2) { return; }
me._map.container.getElement().style.cursor = 'crosshair';
this._isBeginDrawBinded = true;
document.oncontextmenu = function () { return false };
me._map.events.remove('mousemove', drawingRect);
beginDrawRect(e);
});
}
};
ZoomBox.prototype.destroy = function () {
me = this;
me._bind.isZooming = false;
me._fDiv.parentNode.removeChild(me._fDiv);
me._fDiv = null;
me._map.events.remove('mousemove', drawingRect);
me._map.events.remove('mouseup', endDrawRect);
me._map.events.remove('click');
};
};
if (typeof module == 'object') {
module.exports = { default: ZoomBox, ZoomBox: ZoomBox };
}