UNPKG

@orca-fe/x-map

Version:
208 lines (207 loc) 8.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const events_1 = require("events"); const turf_1 = require("@turf/turf"); class DrawState { constructor(options) { this.events = new events_1.EventEmitter(); // 内置状态 // 正在绘画 this.drawMode = false; this.drawing = false; this.mousedownXY = [-1, -1]; this.mousedownPosition = [-999, -999]; this.currentPosition = [-999, -999]; this.positionArr = []; this.multiPositionArr = []; this.mousedown = false; this.onMouseDown = (e) => { this.mousedown = true; this.mousedownXY = this.getXY(e); if (this.drawMode && !this.drawing) { if (e.button === 0) { // 左键 this.mousedownPosition = this.options.pixelToLnglat(this.mousedownXY); this.currentPosition = this.mousedownPosition; this.positionArr = []; this.multiPositionArr = []; this.drawing = true; this.events.emit('draw-start'); } else if (e.button === 2) { // 右键 e.preventDefault(); } } else { // 未开始绘画 } }; this.onMouseMove = (e) => { if (this.drawing) { this.currentPosition = this.options.pixelToLnglat(this.getXY(e)); this.events.emit('state-change'); } }; this.onMouseUp = (e) => { const xy = this.getXY(e); const distance2 = Math.pow((this.mousedownXY[0] - xy[0]), 2) + Math.pow((this.mousedownXY[1] - xy[1]), 2); console.log(distance2); if (distance2 > 4) { // 移动距离过长,忽略本次抬起 return; } if (this.drawing && this.mousedown) { if (e.button === 0) { switch (this.drawMode) { case 'point': case 'line': case 'rect': case 'circle': this.events.emit('state-change'); this.events.emit('draw-finish'); this.drawing = false; break; case 'polyline': case 'polygon': case 'multi-polygon': { if (this.positionArr.length === 0) this.positionArr.push(this.mousedownPosition); const lastPosition = this.positionArr[this.positionArr.length - 1]; if (lastPosition[0] !== this.currentPosition[0] || lastPosition[1] !== this.currentPosition[1]) { // 加入一个点 this.positionArr.push(this.currentPosition); } this.events.emit('state-change'); break; } } } else if (e.button === 2) { // 右键 cancel this.cancel(); } } this.mousedown = false; }; this.onDoubleClick = () => { if (this.drawMode && this.drawing) { switch (this.drawMode) { case 'polygon': case 'polyline': // 结束多边形绘制 if (this.positionArr.length > 2 || this.drawMode === 'polyline' && this.positionArr.length > 1) { this.drawing = false; this.events.emit('state-change'); this.events.emit('draw-finish'); } else { this.cancel(); } break; case 'multi-polygon': // 多重多边形,不结束,仅增加一项 if (this.positionArr.length > 2) { this.multiPositionArr = this.multiPositionArr.concat([this.positionArr]); } this.positionArr = []; this.events.emit('state-change'); break; } } }; this.options = options; this.registerEvents(); } // 根据鼠标事件,获取当前鼠标相对 dom 的位置 getXY(e) { const { dom } = this.options; const { top, left } = dom.getBoundingClientRect(); return [e.clientX - left, e.clientY - top]; } registerEvents() { const { dom } = this.options; dom.addEventListener('mousedown', this.onMouseDown); dom.addEventListener('mousemove', this.onMouseMove); dom.addEventListener('mouseup', this.onMouseUp); dom.addEventListener('dblclick', this.onDoubleClick); } destroy() { const { dom } = this.options; dom.removeEventListener('mousedown', this.onMouseDown); dom.removeEventListener('mousemove', this.onMouseMove); dom.removeEventListener('mouseup', this.onMouseUp); dom.removeEventListener('dblclick', this.onDoubleClick); } begin(type) { this.drawMode = type; } stop() { if (this.drawing) { this.cancel(); } this.drawMode = false; } cancel() { this.drawing = false; this.events.emit('draw-cancel'); } on(eventName, callback) { this.events.on(eventName, callback); } off(eventName, callback) { this.events.off(eventName, callback); } getGeoJson() { if (this.drawMode) { switch (this.drawMode) { case 'point': return { type: 'Point', coordinates: this.currentPosition, }; case 'line': return { type: 'LineString', coordinates: [this.mousedownPosition, this.currentPosition], }; case 'polyline': return { type: 'LineString', coordinates: this.positionArr, }; case 'rect': return { type: 'Polygon', coordinates: [ [ this.mousedownPosition, [this.mousedownPosition[0], this.currentPosition[1]], this.currentPosition, [this.currentPosition[0], this.mousedownPosition[1]], ], ], }; case 'polygon': return { type: 'Polygon', coordinates: [this.positionArr.concat(this.drawing ? [this.currentPosition] : [])], }; case 'multi-polygon': return { type: 'MultiPolygon', coordinates: this.multiPositionArr.map(path => [path]), }; case 'circle': { const centerPoint = (0, turf_1.point)(this.mousedownPosition); const edgePosition = (0, turf_1.point)(this.currentPosition); const radius = (0, turf_1.rhumbDistance)(centerPoint, edgePosition); return (0, turf_1.circle)(centerPoint, radius).geometry; } } } return null; } } exports.default = DrawState;