import Load from './Load' import { stateService } from './Service/StateService' import { elementService } from './Service/ElementService' import { floorplanService } from './Service/FloorplanService' import { tagService } from './Service/TagService' import { historyService } from './Service/HistoryService' import UIControl from './Controls/UIControl' import { moveComponent } from './Controls/MoveComponent' import { moveTag } from './Controls/MoveTag' import { addWall } from './Controls/AddWall' import { moveWall } from './Controls/MoveWall' import { coordinate } from './Coordinate' import Render from './Renderer/Render' import { draw } from './Renderer/Draw' import { listenLayer } from './ListenLayer' import { floorplanData } from './FloorplanData' import LayerEvents from './enum/LayerEvents.js' import UIEvents from './enum/UIEvents.js' import SelectState from './enum/SelectState.js' import Constant from './Constant' import VectorType from './enum/VectorType' import { mathUtil } from './MathUtil' import { wallService } from './Service/WallService' import { componentService } from './Service/ComponentService' import History from './History/History' import { compassService } from './Service/CompassService' import { furnitureService } from './Service/FurnitureService' export default class Layer { constructor() { //super() this.load = new Load(this) this.uiControl = new UIControl(this) this.renderer = new Render(this) this.history = new History(this) this.canvas = null; this.startX = null this.startY = null } //开始 start(canvas,vectorData) { coordinate.init(canvas) this.canvas = canvas; this.load.load(vectorData); this.bindEvents() } bindEvents() { this.canvas.addEventListener('contextmenu', function (e) { e.preventDefault() }) this.canvas.addEventListener('mousedown', this.onMouseDown.bind(this)) this.canvas.addEventListener('mousemove', this.onMouseMove.bind(this)) this.canvas.addEventListener('mouseup', this.onMouseUp.bind(this)) this.canvas.addEventListener('mousewheel', this.onWheel.bind(this)) this.canvas.addEventListener('DOMMouseScroll', this.onWheel.bind(this)) } onMouseDown(e) { this.startX = e.offsetX || e.layerX this.startY = e.offsetY || e.layerY this.lastX = e.offsetX || e.layerX this.lastY = e.offsetY || e.layerY // 右键 if (e.button == 2) { this.stopAddVector() this.uiControl.currentUI = null this.renderer.autoRedraw() return } const eventName = stateService.getEventName() //点击第一次 if (eventName == LayerEvents.AddWall) { let flag = this.setNewWallPoint('start', { x: this.startX, y: this.startY, }) if (!flag) { return } } //点击第二次 else if (eventName == LayerEvents.AddingWall) { let flag = this.setNewWallPoint('end', { x: this.startX, y: this.startY, }) if (!flag) { return } if (addWall.canAdd) { addWall.buildWall(this.uiControl.selectUI == UIEvents.OutWall) this.history.save() } else { return } } else { const selectItem = stateService.getSelectItem() if (eventName == null && selectItem) { stateService.setDraggingItem(selectItem) stateService.setFocusItem(selectItem) this.uiControl.showAttributes() this.uiControl.currentUI = selectItem.type } else if (eventName == null) { this.uiControl.currentUI = null } } this.setEventName('mouseDown') // 清除上一个状态 // 设置当前事件名称 e.preventDefault() e.stopPropagation() } onMouseMove(e) { const X = e.offsetX || e.layerX const Y = e.offsetY || e.layerY let dx = X - this.lastX let dy = Y - this.lastY let position = coordinate.getXYFromScreen({ x: X, y: Y, }) const eventName = stateService.getEventName() // 是否需要重绘 let needAutoRedraw = false const draggingItem = stateService.getDraggingItem() switch (eventName) { case null: //监控 needAutoRedraw = listenLayer.start(position) break case LayerEvents.PanBackGround: stateService.clearItems() coordinate.center.x = coordinate.center.x - (dx * Constant.defaultZoom) / coordinate.zoom / coordinate.res coordinate.center.y = coordinate.center.y + (dy * Constant.defaultZoom) / coordinate.zoom / coordinate.res this.lastX = X this.lastY = Y needAutoRedraw = true break case LayerEvents.AddWall: stateService.clearDraggingItem() stateService.clearFocusItem() needAutoRedraw = true listenLayer.start(position) if (listenLayer.modifyPoint) { position = { x: listenLayer.modifyPoint.x, y: listenLayer.modifyPoint.y, } } elementService.execute(null, position) elementService.setStartAddWall(position) elementService.showStartAddWall() break case LayerEvents.AddingWall: stateService.clearDraggingItem() stateService.clearFocusItem() needAutoRedraw = true listenLayer.start(position) let startPosition = { x: addWall.startInfo.position.x, y: addWall.startInfo.position.y, } if (listenLayer.modifyPoint) { position = { x: listenLayer.modifyPoint.x, y: listenLayer.modifyPoint.y, } } elementService.execute(startPosition, position) elementService.setStartAddWall(position) if (!elementService.newWall.display) { elementService.setNewWall(startPosition, position) elementService.showNewWall() //画墙 } else { if (!listenLayer.modifyPoint && addWall.startInfo.linkedPointId) { let newEndPosition = elementService.checkAngle(position, addWall.startInfo.linkedPointId, null) if (newEndPosition) { mathUtil.clonePoint(position, newEndPosition) } } elementService.setNewWallEndPosition(position) //改变end位置 } addWall.canAdd = addWall.canAddWallForEnd(position) if (!addWall.canAdd) { elementService.setNewWallState('error') } else { if (this.uiControl.selectUI == UIEvents.OutWall) { elementService.setNewWallState('normal-out') } else { elementService.setNewWallState('normal') } } break case LayerEvents.MoveWall: dx = (dx * Constant.defaultZoom) / coordinate.zoom dy = (dy * Constant.defaultZoom) / coordinate.zoom // 1表示可以继续移动,2表示不能移动(启动距离还不够),3表示wallId被删除了,4表示重新开始移动(需要达到一定距离才能启动),5表示不能移动(不合适) let moveFlag = moveWall.moveWallPlane(draggingItem.vectorId, dx, dy) // 启动的时候需要点距离,所以真正移动了才更新lastX和lastY if (moveFlag == 1) { this.lastX = X this.lastY = Y needAutoRedraw = true } // 需要继续保持移动,一般是距离不够启动 else if (moveFlag == 2) { } // wallId被删除了 else if (moveFlag == 3) { this.history.save() stateService.clearSelectItem() stateService.clearDraggingItem() stateService.clearEventName() listenLayer.clear() needAutoRedraw = true } // wallId有一端被吸附了,这时候需要重新启动 else if (moveFlag == 4) { this.lastX = X this.lastY = Y this.startX = X this.startY = Y needAutoRedraw = true } else if (moveFlag == 5) { this.lastX = X this.lastY = Y } break case LayerEvents.MoveWallPoint: let point = floorplanService.getPoint(draggingItem.vectorId) listenLayer.start(position, draggingItem.vectorId, point.parent) if (listenLayer.modifyPoint) { position = { x: listenLayer.modifyPoint.x, y: listenLayer.modifyPoint.y, } } elementService.execute(null, position) let flag = moveWall.movePoint(draggingItem.vectorId, position, listenLayer.modifyPoint) if (!flag) { elementService.hideAll() } needAutoRedraw = true break case LayerEvents.AddComponent: needAutoRedraw = true if (draggingItem == null) { const componentType = this.uiControl.getComponentTypeForUI() const component = componentService.createComponent(position, componentType) if (component.vectorId) { stateService.setSelectItem(component.vectorId, componentType, SelectState.All) stateService.setDraggingItem(stateService.selectItem) } } else { let flag = moveComponent.moveFullComponent(position, draggingItem.vectorId) if (flag) { this.lastX = X this.lastY = Y this.startX = X this.startY = Y } } break case LayerEvents.MoveComponent: needAutoRedraw = true if (draggingItem != null && componentService.isComponent(draggingItem.type)) { let flag = moveComponent.moveFullComponent(position, draggingItem.vectorId) if (flag) { this.lastX = X this.lastY = Y this.startX = X this.startY = Y } } break case LayerEvents.AddTag: needAutoRedraw = true if (draggingItem == null) { const tag = tagService.createTag(position) if (tag.vectorId) { stateService.setSelectItem(tag.vectorId, VectorType.Tag, SelectState.All) stateService.setDraggingItem(stateService.selectItem) } } else { moveTag.moveFullTag(position, draggingItem.vectorId) } break case LayerEvents.MoveTag: needAutoRedraw = true if (draggingItem != null) { moveTag.moveFullTag(position, draggingItem.vectorId) } break case LayerEvents.AddFurniture: needAutoRedraw = true if (draggingItem == null) { const furnitureType = this.uiControl.getFurnitureTypeForUI() const furniture = furnitureService.createFurniture(position, furnitureType) if (furniture.vectorId) { stateService.setSelectItem(furniture.vectorId, furnitureType, SelectState.All) stateService.setDraggingItem(stateService.selectItem) } } else { const furniture = floorplanService.getFurniture(draggingItem.vectorId) mathUtil.clonePoint(furniture.center, position) } break case LayerEvents.MoveFurniture: needAutoRedraw = true const furniture = floorplanService.getFurniture(draggingItem.vectorId) mathUtil.clonePoint(furniture.center, position) break } if (needAutoRedraw) { this.renderer.autoRedraw() } } onMouseUp(e) { if (coordinate.defaultCenter == null) { return } const X = e.offsetX || e.layerX const Y = e.offsetY || e.layerY let eventName = stateService.getEventName() const draggingItem = stateService.getDraggingItem() let focusItem = null if (draggingItem && draggingItem.vectorId) { focusItem = { vectorId: draggingItem.vectorId, type: draggingItem.type, cursor: { x: this.lastX, y: this.lastY }, } stateService.setFocusItem(focusItem) this.uiControl.showAttributes() } let position = coordinate.getXYFromScreen({ x: X, y: Y, }) let needAutoRedraw = false let symbol = null switch (eventName) { case null: return case LayerEvents.PanBackGround: needAutoRedraw = true stateService.clearFocusItem() this.uiControl.currentUI = null break case LayerEvents.MoveWallPoint: needAutoRedraw = true elementService.hideAll() let point = floorplanService.getPoint(draggingItem.vectorId) if (point) { //if (focusItem == null) { listenLayer.start(point, draggingItem.vectorId, point.parent) if (listenLayer.modifyPoint && listenLayer.modifyPoint.hasOwnProperty('linkedPointId')) { wallService.moveTo(draggingItem.vectorId, listenLayer.modifyPoint.linkedPointId) } else if (listenLayer.modifyPoint && (listenLayer.modifyPoint.linkedPointIdX || listenLayer.modifyPoint.linkedPointIdY)) { mathUtil.clonePoint(point, listenLayer.modifyPoint) } else if (listenLayer.modifyPoint && listenLayer.modifyPoint.hasOwnProperty('linkedWallId')) { point = wallService.createPoint(listenLayer.modifyPoint.x, listenLayer.modifyPoint.y) wallService.splitWall(listenLayer.modifyPoint.linkedWallId, point.vectorId, 'start') wallService.moveTo(draggingItem.vectorId, point.vectorId) } else if (moveWall.splitWallId != null) { wallService.splitWall(moveWall.splitWallId, draggingItem.vectorId, 'start') } //draggingItem.vectorId所在的墙面与其他墙角相交 moveWall.updateForAbsorbWallPoints() this.history.save() } break case LayerEvents.AddingWall: needAutoRedraw = true if (addWall.startInfo && addWall.startInfo.linkedPointId) { let addWallStartPoint = floorplanService.getPoint(addWall.startInfo.linkedPointId) if (addWall.endInfo.position && Object.keys(addWallStartPoint.parent).length > 1) { stateService.clearEventName() addWall.clear() elementService.hideAll() } } break case LayerEvents.MoveWall: needAutoRedraw = true if (focusItem != null && focusItem.type == VectorType.Wall) { const wall = floorplanService.getWall(focusItem.vectorId) if (wall.import || wall.out) { this.uiControl.currentUI = 'OutWall' } else { this.uiControl.currentUI = focusItem.type } this.history.save() } else { this.history.save() } break case LayerEvents.AddSymbol: if (draggingItem == null) { this.setEventName('mouseUp') return } focusItem = { vectorId: draggingItem.vectorId, type: draggingItem.type, cursor: { x: this.lastX, y: this.lastY }, } stateService.setFocusItem(focusItem) this.uiControl.showAttributes() this.uiControl.currentUI = focusItem.type this.history.save() break case LayerEvents.AddComponent: focusItem = { vectorId: draggingItem.vectorId, type: draggingItem.type, cursor: { x: this.lastX, y: this.lastY }, } stateService.setFocusItem(focusItem) this.uiControl.showAttributes() this.uiControl.currentUI = focusItem.type this.history.save() break case LayerEvents.MoveComponent: needAutoRedraw = true if (focusItem != null && componentService.isComponent(focusItem.type)) { this.uiControl.currentUI = focusItem.type this.history.save() } else { this.history.save() } break case LayerEvents.MoveTag: needAutoRedraw = true if (focusItem != null && focusItem.type == VectorType.Tag) { this.uiControl.currentUI = focusItem.type this.history.save() } else { this.history.save() } break case LayerEvents.AddTag: needAutoRedraw = true let tag = floorplanService.getTag(draggingItem.vectorId) tag.setAdding(false) focusItem = { vectorId: draggingItem.vectorId, type: draggingItem.type, cursor: { x: this.lastX, y: this.lastY }, } stateService.setFocusItem(focusItem) this.history.save() this.uiControl.currentUI = focusItem.type break case LayerEvents.AddFurniture: focusItem = { vectorId: draggingItem.vectorId, type: draggingItem.type, cursor: { x: this.lastX, y: this.lastY }, } stateService.setFocusItem(focusItem) this.uiControl.showAttributes() this.uiControl.currentUI = focusItem.type this.history.save() break case LayerEvents.MoveFurniture: needAutoRedraw = true if (focusItem != null && furnitureService.isFurniture(focusItem.type)) { this.uiControl.currentUI = focusItem.type this.history.save() } else { debugger this.history.save() } break } this.setEventName('mouseUp') stateService.clearDraggingItem() this.renderer.autoRedraw() } onWheel(e) { if (coordinate.defaultCenter == null) { return } e.preventDefault() const type = e.type if (type == 'DOMMouseScroll' || type == 'mousewheel') { // 当在canvas用滚轮滚动时 const delta = e.wheelDelta ? (e.wheelDelta / 120) * 2 : (-(e.detail || 0) / 3) * 2 const zoom = coordinate.zoom + delta if (zoom < 14) { return } coordinate.updateZoom(zoom) let info = coordinate.getScreenInfoForCAD() info.floorPlanAngle = floorplanService.getAngle() this.renderer.autoRedraw() } } onKeydown(e) { if (!this.display) { return } if (e.ctrlKey && e.code == 'KeyZ') { // 撤销 if (!this.$xui.toolbar.recall) { return } this.revokeHistory() console.log('ctrl+z') } else if (e.ctrlKey && e.code == 'KeyY') { // 恢复 if (!this.$xui.toolbar.recover) { return } this.recoveryHistory() console.log('ctrl+y') } else if (e.code == 'Delete') { this.deleteItem() this.uiControl.currentUI = null this.history.save() this.renderer.autoRedraw() console.log('Delete') } else if (e.code == 'Escape') { this.stopAddVector() this.renderer.autoRedraw() console.log('Esc') } } //点击左侧栏后,更新事件 updateEventNameForSelectUI() { elementService.hideAll() //正在添加tag的时候,需要先删除 const eventName = stateService.getEventName() if (eventName == LayerEvents.AddTag) { let item = stateService.getDraggingItem() if (item && item.type == VectorType.Tag) { floorplanService.deleteTag(item.vectorId) } } stateService.clearItems() if (this.uiControl.selectUI == UIEvents.Wall || this.uiControl.selectUI == UIEvents.OutWall) { stateService.setEventName(LayerEvents.AddWall) } else if ( this.uiControl.selectUI == UIEvents.SingleDoor || this.uiControl.selectUI == UIEvents.DoubleDoor || this.uiControl.selectUI == UIEvents.SlideDoor || this.uiControl.selectUI == UIEvents.SingleWindow || this.uiControl.selectUI == UIEvents.BayWindow || this.uiControl.selectUI == UIEvents.FrenchWindow || this.uiControl.selectUI == UIEvents.Pass ) { stateService.setEventName(LayerEvents.AddSymbol) } else if (this.uiControl.selectUI == UIEvents.Beam || this.uiControl.selectUI == UIEvents.Flue || this.uiControl.selectUI == UIEvents.Corridor) { stateService.setEventName(LayerEvents.AddComponent) } else if (this.uiControl.selectUI == UIEvents.Tag) { stateService.setEventName(LayerEvents.AddTag) } else if ( this.uiControl.selectUI == UIEvents.TV || this.uiControl.selectUI == UIEvents.CombinationSofa || this.uiControl.selectUI == UIEvents.SingleSofa || this.uiControl.selectUI == UIEvents.TeaTable || this.uiControl.selectUI == UIEvents.Carpet || this.uiControl.selectUI == UIEvents.Plant || this.uiControl.selectUI == UIEvents.DiningTable || this.uiControl.selectUI == UIEvents.DoubleBed || this.uiControl.selectUI == UIEvents.SingleBed || this.uiControl.selectUI == UIEvents.Wardrobe || this.uiControl.selectUI == UIEvents.Dresser || this.uiControl.selectUI == UIEvents.BedsideCupboard || this.uiControl.selectUI == UIEvents.Pillow || this.uiControl.selectUI == UIEvents.GasStove || this.uiControl.selectUI == UIEvents.Cupboard || this.uiControl.selectUI == UIEvents.Bathtub || this.uiControl.selectUI == UIEvents.Closestool || this.uiControl.selectUI == UIEvents.Washstand || this.uiControl.selectUI == UIEvents.Desk || this.uiControl.selectUI == UIEvents.BalconyChair || this.uiControl.selectUI == UIEvents.Elevator ) { stateService.setEventName(LayerEvents.AddFurniture) } } setEventName(eventType) { let eventName = stateService.getEventName() if (eventType == 'mouseDown') { if (eventName == null) { const selectItem = stateService.getSelectItem() if (selectItem == null) { stateService.setEventName(LayerEvents.PanBackGround) } else if (selectItem.type == VectorType.Wall) { stateService.setEventName(LayerEvents.MoveWall) } else if (selectItem.type == VectorType.WallCorner) { stateService.setEventName(LayerEvents.MoveWallPoint) } else if (componentService.isComponent(selectItem.type)) { stateService.setEventName(LayerEvents.MoveComponent) } else if (selectItem.type == VectorType.Tag) { stateService.setEventName(LayerEvents.MoveTag) } else if (furnitureService.isFurniture(selectItem.type)) { stateService.setEventName(LayerEvents.MoveFurniture) } } else if (eventName == LayerEvents.AddWall) { stateService.setEventName(LayerEvents.AddingWall) } } else if (eventType == 'mouseUp') { if (eventName == LayerEvents.AddTag) { //可连续添加 } else if (eventName != LayerEvents.AddWall && eventName != LayerEvents.AddingWall) { stateService.clearEventName() } } } exit() { stateService.clearItems() stateService.clearEventName() this.uiControl.clearUI() } stopAddVector() { let eventName = stateService.getEventName() if (eventName != LayerEvents.AddingWall) { stateService.clearEventName() const draggingItem = stateService.getDraggingItem() if (eventName == LayerEvents.AddSymbol) { if (draggingItem && draggingItem.vectorId) { stateService.clearDraggingItem() } } else if (eventName == LayerEvents.AddComponent) { if (draggingItem && draggingItem.vectorId) { floorplanService.deleteComponent(draggingItem.vectorId) } } else if (eventName == LayerEvents.AddTag) { if (draggingItem && draggingItem.vectorId) { tagService.deleteTag(draggingItem.vectorId) this.uiControl.currentUI = null } } else if (eventName == LayerEvents.AddFurniture) { if (draggingItem && draggingItem.vectorId) { floorplanService.deleteFurniture(draggingItem.vectorId) } } } else { stateService.setEventName(LayerEvents.AddWall) } this.uiControl.clearUI() elementService.hideAll() } setNewWallPoint(dir, position) { if (listenLayer.symbolInfo.state == 'select') { return false } if (dir == 'start') { if (listenLayer.modifyPoint) { addWall.setPointInfo(dir, listenLayer.modifyPoint) } else { addWall.setPointInfo(dir, coordinate.getXYFromScreen(position)) } return true } else if (dir == 'end') { if (listenLayer.modifyPoint) { addWall.setPointInfo(dir, listenLayer.modifyPoint) } else { addWall.setPointInfo(dir, coordinate.getXYFromScreen(position)) } return true } return false } deleteItem() { let item = stateService.getFocusItem() if (item) { if (item.type == VectorType.Wall) { floorplanService.deleteWall(item.vectorId) } else if (componentService.isComponent(item.type)) { floorplanService.deleteComponent(item.vectorId) } else if (item.type == VectorType.Tag) { floorplanService.deleteTag(item.vectorId) } else if (furnitureService.isFurniture(item.type)) { floorplanService.deleteComponent(item.vectorId) } else if (item.type == VectorType.WallCorner) { wallService.deleteWallCorner(item.vectorId) } this.history.save() this.renderer.autoRedraw() } } }