鼠标绘制工具加是否超出范围判断
生活随笔
收集整理的這篇文章主要介紹了
鼠标绘制工具加是否超出范围判断
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
初始化鼠標繪制工具的代碼:
//實例化鼠標繪制工具_this.drawingManager = new BMapLib.DrawingManager(_this.addMap, {isOpen: true, //是否開啟繪制模式enableDrawingTool: false, //是否顯示工具欄drawingToolOptions: {anchor: BMAP_ANCHOR_TOP_RIGHT, //位置offset: new BMap.Size(5, 5), //偏離值drawingModes: [BMAP_DRAWING_POLYGON]},polygonOptions: _this.styleOptions, //多邊形的樣式//----------------主要是這里哦----------------outRange:false,//是否超出范圍hasLabel:false//是否顯示label});然后先添加一個多邊形,鼠標繪制不可以離開多邊形:
var ply = new BMap.Polygon(points, { strokeWeight: 2, strokeColor: red, fillOpacity: 0.4}); //建立多邊形覆蓋物 .addEventListener("mouseover", this.mouseover); ply.addEventListener("mouseout", this.mouseout); this.addMap.addOverlay(ply);下面是鼠標移入移出事件:
//子網格鼠標移入事件,如果正在繪制,并且繪制模式為選中狀態mouseover(evt) {if(this.drawingManager._isOpen&&this.drawingManager.getDrawingMode()!='marker'){if(!this.drawingManager._outRange){ this.drawingManager.outRangeAction();}}}, mouseout(evt) {if(this.drawingManager._isOpen && this.drawingManager.getDrawingMode()!='marker'){if(this.drawingManager._outRange){ this.drawingManager.inRangeAction();}}}DrawingManager.js源代碼:搜索outRange可直接查看我加的一些代碼
/*** @fileoverview 百度地圖的鼠標繪制工具,對外開放。* 允許用戶在地圖上點擊完成鼠標繪制的功能。* 使用者可以自定義所繪制結果的相關樣式,例如線寬、顏色、測線段距離、面積等等。* 主入口類是<a href="symbols/BMapLib.DrawingManager.html">DrawingManager</a>,* 基于Baidu Map API 1.4。** @author Baidu Map Api Group * @version 1.4*//** * @namespace BMap的所有library類均放在BMapLib命名空間下*/var BMapLib = window.BMapLib = BMapLib || {};/*** 定義常量, 繪制的模式* @final {Number} DrawingType*/var BMAP_DRAWING_MARKER = "marker", // 鼠標畫點模式BMAP_DRAWING_POLYLINE = "polyline", // 鼠標畫線模式BMAP_DRAWING_CIRCLE = "circle", // 鼠標畫圓模式BMAP_DRAWING_RECTANGLE = "rectangle", // 鼠標畫矩形模式BMAP_DRAWING_POLYGON = "polygon"; // 鼠標畫多邊形模式(function() {/*** 聲明baidu包*/var baidu = baidu || {guid : "$BAIDU$"};(function() {// 一些頁面級別唯一的屬性,需要掛載在window[baidu.guid]上window[baidu.guid] = {};/*** 將源對象的所有屬性拷貝到目標對象中* @name baidu.extend* @function* @grammar baidu.extend(target, source)* @param {Object} target 目標對象* @param {Object} source 源對象* @returns {Object} 目標對象*/baidu.extend = function (target, source) {for (var p in source) {if (source.hasOwnProperty(p)) {target[p] = source[p];}} return target;};/*** @ignore* @namespace* @baidu.lang 對語言層面的封裝,包括類型判斷、模塊擴展、繼承基類以及對象自定義事件的支持。* @property guid 對象的唯一標識*/baidu.lang = baidu.lang || {};/*** 返回一個當前頁面的唯一標識字符串。* @function* @grammar baidu.lang.guid()* @returns {String} 當前頁面的唯一標識字符串*/baidu.lang.guid = function() {return "TANGRAM__" + (window[baidu.guid]._counter ++).toString(36);};window[baidu.guid]._counter = window[baidu.guid]._counter || 1;/*** 所有類的實例的容器* key為每個實例的guid*/window[baidu.guid]._instances = window[baidu.guid]._instances || {};/*** Tangram繼承機制提供的一個基類,用戶可以通過繼承baidu.lang.Class來獲取它的屬性及方法。* @function* @name baidu.lang.Class* @grammar baidu.lang.Class(guid)* @param {string} guid 對象的唯一標識* @meta standard* @remark baidu.lang.Class和它的子類的實例均包含一個全局唯一的標識guid。* guid是在構造函數中生成的,因此,繼承自baidu.lang.Class的類應該直接或者間接調用它的構造函數。<br>* baidu.lang.Class的構造函數中產生guid的方式可以保證guid的唯一性,及每個實例都有一個全局唯一的guid。*/baidu.lang.Class = function(guid) {this.guid = guid || baidu.lang.guid();window[baidu.guid]._instances[this.guid] = this;};window[baidu.guid]._instances = window[baidu.guid]._instances || {};/*** 判斷目標參數是否string類型或String對象* @name baidu.lang.isString* @function* @grammar baidu.lang.isString(source)* @param {Any} source 目標參數* @shortcut isString* @meta standard* * @returns {boolean} 類型判斷結果*/baidu.lang.isString = function (source) {return '[object String]' == Object.prototype.toString.call(source);};/*** 判斷目標參數是否為function或Function實例* @name baidu.lang.isFunction* @function* @grammar baidu.lang.isFunction(source)* @param {Any} source 目標參數* @returns {boolean} 類型判斷結果*/baidu.lang.isFunction = function (source) {return '[object Function]' == Object.prototype.toString.call(source);};/*** 重載了默認的toString方法,使得返回信息更加準確一些。* @return {string} 對象的String表示形式*/baidu.lang.Class.prototype.toString = function(){return "[object " + (this._className || "Object" ) + "]";};/*** 釋放對象所持有的資源,主要是自定義事件。* @name dispose* @grammar obj.dispose()*/baidu.lang.Class.prototype.dispose = function(){delete window[baidu.guid]._instances[this.guid];for(var property in this){if (!baidu.lang.isFunction(this[property])) {delete this[property];}}this.disposed = true;};/*** 自定義的事件對象。* @function* @name baidu.lang.Event* @grammar baidu.lang.Event(type[, target])* @param {string} type 事件類型名稱。為了方便區分事件和一個普通的方法,事件類型名稱必須以"on"(小寫)開頭。* @param {Object} [target]觸發事件的對象* @meta standard* @remark 引入該模塊,會自動為Class引入3個事件擴展方法:addEventListener、removeEventListener和dispatchEvent。* @see baidu.lang.Class*/baidu.lang.Event = function (type, target) {this.type = type;this.returnValue = true;this.target = target || null;this.currentTarget = null;};/*** 注冊對象的事件監聽器。引入baidu.lang.Event后,Class的子類實例才會獲得該方法。* @grammar obj.addEventListener(type, handler[, key])* @param {string} type 自定義事件的名稱* @param {Function} handler 自定義事件被觸發時應該調用的回調函數* @param {string} [key] 為事件監聽函數指定的名稱,可在移除時使用。如果不提供,方法會默認為它生成一個全局唯一的key。* @remark 事件類型區分大小寫。如果自定義事件名稱不是以小寫"on"開頭,該方法會給它加上"on"再進行判斷,即"click"和"onclick"會被認為是同一種事件。 */baidu.lang.Class.prototype.addEventListener = function (type, handler, key) {if (!baidu.lang.isFunction(handler)) {return;}!this.__listeners && (this.__listeners = {});var t = this.__listeners, id;if (typeof key == "string" && key) {if (/[^\w\-]/.test(key)) {throw("nonstandard key:" + key);} else {handler.hashCode = key; id = key;}}type.indexOf("on") != 0 && (type = "on" + type);typeof t[type] != "object" && (t[type] = {});id = id || baidu.lang.guid();handler.hashCode = id;t[type][id] = handler;};/*** 移除對象的事件監聽器。引入baidu.lang.Event后,Class的子類實例才會獲得該方法。* @grammar obj.removeEventListener(type, handler)* @param {string} type 事件類型* @param {Function|string} handler 要移除的事件監聽函數或者監聽函數的key* @remark 如果第二個參數handler沒有被綁定到對應的自定義事件中,什么也不做。*/baidu.lang.Class.prototype.removeEventListener = function (type, handler) {if (baidu.lang.isFunction(handler)) {handler = handler.hashCode;} else if (!baidu.lang.isString(handler)) {return;}!this.__listeners && (this.__listeners = {});type.indexOf("on") != 0 && (type = "on" + type);var t = this.__listeners;if (!t[type]) {return;}t[type][handler] && delete t[type][handler];};/*** 派發自定義事件,使得綁定到自定義事件上面的函數都會被執行。引入baidu.lang.Event后,Class的子類實例才會獲得該方法。* @grammar obj.dispatchEvent(event, options)* @param {baidu.lang.Event|String} event Event對象,或事件名稱(1.1.1起支持)* @param {Object} options 擴展參數,所含屬性鍵值會擴展到Event對象上(1.2起支持)* @remark 處理會調用通過addEventListenr綁定的自定義事件回調函數之外,還會調用直接綁定到對象上面的自定義事件。* 例如:<br>* myobj.onMyEvent = function(){}<br>* myobj.addEventListener("onMyEvent", function(){});*/baidu.lang.Class.prototype.dispatchEvent = function (event, options) {if (baidu.lang.isString(event)) {event = new baidu.lang.Event(event);}!this.__listeners && (this.__listeners = {});options = options || {};for (var i in options) {event[i] = options[i];}var i, t = this.__listeners, p = event.type;event.target = event.target || this;event.currentTarget = this;p.indexOf("on") != 0 && (p = "on" + p);baidu.lang.isFunction(this[p]) && this[p].apply(this, arguments);if (typeof t[p] == "object") {for (i in t[p]) {t[p][i].apply(this, arguments);}}return event.returnValue;};/*** 為類型構造器建立繼承關系* @name baidu.lang.inherits* @function* @grammar baidu.lang.inherits(subClass, superClass[, className])* @param {Function} subClass 子類構造器* @param {Function} superClass 父類構造器* @param {string} className 類名標識* @remark 使subClass繼承superClass的prototype,* 因此subClass的實例能夠使用superClass的prototype中定義的所有屬性和方法。<br>* 這個函數實際上是建立了subClass和superClass的原型鏈集成,并對subClass進行了constructor修正。<br>* <strong>注意:如果要繼承構造函數,需要在subClass里面call一下,具體見下面的demo例子</strong>* @shortcut inherits* @meta standard* @see baidu.lang.Class*/baidu.lang.inherits = function (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;}};/*** @ignore* @namespace baidu.dom 操作dom的方法。*/baidu.dom = baidu.dom || {};/*** 從文檔中獲取指定的DOM元素* * @param {string|HTMLElement} id 元素的id或DOM元素* @meta standard* @return {HTMLElement} DOM元素,如果不存在,返回null,如果參數不合法,直接返回參數*/baidu._g = baidu.dom._g = function (id) {if (baidu.lang.isString(id)) {return document.getElementById(id);}return id;};/*** 從文檔中獲取指定的DOM元素* @name baidu.dom.g* @function* @grammar baidu.dom.g(id)* @param {string|HTMLElement} id 元素的id或DOM元素* @meta standard* * @returns {HTMLElement|null} 獲取的元素,查找不到時返回null,如果參數不合法,直接返回參數*/baidu.g = 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;};/*** 在目標元素的指定位置插入HTML代碼* @name baidu.dom.insertHTML* @function* @grammar baidu.dom.insertHTML(element, position, html)* @param {HTMLElement|string} element 目標元素或目標元素的id* @param {string} position 插入html的位置信息,取值為beforeBegin,afterBegin,beforeEnd,afterEnd* @param {string} html 要插入的html* @remark* * 對于position參數,大小寫不敏感<br>* 參數的意思:beforeBegin<span>afterBegin this is span! beforeEnd</span> afterEnd <br />* 此外,如果使用本函數插入帶有script標簽的HTML字符串,script標簽對應的腳本將不會被執行。* * @shortcut insertHTML* @meta standard* * @returns {HTMLElement} 目標元素*/baidu.insertHTML = baidu.dom.insertHTML = function (element, position, html) {element = baidu.dom.g(element);var range,begin;if (element.insertAdjacentHTML) {element.insertAdjacentHTML(position, html);} else {// 這里不做"undefined" != typeof(HTMLElement) && !window.opera判斷,其它瀏覽器將出錯?!// 但是其實做了判斷,其它瀏覽器下等于這個函數就不能執行了range = element.ownerDocument.createRange();// FF下range的位置設置錯誤可能導致創建出來的fragment在插入dom樹之后html結構亂掉// 改用range.insertNode來插入html, by wenyuxiang @ 2010-12-14.position = position.toUpperCase();if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {range.selectNodeContents(element);range.collapse(position == 'AFTERBEGIN');} else {begin = position == 'BEFOREBEGIN';range[begin ? 'setStartBefore' : 'setEndAfter'](element);range.collapse(begin);}range.insertNode(range.createContextualFragment(html));}return element;};/*** 為目標元素添加className* @name baidu.dom.addClass* @function* @grammar baidu.dom.addClass(element, className)* @param {HTMLElement|string} element 目標元素或目標元素的id* @param {string} className 要添加的className,允許同時添加多個class,中間使用空白符分隔* @remark* 使用者應保證提供的className合法性,不應包含不合法字符,className合法字符參考:http://www.w3.org/TR/CSS2/syndata.html。* @shortcut addClass* @meta standard* * @returns {HTMLElement} 目標元素*/baidu.ac = baidu.dom.addClass = function (element, className) {element = baidu.dom.g(element);var classArray = className.split(/\s+/),result = element.className,classMatch = " " + result + " ",i = 0,l = classArray.length;for (; i < l; i++){if ( classMatch.indexOf( " " + classArray[i] + " " ) < 0 ) {result += (result ? ' ' : '') + classArray[i];}}element.className = result;return element;};/*** @ignore* @namespace baidu.event 屏蔽瀏覽器差異性的事件封裝。* @property target 事件的觸發元素* @property pageX 鼠標事件的鼠標x坐標* @property pageY 鼠標事件的鼠標y坐標* @property keyCode 鍵盤事件的鍵值*/baidu.event = baidu.event || {};/*** 事件監聽器的存儲表* @private* @meta standard*/baidu.event._listeners = baidu.event._listeners || [];/*** 為目標元素添加事件監聽器* @name baidu.event.on* @function* @grammar baidu.event.on(element, type, listener)* @param {HTMLElement|string|window} element 目標元素或目標元素id* @param {string} type 事件類型* @param {Function} listener 需要添加的監聽器* @remark* 1. 不支持跨瀏覽器的鼠標滾輪事件監聽器添加<br>* 2. 改方法不為監聽器灌入事件對象,以防止跨iframe事件掛載的事件對象獲取失敗 * @shortcut on* @meta standard* @see baidu.event.un* * @returns {HTMLElement|window} 目標元素*/baidu.on = baidu.event.on = function (element, type, listener) {type = type.replace(/^on/i, '');element = baidu._g(element);var realListener = function (ev) {// 1. 這里不支持EventArgument, 原因是跨frame的事件掛載// 2. element是為了修正thislistener.call(element, ev);},lis = baidu.event._listeners,filter = baidu.event._eventFilter,afterFilter,realType = type;type = type.toLowerCase();// filter過濾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;};/*** 為目標元素移除事件監聽器* @name baidu.event.un* @function* @grammar baidu.event.un(element, type, listener)* @param {HTMLElement|string|window} element 目標元素或目標元素id* @param {string} type 事件類型* @param {Function} listener 需要移除的監聽器* @shortcut un* @meta standard* * @returns {HTMLElement|window} 目標元素*/baidu.un = baidu.event.un = function (element, type, listener) {element = baidu._g(element);type = type.replace(/^on/i, '').toLowerCase();var lis = baidu.event._listeners, len = lis.length,isRemoveAll = !listener,item,realType, realListener;//如果將listener的結構改成json//可以節省掉這個循環,優化性能//但是由于un的使用頻率并不高,同時在listener不多的時候//遍歷數組的性能消耗不會對代碼產生影響//暫不考慮此優化while (len--) {item = lis[len];// listener存在時,移除element的所有以listener監聽的type類型事件// listener不存在時,移除element的所有type類型事件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;};/*** 獲取event事件,解決不同瀏覽器兼容問題* @param {Event}* @return {Event}*/baidu.getEvent = baidu.event.getEvent = function (event) {return window.event || event;}/*** 獲取event.target,解決不同瀏覽器兼容問題* @param {Event}* @return {Target}*/baidu.getTarget = baidu.event.getTarget = function (event) {var event = baidu.getEvent(event);return event.target || event.srcElement;}/*** 阻止事件的默認行為* @name baidu.event.preventDefault* @function* @grammar baidu.event.preventDefault(event)* @param {Event} event 事件對象* @meta standard*/baidu.preventDefault = baidu.event.preventDefault = function (event) {var event = baidu.getEvent(event);if (event.preventDefault) {event.preventDefault();} else {event.returnValue = false;}};/*** 停止事件冒泡傳播* @param {Event}*/baidu.stopBubble = baidu.event.stopBubble = function (event) {event = baidu.getEvent(event);event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true;}})();/** * @exports DrawingManager as BMapLib.DrawingManager */var DrawingManager =/*** DrawingManager類的構造函數* @class 鼠標繪制管理類,實現鼠標繪制管理的<b>入口</b>。* 實例化該類后,即可調用該類提供的open* 方法開啟繪制模式狀態。* 也可加入工具欄進行選擇操作。* * @constructor* @param {Map} map Baidu map的實例對象* @param {Json Object} opts 可選的輸入參數,非必填項。可輸入選項包括:<br />* {"<b>isOpen</b>" : {Boolean} 是否開啟繪制模式* <br />"<b>enableDrawingTool</b>" : {Boolean} 是否添加繪制工具欄控件,默認不添加* <br />"<b>drawingToolOptions</b>" : {Json Object} 可選的輸入參數,非必填項。可輸入選項包括* <br /> "<b>anchor</b>" : {ControlAnchor} 停靠位置、默認左上角* <br /> "<b>offset</b>" : {Size} 偏移值。* <br /> "<b>scale</b>" : {Number} 工具欄的縮放比例,默認為1* <br /> "<b>drawingModes</b>" : {DrawingType<Array>} 工具欄上可以選擇出現的繪制模式,將需要顯示的DrawingType以數組型形式傳入,如[BMAP_DRAWING_MARKER, BMAP_DRAWING_CIRCLE] 將只顯示畫點和畫圓的選項* <br />"<b>enableCalculate</b>" : {Boolean} 繪制是否進行測距(畫線時候)、測面(畫圓、多邊形、矩形)* <br />"<b>markerOptions</b>" : {CircleOptions} 所畫的點的可選參數,參考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">對應類</a>* <br />"<b>circleOptions</b>" : {CircleOptions} 所畫的圓的可選參數,參考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">對應類</a>* <br />"<b>polylineOptions</b>" : {CircleOptions} 所畫的線的可選參數,參考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">對應類</a>* <br />"<b>polygonOptions</b>" : {PolygonOptions} 所畫的多邊形的可選參數,參考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">對應類</a>* <br />"<b>rectangleOptions</b>" : {PolygonOptions} 所畫的矩形的可選參數,參考api中的<a href="http://developer.baidu.com/map/reference/index.php?title=Class:%E6%80%BB%E7%B1%BB/%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB">對應類</a>** @example <b>參考示例:</b><br />* var map = new BMap.Map("container");<br />map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);<br />* var myDrawingManagerObject = new BMapLib.DrawingManager(map, {isOpen: true, * drawingType: BMAP_DRAWING_MARKER, enableDrawingTool: true,* enableCalculate: false,* drawingToolOptions: {* anchor: BMAP_ANCHOR_TOP_LEFT,* offset: new BMap.Size(5, 5),* drawingTypes : [* BMAP_DRAWING_MARKER,* BMAP_DRAWING_CIRCLE,* BMAP_DRAWING_POLYLINE,* BMAP_DRAWING_POLYGON,* BMAP_DRAWING_RECTANGLE * ]* },* polylineOptions: {* strokeColor: "#333"* });*/BMapLib.DrawingManager = function(map, opts){if (!map) {return;}instances.push(this);opts = opts || {};this._initialize(map, opts);}// 通過baidu.lang下的inherits方法,讓DrawingManager繼承baidu.lang.Classbaidu.lang.inherits(DrawingManager, baidu.lang.Class, "DrawingManager");/*** 開啟地圖的繪制模式** @example <b>參考示例:</b><br />* myDrawingManagerObject.open();*/DrawingManager.prototype.open = function() {// 判斷繪制狀態是否已經開啟if (this._isOpen == true){return true;}closeInstanceExcept(this);this._open();}/*** 關閉地圖的繪制狀態** @example <b>參考示例:</b><br />* myDrawingManagerObject.close();*/DrawingManager.prototype.close = function() {// 判斷繪制狀態是否已經開啟if (this._isOpen == false){return true;}this._close();}DrawingManager.prototype.outRangeAction=function(){this._outRangeAction();}DrawingManager.prototype.inRangeAction=function(){this._inRangeAction();}/*** 設置當前的繪制模式,參數DrawingType,為5個可選常量:* <br/>BMAP_DRAWING_MARKER 畫點* <br/>BMAP_DRAWING_CIRCLE 畫圓* <br/>BMAP_DRAWING_POLYLINE 畫線* <br/>BMAP_DRAWING_POLYGON 畫多邊形* <br/>BMAP_DRAWING_RECTANGLE 畫矩形* @param {DrawingType} DrawingType* @return {Boolean} ** @example <b>參考示例:</b><br />* myDrawingManagerObject.setDrawingMode(BMAP_DRAWING_POLYLINE);*/DrawingManager.prototype.setDrawingMode = function(drawingType) {//與當前模式不一樣時候才進行重新綁定事件if (this._drawingType != drawingType) {closeInstanceExcept(this);this._setDrawingMode(drawingType);}}/*** 獲取當前的繪制模式* @return {DrawingType} 繪制的模式** @example <b>參考示例:</b><br />* alert(myDrawingManagerObject.getDrawingMode());*/DrawingManager.prototype.getDrawingMode = function() {return this._drawingType;}/*** 打開距離或面積計算** @example <b>參考示例:</b><br />* myDrawingManagerObject.enableCalculate();*/DrawingManager.prototype.enableCalculate = function() {this._enableCalculate = true;this._addGeoUtilsLibrary();}/*** 關閉距離或面積計算** @example <b>參考示例:</b><br />* myDrawingManagerObject.disableCalculate();*/DrawingManager.prototype.disableCalculate = function() {this._enableCalculate = false;}/*** 鼠標繪制完成后,派發總事件的接口* @name DrawingManager#overlaycomplete* @event* @param {Event Object} e 回調函數會返回event參數,包括以下返回值:* <br />{"<b>drawingMode</b> : {DrawingType} 當前的繪制模式* <br />"<b>overlay</b>:{Marker||Polyline||Polygon||Circle} 對應的繪制模式返回對應的覆蓋物* <br />"<b>calculate</b>:{Number} 需要開啟計算模式才會返回這個值,當繪制線的時候返回距離、繪制多邊形、圓、矩形時候返回面積,單位為米,* <br />"<b>label</b>:{Label} 計算面積時候出現在Map上的Label對象** @example <b>參考示例:</b>* myDrawingManagerObject.addEventListener("overlaycomplete", function(e) {* alert(e.drawingMode);* alert(e.overlay);* alert(e.calculate);* alert(e.label);* });*//*** 繪制點完成后,派發的事件接口* @name DrawingManager#markercomplete* @event* @param {Marker} overlay 回調函數會返回相應的覆蓋物,* <br />{"<b>overlay</b> : {Marker} ** @example <b>參考示例:</b>* myDrawingManagerObject.addEventListener("circlecomplete", function(e, overlay) {* alert(overlay);* });*//*** 繪制圓完成后,派發的事件接口* @name DrawingManager#circlecomplete* @event* @param {Circle} overlay 回調函數會返回相應的覆蓋物,* <br />{"<b>overlay</b> : {Circle} *//*** 繪制線完成后,派發的事件接口* @name DrawingManager#polylinecomplete* @event* @param {Polyline} overlay 回調函數會返回相應的覆蓋物,* <br />{"<b>overlay</b> : {Polyline} *//*** 繪制多邊形完成后,派發的事件接口* @name DrawingManager#polygoncomplete* @event* @param {Polygon} overlay 回調函數會返回相應的覆蓋物,* <br />{"<b>overlay</b> : {Polygon} *//*** 繪制矩形完成后,派發的事件接口* @name DrawingManager#rectanglecomplete* @event* @param {Polygon} overlay 回調函數會返回相應的覆蓋物,* <br />{"<b>overlay</b> : {Polygon} *//*** 初始化狀態* @param {Map} 地圖實例* @param {Object} 參數*/DrawingManager.prototype._initialize = function(map, opts) {/*** map對象* @private* @type {Map}*/this._map = map;/*** 配置對象* @private* @type {Object}*/this._opts = opts;/*** 當前的繪制模式, 默認是繪制點* @private* @type {DrawingType}*/this._drawingType = opts.drawingMode || BMAP_DRAWING_MARKER;/*** 是否添加添加鼠標繪制工具欄面板*/if (opts.enableDrawingTool) {var drawingTool = new DrawingTool(this, opts.drawingToolOptions);this._drawingTool = drawingTool;map.addControl(drawingTool);}//是否計算繪制出的面積 if (opts.enableCalculate === true) {this.enableCalculate();} else {this.disableCalculate();}/*** 是否已經開啟了繪制狀態* @private* @type {Boolean}*/this._isOpen = !!(opts.isOpen === true);if (this._isOpen) {this._open();}this.markerOptions = opts.markerOptions || {};this.circleOptions = opts.circleOptions || {};this.polylineOptions = opts.polylineOptions || {};this.polygonOptions = opts.polygonOptions || {};this.rectangleOptions = opts.rectangleOptions || {};/**是否越界 */this._outRange=!!(opts.outRange === true);this._hasLabel=!!(opts.hasLabel === true);},DrawingManager.prototype._outRangeAction= function(){this._outRange=true;}DrawingManager.prototype._inRangeAction= function(){this._outRange=false;}/*** 開啟地圖的繪制狀態* @return {Boolean},開啟繪制狀態成功,返回true;否則返回false。*/DrawingManager.prototype._open = function() {this._isOpen = true;//添加遮罩,所有鼠標操作都在這個遮罩上完成if (!this._mask) {this._mask = new Mask();}this._map.addOverlay(this._mask);this._setDrawingMode(this._drawingType);}/*** 設置當前的繪制模式* @param {DrawingType}*/DrawingManager.prototype._setDrawingMode = function(drawingType) {this._drawingType = drawingType;/*** 開啟編輯狀態時候才重新進行事件綁定*/if (this._isOpen) {//清空之前的自定義事件this._mask.__listeners = {};switch (drawingType) {case BMAP_DRAWING_MARKER:this._bindMarker();break;case BMAP_DRAWING_CIRCLE:this._bindCircle();break;case BMAP_DRAWING_POLYLINE:case BMAP_DRAWING_POLYGON:this._bindPolylineOrPolygon();break;case BMAP_DRAWING_RECTANGLE:this._bindRectangle();break;}}/** * 如果添加了工具欄,則也需要改變工具欄的樣式*/if (this._drawingTool && this._isOpen) {this._drawingTool.setStyleByDrawingMode(drawingType);}}/*** 關閉地圖的繪制狀態* @return {Boolean},關閉繪制狀態成功,返回true;否則返回false。*/DrawingManager.prototype._close = function() {this._isOpen = false;if (this._mask) {this._map.removeOverlay(this._mask);}/** * 如果添加了工具欄,則關閉時候將工具欄樣式設置為拖拽地圖*/if (this._drawingTool) {this._drawingTool.setStyleByDrawingMode("hander");}}/*** 綁定鼠標畫點的事件*/DrawingManager.prototype._bindMarker = function() {var me = this,map = this._map,mask = this._mask;/*** 鼠標點擊的事件*/var clickAction = function (e) {// 往地圖上添加markervar marker = new BMap.Marker(e.point, me.markerOptions);map.addOverlay(marker);me._dispatchOverlayComplete(marker);}mask.addEventListener('click', clickAction);}/*** 綁定鼠標畫圓的事件*/DrawingManager.prototype._bindCircle = function() {var me = this,map = this._map,mask = this._mask,circle = null,centerPoint = null; //圓的中心點/*** 開始繪制圓形*/var startAction = function (e) {centerPoint = e.point;circle = new BMap.Circle(centerPoint, 0, me.circleOptions);map.addOverlay(circle);mask.enableEdgeMove();mask.addEventListener('mousemove', moveAction);baidu.on(document, 'mouseup', endAction);}/*** 繪制圓形過程中,鼠標移動過程的事件*/var moveAction = function(e) {circle.setRadius(me._map.getDistance(centerPoint, e.point));}/*** 繪制圓形結束*/var endAction = function (e) {var calculate = me._calculate(circle, e.point);me._dispatchOverlayComplete(circle, calculate);centerPoint = null;mask.disableEdgeMove();mask.removeEventListener('mousemove', moveAction);baidu.un(document, 'mouseup', endAction);}/*** 鼠標點擊起始點*/var mousedownAction = function (e) {baidu.preventDefault(e);baidu.stopBubble(e);if (centerPoint == null) {startAction(e);} }mask.addEventListener('mousedown', mousedownAction);}/*** 畫線和畫多邊形相似性比較大,公用一個方法*/DrawingManager.prototype._bindPolylineOrPolygon = function() {var me = this,map = this._map,mask = this._mask,points = [], //用戶繪制的點drawPoint = null; //實際需要畫在地圖上的點overlay = null,isBinded = false;/*** 鼠標點擊的事件*/var startAction = function (e) { if(me._outRange){return;} points.push(e.point);drawPoint = points.concat(points[points.length - 1]);if (points.length == 1) {if (me._drawingType == BMAP_DRAWING_POLYLINE) {overlay = new BMap.Polyline(drawPoint, me.polylineOptions);} else if (me._drawingType == BMAP_DRAWING_POLYGON) {overlay = new BMap.Polygon(drawPoint, me.polygonOptions);}map.addOverlay(overlay);} else {overlay.setPath(drawPoint);}if (!isBinded) {isBinded = true;mask.enableEdgeMove();mask.addEventListener('mousemove', mousemoveAction);mask.addEventListener('dblclick', dblclickAction);}}/*** 鼠標移動過程的事件*/var mousemoveAction = function(e) {//自定義---如果超出范圍,禁止地圖自動平移if(me._outRange){mask.disableEdgeMove();return;}overlay.setPositionAt(drawPoint.length - 1, e.point);}/*** 鼠標雙擊的事件*/var dblclickAction = function (e) {baidu.stopBubble(e);isBinded = false;mask.disableEdgeMove();mask.removeEventListener('mousemove', mousemoveAction);mask.removeEventListener('dblclick', dblclickAction);overlay.setPath(points);var calculate = me._calculate(overlay, points.pop());me._dispatchOverlayComplete(overlay, calculate);points.length = 0;drawPoint.length = 0;}mask.addEventListener('click', startAction);//雙擊時候不放大地圖級別mask.addEventListener('dblclick', function(e){baidu.stopBubble(e);});}/*** 綁定鼠標畫矩形的事件*/DrawingManager.prototype._bindRectangle = function() {var me = this,map = this._map,mask = this._mask,polygon = null,startPoint = null;/*** 開始繪制矩形*/var startAction = function (e) {baidu.stopBubble(e);baidu.preventDefault(e);startPoint = e.point;var endPoint = startPoint;polygon = new BMap.Polygon(me._getRectanglePoint(startPoint, endPoint), me.rectangleOptions);map.addOverlay(polygon);mask.enableEdgeMove();mask.addEventListener('mousemove', moveAction);baidu.on(document, 'mouseup', endAction);}/*** 繪制矩形過程中,鼠標移動過程的事件*/var moveAction = function(e) {polygon.setPath(me._getRectanglePoint(startPoint, e.point));}/*** 繪制矩形結束*/var endAction = function (e) {var calculate = me._calculate(polygon, polygon.getPath()[2]);me._dispatchOverlayComplete(polygon, calculate);startPoint = null;mask.disableEdgeMove();mask.removeEventListener('mousemove', moveAction);baidu.un(document, 'mouseup', endAction);}mask.addEventListener('mousedown', startAction);}/*** 添加顯示所繪制圖形的面積或者長度* @param {overlay} 覆蓋物* @param {point} 顯示的位置*/DrawingManager.prototype._calculate = function (overlay, point) {var result = {data : 0, //計算出來的長度或面積label : null //顯示長度或面積的label對象};if (this._enableCalculate && BMapLib.GeoUtils) {var type = overlay.toString();//不同覆蓋物調用不同的計算方法switch (type) {case "[object Polyline]":result.data = BMapLib.GeoUtils.getPolylineDistance(overlay);break;case "[object Polygon]":result.data = BMapLib.GeoUtils.getPolygonArea(overlay);break;case "[object Circle]":var radius = overlay.getRadius();result.data = Math.PI * radius * radius;break;}//一場情況處理if (!result.data || result.data < 0) {result.data = 0;} else {//保留2位小數位result.data = result.data.toFixed(2);}//如果需要顯示LABEL并且面積大于0if(this._hasLabel && result.data >0){//把標簽的位置放到了最后一個點的位置result.label = this._addLabel(point, result.data);}}return result;}/*** 開啟測距和測面功能需要依賴于GeoUtils庫* 所以這里判斷用戶是否已經加載,若未加載則用js動態加載*/DrawingManager.prototype._addGeoUtilsLibrary = function () {if (!BMapLib.GeoUtils) {var script = document.createElement('script');script.setAttribute("type", "text/javascript");script.setAttribute("src", 'http://api.map.baidu.com/library/GeoUtils/1.2/src/GeoUtils_min.js');document.body.appendChild(script);}}/*** 向地圖中添加文本標注* @param {Point}* @param {String} 所以顯示的內容*/DrawingManager.prototype._addLabel = function (point, content) {var label = new BMap.Label(content, {position: point});this._map.addOverlay(label);return label;}/*** 根據起終點獲取矩形的四個頂點* @param {Point} 起點* @param {Point} 終點*/DrawingManager.prototype._getRectanglePoint = function (startPoint, endPoint) {return [new BMap.Point(startPoint.lng,startPoint.lat),new BMap.Point(endPoint.lng,startPoint.lat),new BMap.Point(endPoint.lng,endPoint.lat),new BMap.Point(startPoint.lng,endPoint.lat)];}/*** 派發事件*/DrawingManager.prototype._dispatchOverlayComplete = function (overlay, calculate) {var options = {'overlay' : overlay,'drawingMode' : this._drawingType,'calculate' : calculate.data || null,'label' : calculate.label || null};this.dispatchEvent(this._drawingType + 'complete', overlay);this.dispatchEvent('overlaycomplete', options);}/*** 創建遮罩對象*/function Mask(){/*** 鼠標到地圖邊緣的時候是否自動平移地圖*/this._enableEdgeMove = false;}Mask.prototype = new BMap.Overlay();// Mask.disableMassClear();/*** 這里不使用api中的自定義事件,是為了更靈活使用*/Mask.prototype.dispatchEvent = baidu.lang.Class.prototype.dispatchEvent;Mask.prototype.addEventListener = baidu.lang.Class.prototype.addEventListener;Mask.prototype.removeEventListener = baidu.lang.Class.prototype.removeEventListener;Mask.prototype.initialize = function(map){var me = this;// this.se = false;this._map = map;var div = this.container = document.createElement("div");div.id="mask";var size = this._map.getSize();div.style.cssText = "position:absolute;background:url(about:blank);cursor:crosshair;width:" + size.width + "px;height:" + size.height + "px";this._map.addEventListener('resize', function(e) {me._adjustSize(e.size);});this._map.getPanes().floatPane.appendChild(div);this._bind();return div; };Mask.prototype.draw = function() {var map = this._map,point = map.pixelToPoint(new BMap.Pixel(0, 0)),pixel = map.pointToOverlayPixel(point);this.container.style.left = pixel.x + "px";this.container.style.top = pixel.y + "px"; };/*** 開啟鼠標到地圖邊緣,自動平移地圖*/Mask.prototype.enableEdgeMove = function() {this._enableEdgeMove = true;}/*** 關閉鼠標到地圖邊緣,自動平移地圖*/Mask.prototype.disableEdgeMove = function() {clearInterval(this._edgeMoveTimer);this._enableEdgeMove = false;}/*** 綁定事件,派發自定義事件*/Mask.prototype._bind = function() {var me = this,map = this._map,container = this.container,lastMousedownXY = null,lastClickXY = null;/*** 根據event對象獲取鼠標的xy坐標對象* @param {Event}* @return {Object} {x:e.x, y:e.y}*/var getXYbyEvent = function(e){return {x : e.clientX,y : e.clientY}};var domEvent = function(e) {var type = e.type;e = baidu.getEvent(e);point = me.getDrawPoint(e); //當前鼠標所在點的地理坐標var dispatchEvent = function(type) {e.point = point;me.dispatchEvent(e);}if (type == "mousedown") {lastMousedownXY = getXYbyEvent(e);}var nowXY = getXYbyEvent(e);//click經過一些特殊處理派發,其他同事件按正常的dom事件派發if (type == "click") {//鼠標點擊過程不進行移動才派發click和dblclickif (Math.abs(nowXY.x - lastMousedownXY.x) < 5 && Math.abs(nowXY.y - lastMousedownXY.y) < 5 ) {if (!lastClickXY || !(Math.abs(nowXY.x - lastClickXY.x) < 5 && Math.abs(nowXY.y - lastClickXY.y) < 5)) {dispatchEvent('click');lastClickXY = getXYbyEvent(e);} else {lastClickXY = null;}}} else {dispatchEvent(type);}}/*** 將事件都遮罩層的事件都綁定到domEvent來處理*/var events = ['click', 'mousedown', 'mousemove', 'mouseup', 'dblclick'],index = events.length;while (index--) {baidu.on(container, events[index], domEvent);}//鼠標移動過程中,到地圖邊緣后自動平移地圖baidu.on(container, 'mousemove', function(e) {if (me._enableEdgeMove) {me.mousemoveAction(e);}});};//鼠標移動過程中,到地圖邊緣后自動平移地圖Mask.prototype.mousemoveAction = function(e) {function getClientPosition(e) {var clientX = e.clientX,clientY = e.clientY;if (e.changedTouches) {clientX = e.changedTouches[0].clientX;clientY = e.changedTouches[0].clientY;}return new BMap.Pixel(clientX, clientY);}var map = this._map,me = this,pixel = map.pointToPixel(this.getDrawPoint(e)),clientPos = getClientPosition(e),offsetX = clientPos.x - pixel.x,offsetY = clientPos.y - pixel.y;pixel = new BMap.Pixel((clientPos.x - offsetX), (clientPos.y - offsetY));this._draggingMovePixel = pixel;var point = map.pixelToPoint(pixel),eventObj = {pixel: pixel,point: point};// 拖拽到地圖邊緣移動地圖this._panByX = this._panByY = 0;if (pixel.x <= 20 || pixel.x >= map.width - 20|| pixel.y <= 50 || pixel.y >= map.height - 10) {if (pixel.x <= 20) {this._panByX = 8;} else if (pixel.x >= map.width - 20) {this._panByX = -8;}if (pixel.y <= 50) {this._panByY = 8;} else if (pixel.y >= map.height - 10) {this._panByY = -8;}if (!this._edgeMoveTimer) {this._edgeMoveTimer = setInterval(function(){map.panBy(me._panByX, me._panByY, {"noAnimation": true});}, 30);}} else {if (this._edgeMoveTimer) {clearInterval(this._edgeMoveTimer);this._edgeMoveTimer = null;}}}/** 調整大小* @param {Size}*/Mask.prototype._adjustSize = function(size) {this.container.style.width = size.width + 'px';this.container.style.height = size.height + 'px';};/*** 獲取當前繪制點的地理坐標** @param {Event} e e對象* @return Point對象的位置信息*/Mask.prototype.getDrawPoint = function(e) {var map = this._map,trigger = baidu.getTarget(e),x = e.offsetX || e.layerX || 0,y = e.offsetY || e.layerY || 0;if (trigger.nodeType != 1) trigger = trigger.parentNode;while (trigger && trigger != map.getContainer()) {if (!(trigger.clientWidth == 0 &&trigger.clientHeight == 0 &&trigger.offsetParent && trigger.offsetParent.nodeName == 'TD')) {x += trigger.offsetLeft || 0;y += trigger.offsetTop || 0;}trigger = trigger.offsetParent;}var pixel = new BMap.Pixel(x, y);var point = map.pixelToPoint(pixel);return point;}/*** 繪制工具面板,自定義控件*/function DrawingTool(drawingManager, drawingToolOptions) {this.drawingManager = drawingManager;drawingToolOptions = this.drawingToolOptions = drawingToolOptions || {};// 默認停靠位置和偏移量this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;this.defaultOffset = new BMap.Size(10, 10);//默認所有工具欄都顯示this.defaultDrawingModes = [BMAP_DRAWING_MARKER,BMAP_DRAWING_CIRCLE,BMAP_DRAWING_POLYLINE,BMAP_DRAWING_POLYGON,BMAP_DRAWING_RECTANGLE];//工具欄可顯示的繪制模式if (drawingToolOptions.drawingModes) {this.drawingModes = drawingToolOptions.drawingModes;} else {this.drawingModes = this.defaultDrawingModes}//用戶設置停靠位置和偏移量if (drawingToolOptions.anchor) {this.setAnchor(drawingToolOptions.anchor);}if (drawingToolOptions.offset) {this.setOffset(drawingToolOptions.offset);}}// 通過JavaScript的prototype屬性繼承于BMap.ControlDrawingTool.prototype = new BMap.Control();// 自定義控件必須實現自己的initialize方法,并且將控件的DOM元素返回// 在本方法中創建個div元素作為控件的容器,并將其添加到地圖容器中DrawingTool.prototype.initialize = function(map){// 創建一個DOM元素var container = this.container = document.createElement("div");container.className = "BMapLib_Drawing";//用來設置外層邊框陰影var panel = this.panel = document.createElement("div");panel.className = "BMapLib_Drawing_panel";if (this.drawingToolOptions && this.drawingToolOptions.scale) {this._setScale(this.drawingToolOptions.scale);}container.appendChild(panel);// 添加內容panel.innerHTML = this._generalHtml();//綁定事件this._bind(panel);// 添加DOM元素到地圖中map.getContainer().appendChild(container);// 將DOM元素返回return container;}//生成工具欄的html元素DrawingTool.prototype._generalHtml = function(map){//鼠標經過工具欄上的提示信息var tips = {};tips["hander"] = "拖動地圖";tips[BMAP_DRAWING_MARKER] = "畫點";tips[BMAP_DRAWING_CIRCLE] = "畫圓";tips[BMAP_DRAWING_POLYLINE] = "畫折線";tips[BMAP_DRAWING_POLYGON] = "畫多邊形";tips[BMAP_DRAWING_RECTANGLE] = "畫矩形";var getItem = function(className, drawingType) {return '<a class="' + className + '" drawingType="' + drawingType + '" href="javascript:void(0)" title="' + tips[drawingType] + '" onfocus="this.blur()"></a>';}var html = [];html.push(getItem("BMapLib_box BMapLib_hander", "hander"));for (var i = 0, len = this.drawingModes.length; i < len; i++) {var classStr = 'BMapLib_box BMapLib_' + this.drawingModes[i];if (i == len-1) {classStr += ' BMapLib_last';}html.push(getItem(classStr, this.drawingModes[i]));}return html.join('');}/*** 設置工具欄的縮放比例*/DrawingTool.prototype._setScale = function(scale){var width = 390,height = 50,ml = -parseInt((width - width * scale) / 2, 10),mt = -parseInt((height - height * scale) / 2, 10);this.container.style.cssText = ["-moz-transform: scale(" + scale + ");","-o-transform: scale(" + scale + ");","-webkit-transform: scale(" + scale + ");","transform: scale(" + scale + ");","margin-left:" + ml + "px;","margin-top:" + mt + "px;","*margin-left:0px;", //ie6、7"*margin-top:0px;", //ie6、7"margin-left:0px\\0;", //ie8"margin-top:0px\\0;", //ie8//ie下使用濾鏡"filter: progid:DXImageTransform.Microsoft.Matrix(","M11=" + scale + ",","M12=0,","M21=0,","M22=" + scale + ",","SizingMethod='auto expand');"].join('');}//綁定工具欄的事件DrawingTool.prototype._bind = function(panel){var me = this;baidu.on(this.panel, 'click', function (e) {var target = baidu.getTarget(e);var drawingType = target.getAttribute('drawingType');me.setStyleByDrawingMode(drawingType);me._bindEventByDraingMode(drawingType);});}//設置工具欄當前選中的項樣式DrawingTool.prototype.setStyleByDrawingMode = function(drawingType){if (!drawingType) {return;}var boxs = this.panel.getElementsByTagName("a");for (var i = 0, len = boxs.length; i < len; i++) {var box = boxs[i];if (box.getAttribute('drawingType') == drawingType) {var classStr = "BMapLib_box BMapLib_" + drawingType + "_hover";if (i == len - 1) {classStr += " BMapLib_last";}box.className = classStr;} else {box.className = box.className.replace(/_hover/, "");}}}//設置工具欄當前選中的項樣式DrawingTool.prototype._bindEventByDraingMode = function(drawingType){var drawingManager = this.drawingManager;//點在拖拽地圖的按鈕上if (drawingType == "hander") {drawingManager.close();} else {drawingManager.setDrawingMode(drawingType);drawingManager.open();}}//用來存儲用戶實例化出來的drawingmanager對象var instances = [];/** 關閉其他實例的繪制模式* @param {DrawingManager} 當前的實例*/function closeInstanceExcept(instance) {var index = instances.length;while (index--) {if (instances[index] != instance) {instances[index].close();}}}})();?
總結
以上是生活随笔為你收集整理的鼠标绘制工具加是否超出范围判断的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ISO7816 调试心得
- 下一篇: RN实现仿余额宝余额数字翻滚动画特效