import deviceType from './constant/deviceType'; import Eventful from 'zrender/src/mixin/Eventful'; import * as eventTool from 'zrender/src/core/event'; import store from '@/store/index_APP_TARGET'; 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._previewOrMapDraw = opts.previewOrMapDraw || false; 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; // } this.$zr.dom.focus(); 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._previewOrMapDraw) { 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._previewOrMapDraw ) { 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); // console.log(em, 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; // 获取当前拿到train详情 对比 移除 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.commit('map/setSeclectDeviceList', this.deviceList); // 给store设置框选的 model } // 生成包围盒对象坐标 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; const height = Math.abs(point1.y - point2.y) / this.$jmap.$options.scaleRate; this.$jmap.renderCheckBox({code: 'check_box', _type: 'CheckBox', point: {x: x, y: y}, width: width, height: height }); } } export default MouseController;