添加ibp局部选中拖拽

This commit is contained in:
fan 2019-11-07 16:42:56 +08:00
parent 4e1ee242a5
commit d3e1086596
7 changed files with 434 additions and 267 deletions

View File

@ -4,107 +4,113 @@ const deviceRender = {};
/** IbpText渲染配置*/
deviceRender[deviceType.IbpText] = {
_type: deviceType.IbpText,
zlevel: 1,
z: 4
_type: deviceType.IbpText,
zlevel: 1,
z: 4
};
/** SquareButton渲染配置*/
deviceRender[deviceType.SquareButton] = {
_type: deviceType.SquareButton,
zlevel: 1,
z: 4
_type: deviceType.SquareButton,
zlevel: 1,
z: 4
};
/** WarnButton渲染配置*/
deviceRender[deviceType.WarnButton] = {
_type: deviceType.WarnButton,
zlevel: 1,
z: 4
_type: deviceType.WarnButton,
zlevel: 1,
z: 4
};
/** Arrow渲染配置*/
deviceRender[deviceType.Arrow] = {
_type: deviceType.Arrow,
zlevel: 1,
z: 2
_type: deviceType.Arrow,
zlevel: 1,
z: 2
};
/** TipBox渲染配置*/
deviceRender[deviceType.TipBox] = {
_type: deviceType.TipBox,
zlevel: 1,
z: 3
_type: deviceType.TipBox,
zlevel: 1,
z: 3
};
/** BackGround渲染配置*/
deviceRender[deviceType.Background] = {
_type: deviceType.Background,
zlevel: 1,
z: 0
_type: deviceType.Background,
zlevel: 1,
z: 0
};
/** CircularLamp渲染配置 */
deviceRender[deviceType.CircularLamp] = {
_type: deviceType.CircularLamp,
zlevel: 1,
z: 4
_type: deviceType.CircularLamp,
zlevel: 1,
z: 4
};
/** AppendageBox渲染配置 */
deviceRender[deviceType.AppendageBox] = {
_type: deviceType.AppendageBox,
zlevel: 1,
z: 1
_type: deviceType.AppendageBox,
zlevel: 1,
z: 1
};
/** IbpLine渲染配置 */
deviceRender[deviceType.IbpLine] = {
_type: deviceType.IbpLine,
zlevel: 1,
z: 1
_type: deviceType.IbpLine,
zlevel: 1,
z: 1
};
/** Elevator 渲染配置 */
deviceRender[deviceType.Elevator] = {
_type: deviceType.Elevator,
zlevel: 1,
z: 2
_type: deviceType.Elevator,
zlevel: 1,
z: 2
};
/** Key 渲染配置 */
deviceRender[deviceType.Key] = {
_type: deviceType.Key,
zlevel: 1,
z: 4
_type: deviceType.Key,
zlevel: 1,
z: 4
};
/** TeleTerminal 渲染配置 */
deviceRender[deviceType.TeleTerminal] = {
_type: deviceType.TeleTerminal,
zlevel: 1,
z: 4
_type: deviceType.TeleTerminal,
zlevel: 1,
z: 4
};
/** Clock 渲染配置*/
deviceRender[deviceType.Clock] = {
_type: deviceType.Clock,
zlevel: 1,
z: 4
_type: deviceType.Clock,
zlevel: 1,
z: 4
};
/** RotateTip 渲染配置 */
deviceRender[deviceType.RotateTip] = {
_type: deviceType.RotateTip,
zlevel: 1,
z: 4
_type: deviceType.RotateTip,
zlevel: 1,
z: 4
};
/** Alarm */
deviceRender[deviceType.Alarm] = {
_type: deviceType.Alarm,
zlevel: 1,
z: 4
_type: deviceType.Alarm,
zlevel: 1,
z: 4
};
deviceRender[deviceType.CheckBox] = {
_type: deviceType.CheckBox,
zlevel: 10,
z: 0
};
export default deviceRender;

View File

@ -1,18 +1,19 @@
const deviceType = {
IbpText: 'IbpText',
SquareButton: 'SquareButton',
Arrow: 'Arrow',
TipBox: 'TipBox',
Background: 'Background',
CircularLamp: 'CircularLamp',
IbpLine: 'IbpLine',
AppendageBox: 'AppendageBox',
Alarm: 'Alarm',
Elevator: 'Elevator',
Key: 'Key',
TeleTerminal: 'TeleTerminal',
Clock: 'Clock',
RotateTip: 'RotateTip'
IbpText: 'IbpText',
SquareButton: 'SquareButton',
Arrow: 'Arrow',
TipBox: 'TipBox',
Background: 'Background',
CircularLamp: 'CircularLamp',
IbpLine: 'IbpLine',
AppendageBox: 'AppendageBox',
Alarm: 'Alarm',
Elevator: 'Elevator',
Key: 'Key',
TeleTerminal: 'TeleTerminal',
Clock: 'Clock',
RotateTip: 'RotateTip',
CheckBox: 'CheckBox'
};
export default deviceType;

View File

@ -303,5 +303,25 @@ class IbpPan {
}
}
}
renderCheckBox(model) {
const type = model._type;
const code = model.code;
const oDevice = this.ibpDevice[code] || deviceFactory(type, model);
const nDevice = deviceFactory(type, Object.assign(oDevice.model || {}, model));
delete this.ibpDevice[code];
this.$painter.delete(oDevice);
if (!model._dispose) {
this.ibpDevice[code] = nDevice;
this.$painter.add(nDevice);
}
}
deleteCheckBox(code) {
const oDevice = this.ibpDevice[code];
if (oDevice) {
delete this.ibpDevice[code];
this.$painter.delete(oDevice);
}
}
}
export default IbpPan;

View File

@ -4,193 +4,284 @@ 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;
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.deviceModel = view.model;
this.eventTarget = view;
break;
}
view = view.parent;
}
}
let view = e.target;
while (view) {
if (Object.values(deviceType).includes(view._type)) {
this.deviceCode = view._code;
this.deviceType = view._type;
this.deviceModel = view.model;
this.eventTarget = view;
break;
}
view = view.parent;
}
}
}
class MouseController extends Eventful {
constructor(ibp) {
super();
this.$ibp = ibp;
this.$zr = ibp.getZr();
this.isAllowDragging=ibp.isAllowDragging||false;
this.events = ibp.getEvents();
this._dragging = false;
this.initHandler(this.$zr);
}
constructor(ibp) {
super();
this.$ibp = ibp;
this.$zr = ibp.getZr();
this.isAllowDragging = ibp.isAllowDragging || false; // 是否在绘图中,仅绘图状态下可拖拽
this.events = ibp.getEvents();
this._dragging = false; // 是否在拖拽状态
this.deviceList = [];
this.rightClickPoint = {
x: 0,
y: 0
}; // 右键点击坐标
this.initHandler(this.$zr);
}
initHandler(zr) {
if (zr) {
zr.on('contextmenu', this.contextmenu, this);
zr.on('mousemove', this.moveEvent, this);
zr.on('click', this.click, this);
initHandler(zr) {
if (zr) {
zr.on('contextmenu', this.contextmenu, this);
zr.on('mousemove', this.moveEvent, this);
zr.on('click', this.click, this);
this.enable = function (opts) {
opts = opts || {};
this._moveOnMouseMove = opts.moveOnMouseMove || true;
this._preventDefaultMouseMove = opts.preventDefaultMouseMove || true;
this.enable = function (opts) {
opts = opts || {};
this._moveOnMouseMove = opts.moveOnMouseMove || true;
this._preventDefaultMouseMove = opts.preventDefaultMouseMove || true;
this.disable();
this.disable();
zr.on('mousedown', this.mousedown, this);
zr.on('mousemove', this.mousemove, this);
zr.on('mouseup', this.mouseup, this);
zr.on('touchstart', this.mousedown, this);
zr.on('touchmove', this.mousemove, this);
zr.on('touchend', this.mouseup, this);
};
zr.on('mousedown', this.mousedown, this);
zr.on('mousemove', this.mousemove, this);
zr.on('mouseup', this.mouseup, this);
zr.on('touchstart', this.mousedown, this);
zr.on('touchmove', this.mousemove, this);
zr.on('touchend', this.mouseup, this);
};
this.disable = function () {
zr.off('mousedown', this.mousedown);
zr.off('mousemove', this.mousemove);
zr.off('mouseup', this.mouseup);
zr.off('touchstart', this.mousedown);
zr.off('touchmove', this.mousemove);
zr.off('touchend', this.mouseup);
};
this.disable = function () {
zr.off('mousedown', this.mousedown);
zr.off('mousemove', this.mousemove);
zr.off('mouseup', this.mouseup);
zr.off('touchstart', this.mousedown);
zr.off('touchmove', this.mousemove);
zr.off('touchend', this.mouseup);
};
this.dispose = function () {
zr.off('click', this.click);
zr.off('contextmenu', this.contextmenu);
zr.off('mousemove', this.moveEvent);
this.disable();
};
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; };
}
}
this.isDragging = function () { return this._dragging; };
}
}
setAllowDragging(data) {
this.isAllowDragging=data;
}
setAllowDragging(data) {
this.isAllowDragging = data;
}
mousedown(e) {
if (eventTool.notLeftMouse(e)) {
return;
}
e.event.preventDefault();
e.event.stopPropagation();
const em = new EventModel(e);
this.eventTarget = em.eventTarget;
if (this.eventTarget && this.eventTarget._type === deviceType.Background) {
this.eventTarget.setCursor('pointer');
}
this._offsetX=e.offsetX;
this._offsetY=e.offsetY;
this._x = e.offsetX;
this._y = e.offsetY;
this._dragging = true;
}
mousedown(e) {
e.event.preventDefault();
e.event.stopPropagation();
const em = new EventModel(e);
this.eventTarget = em.eventTarget;
this._offsetX = e.offsetX;
this._offsetY = e.offsetY;
this._x = e.offsetX;
this._y = e.offsetY;
this._dragging = true;
if (e.which === 3) {
this.handleMouseDownRight(e);
} else if (e.which === 1) {
this.handleMouseDownLeft(e);
} else if (e.which === 2) {
this.handleMouseDownWheel(e);
}
}
mousemove(e) {
if (eventTool.notLeftMouse(e) ||
!this._moveOnMouseMove ||
!this._dragging || !this.isAllowDragging
) {
return;
}
mousemove(e) {
const oldX = this._x;
const oldY = this._y;
const oldX = this._x;
const oldY = this._y;
const dx = e.offsetX - oldX;
const dy = e.offsetY - oldY;
const dx = e.offsetX - oldX;
const dy = e.offsetY - oldY;
this._x = e.offsetX;
this._y = e.offsetY;
if (e.which === 3) {
this.handleMouseMoveRight({x: e.offsetX, y: e.offsetY});
} else if (e.which === 1) {
this.handleMouseMoveLeft(e, dx, dy, oldX, oldY);
}
}
this._x = e.offsetX;
this._y = e.offsetY;
if (this._dragging) {
if ((this.eventTarget && this.eventTarget._type === deviceType.Background) || !this.isAllowDragging) {
this._preventDefaultMouseMove && eventTool.stop(e.event);
this.trigger(this.events.__Pan, { dx, dy, oldX, oldY, newX: this._x, newY: this._y });
return true;
} else if (this.isAllowDragging && this.eventTarget) {
this.eventTarget.grouper.drift(dx, dy, e);
}
} else {
return true;
}
mouseup(e) {
if (eventTool.notLeftMouse(e) || !this.eventTarget ) {
return;
}
if (this.deviceList.length) {
this.deviceList.forEach(item => {
item.setModel(e.offsetX - this._offsetX, e.offsetY - this._offsetY);
});
this.deviceList = [];
this.$ibp.deleteCheckBox('check_box');
this.eventTarget = '';
this._dragging = false;
this.deviceList = [];
return;
}
if (this.isAllowDragging) {
this.eventTarget.setModel(e.offsetX - this._offsetX, e.offsetY - this._offsetY);
this.eventTarget.dirty();
}
if (this.eventTarget._type === deviceType.Background) {
this.eventTarget.setCursor('default');
}
this.eventTarget = '';
this._dragging = false;
this.deviceList = [];
}
}
contextmenu(e) {
var em = this.checkEvent(e);
this.trigger(this.events.Contextmenu, em);
}
click(e) {
var em = this.checkEvent(e);
this.trigger(this.events.Selected, 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.$ibp.getDeviceByCode(trainDetails.code) || {} ).instance;
instance && instance.removeTrainDetail && instance.removeTrainDetail();
}
}
}
mouseup(e) {
if (!eventTool.notLeftMouse(e)&&this.isAllowDragging && this.eventTarget) {
this.eventTarget.setModel(e.offsetX - this._offsetX, e.offsetY - this._offsetY);
this.eventTarget.dirty();
}
// debugger;
if (this.eventTarget && this.eventTarget._type === deviceType.Background) {
// console.log('111-------');
this.eventTarget.setCursor('default');
}
this.eventTarget = '';
this._dragging = false;
}
checkEvent(e) {
var oldEm = new EventModel(this.$zr.curEvent || { event: {} });
var newEm = new EventModel(e);
if ([1, 3].includes(e.which)) {
// 查找之前和当前鼠标选中的实例
var oldDevice = this.$ibp.getDeviceByCode(oldEm.deviceCode) || {};
var newDevice = this.$ibp.getDeviceByCode(newEm.deviceCode) || {};
var oldInstance = (this.$ibp.getDeviceByCode(oldEm.deviceCode) || {}).instance || {};
var newInstance = (this.$ibp.getDeviceByCode(newEm.deviceCode) || {}).instance || {};
contextmenu(e) {
var em = this.checkEvent(e);
this.trigger(this.events.Contextmenu, em);
}
click(e) {
var em = this.checkEvent(e);
this.trigger(this.events.Selected, 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.$ibp.getDeviceByCode(trainDetails.code) || {} ).instance;
instance && instance.removeTrainDetail && instance.removeTrainDetail();
}
}
}
// 如果之前和当前选中的实例不一致
if (oldInstance != newInstance) {
// 如果实例有取消选择函数并且被点击,则执行取消选中函数
if (oldInstance.mouseEvent && oldInstance.mouseEvent.mouseout) {
// 视图数据设置点击标志,同步执行
oldDevice['down'] = false;
oldInstance.mouseEvent['mouseout'](e);
}
checkEvent(e) {
var oldEm = new EventModel(this.$zr.curEvent || { event: {} });
var newEm = new EventModel(e);
if ([1, 3].includes(e.which)) {
// 查找之前和当前鼠标选中的实例
var oldDevice = this.$ibp.getDeviceByCode(oldEm.deviceCode) || {};
var newDevice = this.$ibp.getDeviceByCode(newEm.deviceCode) || {};
var oldInstance = (this.$ibp.getDeviceByCode(oldEm.deviceCode) || {}).instance || {};
var newInstance = (this.$ibp.getDeviceByCode(newEm.deviceCode) || {}).instance || {};
// 如果实例有选中函数并且被点击,则执行选中函数
if (e.which == 3 && newInstance.mouseEvent && newInstance.mouseEvent.mouseover) {
newDevice['down'] = true;
newInstance.mouseEvent['mouseover'](e);
}
}
// 如果之前和当前选中的实例不一致
if (oldInstance != newInstance) {
// 如果实例有取消选择函数并且被点击,则执行取消选中函数
if (oldInstance.mouseEvent && oldInstance.mouseEvent.mouseout) {
// 视图数据设置点击标志,同步执行
oldDevice['down'] = false;
oldInstance.mouseEvent['mouseout'](e);
}
// 保存当前实例到全局
this.$zr.curEvent = e;
}
// 如果实例有选中函数并且被点击,则执行选中函数
if (e.which == 3 && newInstance.mouseEvent && newInstance.mouseEvent.mouseover) {
newDevice['down'] = true;
newInstance.mouseEvent['mouseover'](e);
}
}
// 保存当前实例到全局
this.$zr.curEvent = e;
}
return newEm;
}
return newEm;
}
/** 处理鼠标右键按下事件 */
handleMouseDownRight(e) {
this.rightClickPoint.x = e.offsetX;
this.rightClickPoint.y = e.offsetY;
}
/** 处理鼠标左键按下事件 */
handleMouseDownLeft(e) {
if (this.eventTarget && this.eventTarget._type === deviceType.Background) {
this.eventTarget.setCursor('pointer');
this.$ibp.deleteCheckBox('check_box');
} else if (this.eventTarget && this.eventTarget._type === deviceType.CheckBox) {
this.handleBoundingRect(this.eventTarget);
} else {
this.$ibp.deleteCheckBox('check_box');
}
}
/** 处理滚轮按下事件 */
handleMouseDownWheel(e) {
this.deviceList = [];
Object.values(this.$ibp.ibpDevice).forEach(item => {
if (item.instance._type !== deviceType.Background) {
this.deviceList.push(item.instance);
}
});
}
/** 处理右键拖动事件--- 改变选中区域大小 */
handleMouseMoveRight(point2) {
const point1 = this.rightClickPoint;
const x = Math.min(point1.x, point2.x) + this.$ibp.$options.offsetX;
const y = Math.min(point1.y, point2.y) + this.$ibp.$options.offsetY;
const width = Math.abs(point1.x - point2.x);
const height = Math.abs(point1.y - point2.y);
this.$ibp.renderCheckBox({code: 'check_box', _type: 'CheckBox', point: {x: x, y: y}, width: width, height: height });
}
/** 处理左键拖动事件--- 图形移动 */
handleMouseMoveLeft(e, dx, dy, oldX, oldY) {
if (!this._moveOnMouseMove || !this._dragging || !this.isAllowDragging) {
return;
}
if (this.deviceList.length) {
this.deviceList.forEach(item => {
item.grouper.drift(dx, dy, e);
});
return;
}
if (this._dragging) {
if ((this.eventTarget && this.eventTarget._type === deviceType.Background) || !this.isAllowDragging) {
this._preventDefaultMouseMove && eventTool.stop(e.event);
this.trigger(this.events.__Pan, { dx, dy, oldX, oldY, newX: this._x, newY: this._y });
return true;
} else if (this.isAllowDragging && this.eventTarget) {
this.eventTarget.grouper.drift(dx, dy, e);
}
}
}
/** 通过包围盒筛选选中区域的元素 */
handleBoundingRect(eventTarget) {
this.deviceList = [];
let boundingRect = eventTarget.grouper.getBoundingRect();
boundingRect = this.createFakeBoundingRect(eventTarget, boundingRect);
const deviceList = Object.values(this.$ibp.ibpDevice);
const includeDeviceList = [];
deviceList.forEach( item =>{
if (item.instance._type !== deviceType.Background) {
let deviceBoundingRect = item.instance.grouper.getBoundingRect();
deviceBoundingRect = this.createFakeBoundingRect(item.instance, deviceBoundingRect);
if (this.whetherInclude(boundingRect, deviceBoundingRect )) {
includeDeviceList.push(item.instance);
}
}
});
this.deviceList = includeDeviceList;
}
/** 创建假包围盒对象 */
createFakeBoundingRect(instance, boundingRect) {
return {
x1: instance.model.point.x + boundingRect.x,
y1: instance.model.point.y + boundingRect.y,
x2: instance.model.point.x + boundingRect.width,
y2: instance.model.point.y + boundingRect.height
};
}
/** 判断元素包围盒是否在选中区域 */
whetherInclude(boundingRect1, boundingRect2) {
return boundingRect1.x1 <= boundingRect2.x1 && boundingRect1.y1 <= boundingRect2.y1 && boundingRect1.x2 >= boundingRect2.x2 && boundingRect1.y2 >= boundingRect2.y2;
}
}
export default MouseController;

46
src/ibp/shape/checkBox.js Normal file
View File

@ -0,0 +1,46 @@
import Group from 'zrender/src/container/Group';
import Rect from 'zrender/src/graphic/shape/Rect';
export default class checkBox extends Group {
constructor(device) {
super();
this.model = device.model;
this._type = device.model._type;
this._code = device.model.code;
this.zlevel = device.model.zlevel;
this.z = device.model.z;
this.create();
}
create() {
const model = this.model;
this.grouper = new Group({
id: model.code,
position: [model.point.x, model.point.y]
});
this.box = new Rect({
zlevel: model.zlevel,
z: model.z,
draggable: false,
shape: {
x: 0,
y: 0,
width: this.model.width,
height: this.model.height
},
style: {
fill: 'rgb(135,206,250,0.2)'
}
});
this.grouper.add(this.box);
this.add(this.grouper);
}
setModel(dx, dy) {
this.model.point.x += dx;
this.model.point.y += dy;
}
setSize(width, height) {
this.model.width = width;
this.model.height = height;
}
}

View File

@ -13,6 +13,7 @@ import Key from './key';
import TeleTerminal from './teleTerminal';
import Clock from './clock';
import RotateTip from './rotateTip';
import CheckBox from './checkBox';
const ibpShape = {};
ibpShape[deviceType.Arrow] = Arrow;
@ -29,14 +30,15 @@ ibpShape[deviceType.Key] = Key;
ibpShape[deviceType.TeleTerminal] = TeleTerminal;
ibpShape[deviceType.Clock] = Clock;
ibpShape[deviceType.RotateTip] = RotateTip;
ibpShape[deviceType.CheckBox] = CheckBox;
function shapefactory(device, ibp) {
const type = device.model._type;
const shape = ibpShape[type];
if (shape instanceof Function) {
// eslint-disable-next-line
const type = device.model._type;
const shape = ibpShape[type];
if (shape instanceof Function) {
// eslint-disable-next-line
return new shape(device, ibp.style);
}
}
}
export default shapefactory;

View File

@ -2,43 +2,44 @@ import Group from 'zrender/src/container/Group';
import Line from 'zrender/src/graphic/shape/Line';
export default class ibpLine extends Group {
constructor(device) {
super();
this.model = device.model;
this._type = device.model._type;
this._code = device.model.code;
this.zlevel = device.model.zlevel;
this.z = device.model.z;
this.create();
}
create() {
const model = this.model;
this.grouper=new Group({
id: model.code,
position: [model.point1.x, model.point1.y]
});
this.ibpLine = new Line({
zlevel: model.zlevel,
z: model.z,
draggable: false,
shape: {
x1: 0,
y1: 0,
x2: model.point2.x-model.point1.x,
y2: model.point2.y-model.point1.y
},
style: {
lineWidth: this.model.lineWidth,
stroke: this.model.fillColor
}
});
this.grouper.add(this.ibpLine);
this.add(this.grouper);
}
setModel(dx, dy) {
this.model.point1.x += dx;
this.model.point1.y += dy;
this.model.point2.x += dx;
this.model.point2.y += dy;
}
constructor(device) {
super();
this.model = device.model;
this._type = device.model._type;
this._code = device.model.code;
this.zlevel = device.model.zlevel;
this.model.point = this.model.point1;
this.z = device.model.z;
this.create();
}
create() {
const model = this.model;
this.grouper = new Group({
id: model.code,
position: [model.point1.x, model.point1.y]
});
this.ibpLine = new Line({
zlevel: model.zlevel,
z: model.z,
draggable: false,
shape: {
x1: 0,
y1: 0,
x2: model.point2.x - model.point1.x,
y2: model.point2.y - model.point1.y
},
style: {
lineWidth: this.model.lineWidth,
stroke: this.model.fillColor
}
});
this.grouper.add(this.ibpLine);
this.add(this.grouper);
}
setModel(dx, dy) {
this.model.point1.x += dx;
this.model.point1.y += dy;
this.model.point2.x += dx;
this.model.point2.y += dy;
}
}