@h21-map/baidu-zoom-box
Version:
A library of Baidu Map JS API
665 lines (582 loc) • 24.3 kB
JavaScript
/**
* @fileoverview 百度地图的鼠标绘制工具,对外开放。
* 允许用户在地图上点击完成鼠标绘制的功能。
* 使用者可以自定义所绘制结果的相关样式,例如线宽、颜色、测线段距离、面积等等。
* 主入口类是<a href="symbols/Geodesic"></a>,
* 基于Baidu Map API 1.0。
*
* @author Baidu Map Api Group
* @version 1.0
*/
window['BMapLib'] = window['BMapLib'] || {};
(function (root, factory) {
if (typeof exports === 'object') {
module.exports = { default: factory(), ZoomBox: factory() };
} else if (typeof define === 'function' && define.amd) {
define(factory);
} else {
root.BMapLib = root.BMapLib || {};
root.BMapLib.ZoomBox = root.BMapLib.ZoomBox || factory();
}
})(this, function () {
var T, baidu = T = baidu || { version: '1.5.0' };
baidu.guid = '$BAIDU$';
window[baidu.guid] = window[baidu.guid] || {};
baidu.lang = baidu.lang || {};
baidu.lang.isString = function (source) {
return '[object String]' == Object.prototype.toString.call(source);
};
baidu.lang.isFunction = function (source) {
return '[object Function]' == Object.prototype.toString.call(source);
};
baidu.lang.Event = function (type, target) {
this.type = type;
this.returnValue = true;
this.target = target || null;
this.currentTarget = null;
};
baidu.object = baidu.object || {};
baidu.extend =
baidu.object.extend = function (target, source) {
for (var p in source) {
if (source.hasOwnProperty(p)) {
target[p] = source[p];
}
}
return target;
};
baidu.event = baidu.event || {};
baidu.event._listeners = baidu.event._listeners || [];
baidu.dom = baidu.dom || {};
baidu.dom._g = function (id) {
if (baidu.lang.isString(id)) {
return document.getElementById(id);
}
return id;
};
baidu._g = baidu.dom._g;
baidu.event.on = function (element, type, listener) {
type = type.replace(/^on/i, '');
element = baidu.dom._g(element);
var realListener = function (ev) {
listener.call(element, ev);
},
lis = baidu.event._listeners,
filter = baidu.event._eventFilter,
afterFilter,
realType = type;
type = type.toLowerCase();
if (filter && filter[type]) {
afterFilter = filter[type](element, type, realListener);
realType = afterFilter.type;
realListener = afterFilter.listener;
}
if (element.addEventListener) {
element.addEventListener(realType, realListener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + realType, realListener);
}
lis[lis.length] = [element, type, listener, realListener, realType];
return element;
};
baidu.on = baidu.event.on;
baidu.event.un = function (element, type, listener) {
element = baidu.dom._g(element);
type = type.replace(/^on/i, '').toLowerCase();
var lis = baidu.event._listeners,
len = lis.length,
isRemoveAll = !listener,
item,
realType, realListener;
while (len--) {
item = lis[len];
if (item[1] === type
&& item[0] === element
&& (isRemoveAll || item[2] === listener)) {
realType = item[4];
realListener = item[3];
if (element.removeEventListener) {
element.removeEventListener(realType, realListener, false);
} else if (element.detachEvent) {
element.detachEvent('on' + realType, realListener);
}
lis.splice(len, 1);
}
}
return element;
};
baidu.un = baidu.event.un;
baidu.dom.g = function (id) {
if ('string' == typeof id || id instanceof String) {
return document.getElementById(id);
} else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
return id;
}
return null;
};
baidu.g = baidu.G = baidu.dom.g;
baidu.dom._styleFixer = baidu.dom._styleFixer || {};
baidu.dom._styleFilter = baidu.dom._styleFilter || [];
baidu.dom._styleFilter.filter = function (key, value, method) {
for (var i = 0, filters = baidu.dom._styleFilter, filter; filter = filters[i]; i++) {
if (filter = filter[method]) {
value = filter(key, value);
}
}
return value;
};
baidu.string = baidu.string || {};
baidu.string.toCamelCase = function (source) {
if (source.indexOf('-') < 0 && source.indexOf('_') < 0) {
return source;
}
return source.replace(/[-_][^-_]/g, function (match) {
return match.charAt(1).toUpperCase();
});
};
baidu.dom.setStyle = function (element, key, value) {
var dom = baidu.dom, fixer;
element = dom.g(element);
key = baidu.string.toCamelCase(key);
if (fixer = dom._styleFilter) {
value = fixer.filter(key, value, 'set');
}
fixer = dom._styleFixer[key];
(fixer && fixer.set) ? fixer.set(element, value) : (element.style[fixer || key] = value);
return element;
};
baidu.setStyle = baidu.dom.setStyle;
baidu.dom.setStyles = function (element, styles) {
element = baidu.dom.g(element);
for (var key in styles) {
baidu.dom.setStyle(element, key, styles[key]);
}
return element;
};
baidu.setStyles = baidu.dom.setStyles;
baidu.browser = baidu.browser || {};
baidu.browser.ie = baidu.ie = /msie (\d+\.\d+)/i.test(navigator.userAgent) ? (document.documentMode || + RegExp['\x241']) : undefined;
baidu.dom._NAME_ATTRS = (function () {
var result = {
'cellpadding': 'cellPadding',
'cellspacing': 'cellSpacing',
'colspan': 'colSpan',
'rowspan': 'rowSpan',
'valign': 'vAlign',
'usemap': 'useMap',
'frameborder': 'frameBorder'
};
if (baidu.browser.ie < 8) {
result['for'] = 'htmlFor';
result['class'] = 'className';
} else {
result['htmlFor'] = 'for';
result['className'] = 'class';
}
return result;
})();
baidu.dom.setAttr = function (element, key, value) {
element = baidu.dom.g(element);
if ('style' == key) {
element.style.cssText = value;
} else {
key = baidu.dom._NAME_ATTRS[key] || key;
element.setAttribute(key, value);
}
return element;
};
baidu.setAttr = baidu.dom.setAttr;
baidu.dom.setAttrs = function (element, attributes) {
element = baidu.dom.g(element);
for (var key in attributes) {
baidu.dom.setAttr(element, key, attributes[key]);
}
return element;
};
baidu.setAttrs = baidu.dom.setAttrs;
baidu.dom.create = function (tagName, opt_attributes) {
var el = document.createElement(tagName),
attributes = opt_attributes || {};
return baidu.dom.setAttrs(el, attributes);
};
T.undope = true;
function extend(subClass, superClass, className) {
var key, proto,
selfProps = subClass.prototype,
clazz = new Function();
clazz.prototype = superClass.prototype;
proto = subClass.prototype = new clazz();
for (key in selfProps) {
proto[key] = selfProps[key];
}
subClass.prototype.constructor = subClass;
subClass.superClass = superClass.prototype;
if ("string" == typeof className) {
proto._className = className;
}
};
var T, baidu = T = baidu || { version: '1.5.0' };
baidu.guid = '$BAIDU$';
window[baidu.guid] = window[baidu.guid] || {};
baidu.lang = baidu.lang || {};
baidu.lang.isString = function (source) {
return '[object String]' == Object.prototype.toString.call(source);
};
baidu.lang.isFunction = function (source) {
return '[object Function]' == Object.prototype.toString.call(source);
};
baidu.lang.Event = function (type, target) {
this.type = type;
this.returnValue = true;
this.target = target || null;
this.currentTarget = null;
};
baidu.object = baidu.object || {};
baidu.extend =
baidu.object.extend = function (target, source) {
for (var p in source) {
if (source.hasOwnProperty(p)) {
target[p] = source[p];
}
}
return target;
};
baidu.event = baidu.event || {};
baidu.event._listeners = baidu.event._listeners || [];
baidu.dom = baidu.dom || {};
baidu.dom._g = function (id) {
if (baidu.lang.isString(id)) {
return document.getElementById(id);
}
return id;
};
baidu._g = baidu.dom._g;
baidu.event.on = function (element, type, listener) {
type = type.replace(/^on/i, '');
element = baidu.dom._g(element);
var realListener = function (ev) {
listener.call(element, ev);
},
lis = baidu.event._listeners,
filter = baidu.event._eventFilter,
afterFilter,
realType = type;
type = type.toLowerCase();
if (filter && filter[type]) {
afterFilter = filter[type](element, type, realListener);
realType = afterFilter.type;
realListener = afterFilter.listener;
}
if (element.addEventListener) {
element.addEventListener(realType, realListener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + realType, realListener);
}
lis[lis.length] = [element, type, listener, realListener, realType];
return element;
};
baidu.on = baidu.event.on;
baidu.event.un = function (element, type, listener) {
element = baidu.dom._g(element);
type = type.replace(/^on/i, '').toLowerCase();
var lis = baidu.event._listeners,
len = lis.length,
isRemoveAll = !listener,
item,
realType, realListener;
while (len--) {
item = lis[len];
if (item[1] === type
&& item[0] === element
&& (isRemoveAll || item[2] === listener)) {
realType = item[4];
realListener = item[3];
if (element.removeEventListener) {
element.removeEventListener(realType, realListener, false);
} else if (element.detachEvent) {
element.detachEvent('on' + realType, realListener);
}
lis.splice(len, 1);
}
}
return element;
};
baidu.un = baidu.event.un;
baidu.dom.g = function (id) {
if ('string' == typeof id || id instanceof String) {
return document.getElementById(id);
} else if (id && id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {
return id;
}
return null;
};
baidu.g = baidu.G = baidu.dom.g;
baidu.dom._styleFixer = baidu.dom._styleFixer || {};
baidu.dom._styleFilter = baidu.dom._styleFilter || [];
baidu.dom._styleFilter.filter = function (key, value, method) {
for (var i = 0, filters = baidu.dom._styleFilter, filter; filter = filters[i]; i++) {
if (filter = filter[method]) {
value = filter(key, value);
}
}
return value;
};
baidu.string = baidu.string || {};
baidu.string.toCamelCase = function (source) {
if (source.indexOf('-') < 0 && source.indexOf('_') < 0) {
return source;
}
return source.replace(/[-_][^-_]/g, function (match) {
return match.charAt(1).toUpperCase();
});
};
baidu.dom.setStyle = function (element, key, value) {
var dom = baidu.dom, fixer;
element = dom.g(element);
key = baidu.string.toCamelCase(key);
if (fixer = dom._styleFilter) {
value = fixer.filter(key, value, 'set');
}
fixer = dom._styleFixer[key];
(fixer && fixer.set) ? fixer.set(element, value) : (element.style[fixer || key] = value);
return element;
};
baidu.setStyle = baidu.dom.setStyle;
baidu.dom.setStyles = function (element, styles) {
element = baidu.dom.g(element);
for (var key in styles) {
baidu.dom.setStyle(element, key, styles[key]);
}
return element;
};
baidu.setStyles = baidu.dom.setStyles;
baidu.browser = baidu.browser || {};
baidu.browser.ie = baidu.ie = /msie (\d+\.\d+)/i.test(navigator.userAgent) ? (document.documentMode || + RegExp['\x241']) : undefined;
baidu.dom._NAME_ATTRS = (function () {
var result = {
'cellpadding': 'cellPadding',
'cellspacing': 'cellSpacing',
'colspan': 'colSpan',
'rowspan': 'rowSpan',
'valign': 'vAlign',
'usemap': 'useMap',
'frameborder': 'frameBorder'
};
if (baidu.browser.ie < 8) {
result['for'] = 'htmlFor';
result['class'] = 'className';
} else {
result['htmlFor'] = 'for';
result['className'] = 'class';
}
return result;
})();
baidu.dom.setAttr = function (element, key, value) {
element = baidu.dom.g(element);
if ('style' == key) {
element.style.cssText = value;
} else {
key = baidu.dom._NAME_ATTRS[key] || key;
element.setAttribute(key, value);
}
return element;
};
baidu.setAttr = baidu.dom.setAttr;
baidu.dom.setAttrs = function (element, attributes) {
element = baidu.dom.g(element);
for (var key in attributes) {
baidu.dom.setAttr(element, key, attributes[key]);
}
return element;
};
baidu.setAttrs = baidu.dom.setAttrs;
baidu.dom.create = function (tagName, opt_attributes) {
var el = document.createElement(tagName),
attributes = opt_attributes || {};
return baidu.dom.setAttrs(el, attributes);
};
T.undope = true;
var ZoomBox = function () {
try {
BMap;
} catch (e) {
throw Error('Baidu Map JS API is not ready yet!');
}
if (!ZoomBox._isExtended) {
ZoomBox._isExtended = true;
extend(ZoomBox, BMap.Overlay, "ZoomBox");
var zoomBox = new ZoomBox();
this.__proto__ = zoomBox.__proto__;
}
this.opts = {
zoomType: 0,
strokeWeight: 1,
};
this._isOpen = true;
this._fDiv = null;
this._div = null;
}
baidu.object.extend(ZoomBox.prototype, {
initialize: function (map) {
var me = this;
me._map = map;
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.getContainer().offsetWidth;
size.height = me._map.getContainer().offsetHeight;
div.style.cssText = "z-index: 8; position:absolute; width:" + size.width + "px;height:" + size.height + "px";
this._map.getPanes().mapPane.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.61;
me._fDiv.style.backgroundColor = "#e4e9f4";
me._fDiv.style.cursor = "crosshair";
me._fDiv.style.zIndex = 99;
me._fDiv.style.position = 'absolute';
me._fDiv.style.width = 0;
me._fDiv.style.height = 0;
me._fDiv.style.border = " 2px solid #0051FF";
me._map.getContainer().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";
T.event.on(me._map.getContainer(), "mousemove", drawingRect);
T.event.on(me._map.getContainer(), "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.getContainer().clientWidth, me._map.getContainer().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 (e) {
if (me._isOpen == true && me._fDiv) {
me._map.removeEventListener('mousemove', drawingRect);
me._map.removeEventListener('mouseup', endDrawRect);
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.getContainer().clientWidth, me._map.getContainer().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) {
var targetCenterPt = me._map.pixelToPoint({ x: centerX, y: centerY }, me._map.getZoom());
me._map.centerAndZoom(targetCenterPt, targetZoomLv);
}
me._bind.isZooming = false;
me._fDiv.parentNode.removeChild(me._fDiv);
me._fDiv = null;
me.stopBubble(e);
return me.preventDefault(e);
}
};
if (!this._isBeginDrawBinded) {
T.event.on(me._map.getContainer(), "mousedown", function (e) {
if (e.which === 3) {
this._isBeginDrawBinded = true;
document.oncontextmenu = function () { return false };
beginDrawRect(e);
}
});
}
},
_bind: function () {
var me = this;
if (!me._isOpen) {
return;
}
},
_dispatchEvent: function (instance, type, opts) {
type.indexOf("on") != 0 && (type = "on" + type);
var event = new baidu.lang.Event(type);
if (!!opts) {
for (var p in opts) {
event[p] = opts[p];
}
}
instance.dispatchEvent(event);
},
stopBubble: function (instance, type, opts) {
var e = window.event || e;
e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
},
preventDefault: function (instance, type, opts) {
var e = window.event || e;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
return false;
}
});
return ZoomBox;
});