@orca-fe/x-map
Version:
208 lines (207 loc) • 8.36 kB
JavaScript
"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;