320 lines
11 KiB
JavaScript
320 lines
11 KiB
JavaScript
import deviceType from './constant/deviceType';
|
|
import Eventful from 'zrender/src/mixin/Eventful';
|
|
import * as eventTool from 'zrender/src/core/event';
|
|
import store from '@/store';
|
|
|
|
class EventModel {
|
|
constructor(e) {
|
|
this.clientX = e.event.clientX;
|
|
this.clientY = e.event.clientY;
|
|
|
|
let view = e.target;
|
|
while (view) {
|
|
if (Object.values(deviceType).includes(view._type)) {
|
|
this.deviceCode = view._code;
|
|
this.deviceType = view._type;
|
|
this.eventTarget = view;
|
|
break;
|
|
}
|
|
|
|
if (view._subType) {
|
|
this.subType = view._subType;
|
|
}
|
|
if (view._val) {
|
|
this.val = view._val;
|
|
}
|
|
|
|
view = view.parent;
|
|
}
|
|
}
|
|
}
|
|
|
|
class MouseController extends Eventful {
|
|
constructor(jmap) {
|
|
super();
|
|
this.$jmap = jmap;
|
|
this.deviceList = [];
|
|
this.rightClickPoint = {
|
|
x: 0,
|
|
y: 0
|
|
}; // 右键点击坐标
|
|
this.$zr = jmap.getZr();
|
|
this.events = jmap.getEvents();
|
|
this.initHandler(this.$zr);
|
|
}
|
|
|
|
initHandler(zr) {
|
|
if (zr) {
|
|
zr.on('click', this.click, this);
|
|
zr.on('contextmenu', this.contextmenu, this);
|
|
zr.on('mousemove', this.moveEvent, this);
|
|
|
|
this.enable = function (opts) {
|
|
opts = opts || {};
|
|
this._moveOnMouseMove = opts.moveOnMouseMove || true;
|
|
this._zoomOnMouseWheel = opts.zoomOnMouseWheel || false;
|
|
this._preventDefaultMouseMove = opts.preventDefaultMouseMove || true;
|
|
|
|
this.disable();
|
|
|
|
zr.on('mousedown', this.mousedown, this);
|
|
zr.on('mousemove', this.mousemove, this);
|
|
zr.on('mouseup', this.mouseup, this);
|
|
zr.on('mousewheel', this.mousewheel, this);
|
|
};
|
|
|
|
this.disable = function () {
|
|
zr.off('mousedown', this.mousedown);
|
|
zr.off('mousemove', this.mousemove);
|
|
zr.off('mouseup', this.mouseup);
|
|
zr.off('mousewheel', this.mousewheel);
|
|
};
|
|
|
|
this.dispose = function () {
|
|
zr.off('click', this.click);
|
|
zr.off('contextmenu', this.contextmenu);
|
|
zr.off('mousemove', this.moveEvent);
|
|
this.disable();
|
|
};
|
|
|
|
this.isDragging = function () { return this._dragging; };
|
|
}
|
|
}
|
|
|
|
mousedown(e) {
|
|
// if (eventTool.notLeftMouse(e)) {
|
|
// return;
|
|
// }
|
|
if (e.which == 1 || e.which == 3) {
|
|
var x = e.offsetX;
|
|
var y = e.offsetY;
|
|
|
|
this._x = x;
|
|
this._y = y;
|
|
this._dragging = true;
|
|
if (e.which == 3 && this._zoomOnMouseWheel) {
|
|
this.handleMouseDownRight(e);
|
|
} else if (e.which == 1 && this._zoomOnMouseWheel) {
|
|
this.handleMouseDownLeft(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
mousemove(e) {
|
|
// if (eventTool.notLeftMouse(e) ||
|
|
// !this._moveOnMouseMove ||
|
|
// !this._dragging
|
|
// ) {
|
|
// return;
|
|
// }
|
|
|
|
const oldX = this._x;
|
|
const oldY = this._y;
|
|
|
|
const dx = e.offsetX - oldX;
|
|
const dy = e.offsetY - oldY;
|
|
|
|
this._x = e.offsetX;
|
|
this._y = e.offsetY;
|
|
|
|
if (e.which == 1) {
|
|
this._preventDefaultMouseMove && eventTool.stop(e.event);
|
|
|
|
this.trigger(this.events.__Pan, { dx, dy, oldX, oldY, newX: this._x, newY: this._y });
|
|
} else if (e.which === 3 && this._zoomOnMouseWheel) {
|
|
this.handleMouseMoveRight({x: e.offsetX, y: e.offsetY});
|
|
}
|
|
}
|
|
|
|
mouseup(e) {
|
|
if (!eventTool.notLeftMouse(e)) {
|
|
this._dragging = false;
|
|
}
|
|
if (this._zoomOnMouseWheel && this.$jmap.mapDevice['check_box']) {
|
|
this.eventTarget = this.$jmap.mapDevice['check_box'].instance;
|
|
this.handleBoundingRect(this.eventTarget);
|
|
var em = this.checkEvent(e);
|
|
this.trigger(this.events.Selected, em);
|
|
}
|
|
}
|
|
|
|
mousewheel(e) {
|
|
const shouldZoom = this._zoomOnMouseWheel;
|
|
const wheelDelta = e.wheelDelta;
|
|
const originX = e.offsetX;
|
|
const originY = e.offsetY;
|
|
|
|
if (wheelDelta === 0 || !shouldZoom) {
|
|
return;
|
|
}
|
|
|
|
if (shouldZoom) {
|
|
eventTool.stop(e.event);
|
|
let scale = 1;
|
|
if (wheelDelta > 0) {
|
|
scale = 1;
|
|
} else if (wheelDelta < 0) {
|
|
scale = -1;
|
|
}
|
|
|
|
this.trigger(this.events.__Zoom, {type: this.events.__Zoom, scale, originX, originY });
|
|
}
|
|
}
|
|
|
|
click(e) {
|
|
var em = this.checkEvent(e);
|
|
this.trigger(this.events.Selected, em);
|
|
}
|
|
|
|
contextmenu(e) {
|
|
var em = this.checkEvent(e);
|
|
this.trigger(this.events.Contextmenu, em);
|
|
}
|
|
|
|
moveEvent(e) {
|
|
const newEm = new EventModel(e);
|
|
const trainDetails = store.state.map.trainDetails;
|
|
if (trainDetails) {
|
|
if (newEm.deviceType != deviceType.Train || trainDetails.code != newEm.deviceCode) {
|
|
var instance = (this.$jmap.getDeviceByCode(trainDetails.code) || {} ).instance;
|
|
instance && instance.removeTrainDetail && instance.removeTrainDetail();
|
|
}
|
|
}
|
|
}
|
|
|
|
checkEvent(e) {
|
|
var oldEm = new EventModel(this.$zr.curEvent || { event: {} });
|
|
var newEm = new EventModel(e);
|
|
if ([1, 3].includes(e.which)) {
|
|
// 查找之前和当前鼠标选中的实例
|
|
var oldDevice = this.$jmap.getDeviceByCode(oldEm.deviceCode) || {};
|
|
var newDevice = this.$jmap.getDeviceByCode(newEm.deviceCode) || {};
|
|
var oldInstance = (this.$jmap.getDeviceByCode(oldEm.deviceCode) || {}).instance || {};
|
|
var newInstance = (this.$jmap.getDeviceByCode(newEm.deviceCode) || {}).instance || {};
|
|
|
|
// 如果之前和当前选中的实例不一致
|
|
if (oldInstance != newInstance) {
|
|
// 如果实例有取消选择函数并且被点击,则执行取消选中函数
|
|
if (oldInstance.mouseEvent && oldInstance.mouseEvent.mouseout) {
|
|
// 视图数据设置点击标志,同步执行
|
|
oldDevice['down'] = false;
|
|
oldInstance.mouseEvent['mouseout'](e);
|
|
}
|
|
|
|
// 如果实例有选中函数并且被点击,则执行选中函数
|
|
if (e.which == 3 && newInstance.mouseEvent && newInstance.mouseEvent.mouseover) {
|
|
newDevice['down'] = true;
|
|
newInstance.mouseEvent['mouseover'](e);
|
|
}
|
|
}
|
|
|
|
// 保存当前实例到全局
|
|
this.$zr.curEvent = e;
|
|
}
|
|
|
|
return newEm;
|
|
}
|
|
|
|
// 处理鼠标右键按下事件
|
|
handleMouseDownRight(e) {
|
|
this.rightClickPoint.x = e.offsetX;
|
|
this.rightClickPoint.y = e.offsetY;
|
|
}
|
|
// 处理鼠标左键按下事件
|
|
handleMouseDownLeft(e) {
|
|
const em = new EventModel(e);
|
|
this.eventTarget = em.eventTarget;
|
|
if (this.eventTarget && this.eventTarget._type === deviceType.CheckBox) {
|
|
this.handleBoundingRect(this.eventTarget);
|
|
} else {
|
|
this.$jmap.deleteCheckBox('check_box');
|
|
this.eventTarget = '';
|
|
this.deviceList = [];
|
|
}
|
|
}
|
|
// 通过包围盒筛选选中区域的元素
|
|
handleBoundingRect(eventTarget) {
|
|
this.deviceList = [];
|
|
const boundingRect = this.createFakeBoundingRect(eventTarget);
|
|
const deviceList = Object.values(this.$jmap.mapDevice);
|
|
const includeDeviceList = [];
|
|
deviceList.forEach( item =>{
|
|
if (item.instance && item.instance._type == deviceType.Section) {
|
|
let deviceBoundingRect = {};
|
|
if (item.type == '04') {
|
|
deviceBoundingRect = {
|
|
x1: item.namePosition.x,
|
|
y1: item.namePosition.y,
|
|
x2: item.namePosition.x,
|
|
y2: item.namePosition.y
|
|
};
|
|
} else {
|
|
deviceBoundingRect = {
|
|
x1: item.points[0].x,
|
|
y1: item.points[0].y,
|
|
x2: item.points[item.points.length - 1].x,
|
|
y2: item.points[item.points.length - 1].y
|
|
};
|
|
}
|
|
if (this.whetherInclude(boundingRect, deviceBoundingRect )) {
|
|
includeDeviceList.push(item);
|
|
}
|
|
}
|
|
if (item.instance && item.instance._type == deviceType.Switch) {
|
|
const deviceBoundingRect = {
|
|
x1: item.intersection.x,
|
|
y1: item.intersection.y,
|
|
x2: item.intersection.x,
|
|
y2: item.intersection.y
|
|
};
|
|
if (this.whetherInclude(boundingRect, deviceBoundingRect )) {
|
|
includeDeviceList.push(item);
|
|
}
|
|
}
|
|
if (item.instance && item.instance._type == deviceType.Signal) {
|
|
const deviceBoundingRect = {
|
|
x1: item.position.x,
|
|
y1: item.position.y,
|
|
x2: item.position.x,
|
|
y2: item.position.y
|
|
};
|
|
if (this.whetherInclude(boundingRect, deviceBoundingRect )) {
|
|
includeDeviceList.push(item);
|
|
}
|
|
}
|
|
});
|
|
this.deviceList = includeDeviceList;
|
|
store.dispatch('map/setSeclectDeviceList', this.deviceList);
|
|
}
|
|
// 生成包围盒对象坐标
|
|
createFakeBoundingRect(instance) {
|
|
return {
|
|
x1: instance.model.point.x,
|
|
y1: instance.model.point.y,
|
|
x2: instance.model.point.x + instance.model.width,
|
|
y2: instance.model.point.y + instance.model.height
|
|
};
|
|
}
|
|
|
|
// 判断元素包围盒是否在选中区域
|
|
whetherInclude(boundingRect1, boundingRect2) {
|
|
return boundingRect1.x1 <= boundingRect2.x1 && boundingRect1.y1 <= boundingRect2.y1 && boundingRect1.x2 >= boundingRect2.x2 && boundingRect1.y2 >= boundingRect2.y2;
|
|
}
|
|
|
|
// 右键拖动区域大小
|
|
handleMouseMoveRight(point2) {
|
|
const point1 = this.rightClickPoint;
|
|
const originX = Math.min(point1.x, point2.x);
|
|
const originY = Math.min(point1.y, point2.y);
|
|
const dx = originX + this.$jmap.$options.offsetX;
|
|
const dy = originY + this.$jmap.$options.offsetY;
|
|
const x = dx / this.$jmap.$options.scaleRate;
|
|
const y = dy / this.$jmap.$options.scaleRate;
|
|
const width = Math.abs(point1.x - point2.x) / this.$jmap.$options.scaleRate + 10;
|
|
const height = Math.abs(point1.y - point2.y) / this.$jmap.$options.scaleRate + 10;
|
|
this.$jmap.renderCheckBox({code: 'check_box', _type: 'CheckBox', point: {x: x, y: y}, width: width, height: height });
|
|
}
|
|
}
|
|
|
|
export default MouseController;
|