import { APP_STATE } from "../enums/app-state-enum"; import { stageManager as Stages } from "./stage-manager"; import { state as State } from "../application/state"; import { objects as Objects } from "../application/objects"; import { ELEMENTS_CLASS } from "../enums/elements-class-enum"; import { app as App } from "../../app"; export class Selector { constructor() { this._selectorPosStart; this._selectorPosNow; this._mode = ""; this._stage = Stages.getCurrentKonvaStage(); this._layer = Stages.getCurrentKonvaLayer(); this._selectorRect = new Konva.Rect({ x: 0, y: 0, width: 0, height: 0, stroke: "#33BCFF", dash: [2, 2] }); } bootstrap() { this.configureSelectorEvents(); this.addToLayer(); } addToLayer() { this._selectorRect.listening(false); Stages.getCurrentKonvaLayer().add(this._selectorRect); } getSelectedAggregators() { return Objects.getSelectedObjects(); } getSelectedKonvaObjects() { return this.getSelectedAggregators().map(function(aggregator) { if (aggregator.konvaObject.children == undefined) { return aggregator.konvaObject; } else { return aggregator.konvaObject.children.map(function(object) { return object; })[0]; } }); } getSelectedKonvaPoints() { const objects = this.getSelectedKonvaObjects(); return objects.filter( x => x.attrs.class != undefined && x.attrs.class == ELEMENTS_CLASS.POINT ); } getSelectedPoints() { const objects = this.getSelectedAggregators().filter( x => x.elementClass === ELEMENTS_CLASS.POINT || x.elementClass === ELEMENTS_CLASS.INTERSECTION_POINT ); return objects.map(x => x.genericObject); } getSelectedPointsAggregators() { const objects = this.getSelectedAggregators().filter( x => x.elementClass === ELEMENTS_CLASS.POINT || x.elementClass === ELEMENTS_CLASS.INTERSECTION_POINT ); return objects; } startDragSelector(posIn) { this._selectorPosStart = { x: posIn.x, y: posIn.y }; this._selectorPosNow = { x: posIn.x, y: posIn.y }; } updateDragSelector(posIn) { if (State.getCurrentState() != APP_STATE.NONE) return; App.clearSelectedTool(); const currentObjects = Objects.get(); const posRect = this.reverse(this._selectorPosStart, this._selectorPosNow); this._selectorPosNow = { x: posIn.x, y: posIn.y }; console.info(" his._selectorPosStart", this._selectorPosStart); console.info("posRect", posRect); this._selectorRect.x(posRect.x1); this._selectorRect.y(posRect.y1); this._selectorRect.width(posRect.x2 - posRect.x1); this._selectorRect.height(posRect.y2 - posRect.y1); this._selectorRect.visible(true); console.info("this._selectorRect", this._selectorRect); for (let i = 0; i < currentObjects.length; i = i + 1) { const aggregator = currentObjects[i]; const object = aggregator.konvaObject; if (object == undefined) return; if (object.children != undefined && object.children.length > 0) { for (let j = 0; j < object.children.length; j++) { this.style(object.children[j], this._selectorRect, aggregator); } } else { this.style(object, this._selectorRect, aggregator); } } this._stage.draw(); } style(object, selectorRect, aggregator) { if (object == undefined) return; if (object.attrs.selectable != undefined) { if (object.attrs.selectable == false) { return; } } if (this.hitCheck(object, selectorRect)) { object.stroke("#33BCFF"); object.fill("#33BCFF"); this.setObject(aggregator); } else { if (object.attrs.style != undefined) { this.removeObject(aggregator); object.stroke(object.attrs.style.stroke); object.fill(object.attrs.style.fill); } else { this.removeObject(aggregator); object.stroke("grey"); } } } hitCheck(shape1, shape2) { let s1 = shape1.getClientRect(); let s2 = shape2.getClientRect(); let X = s1.x; let Y = s1.y; let A = s1.x + s1.width; let B = s1.y + s1.height; let X1 = s2.x; let A1 = s2.x + s2.width; let Y1 = s2.y; let B1 = s2.y + s2.height; if (A < X1 || A1 < X || B < Y1 || B1 < Y) { return false; } else { return true; } } setObject(object) { Objects.setSelectedOject(object); } removeObject(object) { Objects.removeSelectedOject(object); } reverse(r1, r2) { let r1x = r1.x, r1y = r1.y, r2x = r2.x, r2y = r2.y, d; if (r1x > r2x) { d = Math.abs(r1x - r2x); r1x = r2x; r2x = r1x + d; } if (r1y > r2y) { d = Math.abs(r1y - r2y); r1y = r2y; r2y = r1y + d; } return { x1: r1x, y1: r1y, x2: r2x, y2: r2y }; } clear() { Objects.get().forEach(aggregator => { const object = aggregator.konvaObject; if (object == undefined) return; if (object.attrs.selectable != undefined) { if (object.attrs.selectable == false) { return; } } if (object.children != undefined && object.children.length > 0) { for (let j = 0; j < object.children.length; j++) { this.clearAggregator(object.children[j], aggregator); } } else { this.clearAggregator(object, aggregator); } }); } clearAggregator(object, aggregator) { if (object == undefined) return; if (object.attrs.style != undefined) { this.removeObject(aggregator); object.stroke(object.attrs.style.stroke); object.fill(object.attrs.style.fill); } else { this.removeObject(aggregator); object.stroke("grey"); } } configureSelectorEvents() { this._stage.on("mousedown touchstart", this.start.bind(this)); this._stage.on("mousemove touchmove", this.move.bind(this)); this._stage.on("mouseup touchend", this.end.bind(this)); } start(event) { const pos = { x: undefined, y: undefined }; if (event.evt.type === "touchstart") { pos.x = event.target.pointerPos.x; pos.y = event.target.pointerPos.y; } else { pos.x = event.evt.layerX; pos.y = event.evt.layerY; } Stages.getCurrentKonvaLayer().add(this._selectorRect); this._mode = "drawing"; this.startDragSelector(pos); } move(event) { const pos = { x: undefined, y: undefined }; if (event.evt.type === "touchmove") { pos.x = event.target.pointerPos.x; pos.y = event.target.pointerPos.y; } else { pos.x = event.evt.layerX; pos.y = event.evt.layerY; } if (this._mode === "drawing") { this.updateDragSelector(pos); } } end(event) { this._selectorRect.remove(); this._mode = ""; this._selectorRect.visible(false); this._stage.draw(); } } export const selector = new Selector();