/* * iGeom by LInE * Geometric Object: Segment * Drawer to Segment * www.usp.br/line * www.matematica.br/igeom * ./app/components/middle-point/drawers/middle-point-drawer.js * * @version 2024/09/28: fixed import bug (now coord. of MidPoint is effectively updated in movements) * @version 2020/11/02: indentation */ import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum"; import { label as Label } from "../../../component-registry/label"; import { DrawerAggregator } from "../../../core/drawers/drawer-aggregator"; import { selector as Selector } from "../../../core/application/selector"; import { PointDrawer } from "../../point-component/drawers/point-drawer"; import { objects as Objects } from "../../../core/application/objects"; import { SelectableDrawer } from "../../../core/drawers/selectable-drawer"; import { PointModel } from "../../point-component/models/point-model"; import { MiddlePointModel } from "../models/middle-point-model"; // MiddlePointDrawer extends PointDrawer (app/components/point-component/drawers/point-drawer.js) export class MiddlePointDrawer extends PointDrawer { static count2debug = 1; //DEBUG static FIRST_POINT_STATE () { return "FIRST_POINT"; } static SECOND_POINT_STATE () { return "SECOND_POINT"; } // A single instace of "MiddlePointDrawer" is created constructor () { // constructor of any MidPoint (called once at the begining super(); this.id = MiddlePointDrawer.count2debug++; //DEBUG //D console.log("middle-point-drawer.js: constructor(): this.id=" + this.id); this.pointA; // origin this.pointB; // end point this.aggregatorA; this.aggregatorB; this.label; this.states = [MiddlePointDrawer.FIRST_POINT_STATE, MiddlePointDrawer.SECOND_POINT_STATE]; this.middlePoint; // also MidPoint? (missing the segment!) this.pointDrawer = new PointDrawer(); super.setElementClass(ELEMENTS_CLASS.MIDDLE_POINT); } setPointA (point) { this.pointA = point; console.log("middle-point-drawer.js: setPointA(point): point.id=" + point.id); } setPointB(point) { this.pointB = point; console.log("middle-point-drawer.js: setPointB(point): point.id=" + point.id); } setPointC(point) { //REMOVER this.pointC = point; console.log("middle-point-drawer.js: setPointC(point): point.id=" + point.id); } // @calledby this.drawByStates(konvaObject): this.setAggregatorA(aggregator); setAggregatorA (aggregator) { this.aggregatorA = aggregator; this.setPointA(aggregator.genericObject); // console.trace(); //D detectar erro aggregatorA.id=3 mas aggregatorA.genericObject.id=2! console.log("middle-point-drawer.js: setAggregatorA(aggregator): aggregatorA.id=" + aggregator.id + ", aggregatorA.genericObject.id=" + aggregator.genericObject.id); } setAggregatorB (aggregator) { this.aggregatorB = aggregator; this.setPointB(aggregator.genericObject); console.log("middle-point-drawer.js: setAggregatorB(aggregator): aggregatorB.id=" + aggregator.id + ", aggregatorB.genericObject.id=" + aggregator.genericObject.id); } setAggregatorC (aggregator) { //REMOVER this.aggregatorC = aggregator; this.setPointC(aggregator.genericObject); console.log("middle-point-drawer.js: setAggregatorC(aggregator): aggregator.genericObject.id=" + aggregator.genericObject.id); } //DEBUG print coordinates of point pp (point) { var px="",py=""; try { //D //leo px=""+point.id+":"+point.posX; py=""+point.posY; var aux1="", aux2=""; var items = px.split("."); if (items && items.length>1) aux1 = "." + items[1].substr(0,3); px = items[0] + aux1; // pegar apenas 3 digitos var items = py.split("."); if (items && items.length>1) aux2 = "." + items[1].substr(0,3); py = items[0] + aux2; // pegar apenas 3 digitos } catch (e) { console.log("pp(.): erro! " + e); } return "(" + px + "," + py + ")"; } // @calledby app/core/models/components/component.js: draw(e): this.drawer.draw(e); draw (e) { // First "click" on MidlePoint icon reache this point console.log("middle-point-drawer.js!draw(e)"); if (e != undefined) { // if (e.target != undefined && e.target.attrs.class != undefined && (e.target.attrs.class == ELEMENTS_CLASS.POINT || e.target.attrs.class == ELEMENTS_CLASS.INTERSECTION_POINT)) { console.log(" * 4. b, e.target.attrs=" + JSON.stringify(e.target.attrs)); // first and second point already exists this.drawByStates(e.target); // create the final point defining this MidPoint return; } else if (e.attrs != undefined && e.attrs.genericObject != undefined) { console.log(" * 5. c"); this.drawByMiddlePoint(e.attrs.genericObject) return; } } // Selected MidPoint constructor const points = Selector.getSelectedPoints(); if (points == undefined || points.length == 0) { this.drawByStates(); // create this MidPoint var aux1 = (this.middlePoint && this.middlePoint.id ? this.middlePoint.id : "<>"); console.log(" * 6. apos 'this.drawByStates()' this.middlePoint.id=" + aux1 + "; points=0"); //D //leo return; } console.log(" * 7. this.middlePoint.id="+(this.middlePoint&&this.middlePoint.id?this.middlePoint.id:"<>") + " #points=" + points.length + " xxxxxxxxxxxxxxxxxxxxxxxxxxxx "); //D //leo if (points.length >= 2) this.drawByPoints(points); // necessary to crate new MidPoint from 2 already existing point (mode "selection + action") } // draw(e) drawByStates (konvaObject) { let aggregator = undefined; var aux = ""; if (konvaObject != undefined) { aggregator = Objects.getByKonvaObject(konvaObject)[0]; aux += " (1) aggregator.id=" + (aggregator!=undefined ? aggregator.id : "<>") + "; "; } if (this.state == undefined) { super.setState(MiddlePointDrawer.FIRST_POINT_STATE); console.log("middle-point-drawer.js!drawByStates(konvaObject): " + aux + " (2) FIRST_POINT_STATE; "); } else if (this.state == MiddlePointDrawer.FIRST_POINT_STATE) { // second "click" after initial Point => creates final Point try { // aggregator=["id","drawer","genericObject","konvaObject","aggregators","visible","elementClass"] // var aux2 = ", aggregator=" + JSON.stringify(Object.keys(aggregator)); // JSON.stringify(aggregator) => "TypeError: cyclic object value" // aggregator[id, genericObject.id, #aggregators, elementClass]=[3, 2, 0, 13] var aux2 = (aggregator!=undefined ? ", aggregator[id, genericObject.id, #aggregators, elementClass]=[" + aggregator.id + ", " + aggregator.genericObject.id + ", " + aggregator.aggregators.length + ", " + aggregator.elementClass + "]" : "<>"); aggregator = aggregator != undefined ? aggregator : this.pointDrawer.drawPoint(); // drawPoint() provides "point" to "this.pointA" this.setAggregatorA(aggregator); // will associate "this.pointA" with "aggregator.genericObject" console.log("middle-point-drawer.js!drawByStates(konvaObject): aggregatorA.id=" + aggregator.id + aux2); } catch (e) { console.log("middle-point-drawer.js!drawByStates(.): 4 - erro " + e); } console.log("middle-point-drawer.js!drawByStates(konvaObject): aggregatorA.id=" + aggregator.id + ", this.pointA.id=" + this.pointA.id); super.setState(MiddlePointDrawer.SECOND_POINT_STATE); } else if (this.state == MiddlePointDrawer.SECOND_POINT_STATE) { // second "click" after final Point => creates MidPoint console.log("middle-point-drawer.js!drawByStates(.): 5"); aggregator = aggregator != undefined ? aggregator : this.pointDrawer.drawPoint(); // drawPoint() provides "point" to "this.pointB" this.setAggregatorB(aggregator); // will associate "this.pointB" with "aggregator.genericObject" var aux = ", A=" + this.pp(this.pointA) + ", B=" + this.pp(this.pointB) + ": "; console.log("middle-point-drawer.js!drawByStates(konvaObject): aggregatorB.id=" + aggregator.id + ", this.pointB.id=" + this.pointB.id + aux); //D//leo this.draggable = false; //novo const coord = MiddlePointModel.getMiddlePointPos(this.pointA, this.pointB); // get coord. of defining points this.posX = coord.posX; this.posY = coord.posY; this.drawByPoints([this.pointA, this.pointB], [this.aggregatorA, this.aggregatorB]); //x origem do 2o MidPoint! super.setState(MiddlePointDrawer.FIRST_POINT_STATE); // return to the state initial } } // drawByStates(konvaObject) drawByPoints (points, aggregators) { // create 2 midpoint with the points A and B already created console.log("middle-point-drawer.js!drawByPoints(.): #points=" + points.length); //D var aux = ""; if (points == undefined || points.length < 1) return; try { // Considering this as C=MidPoint(A,B) this.setPointA(points[0]); // get source point A this.setPointB(points[1]); // get source point B aggregators = this.resolveAggregators(points, aggregators, true); // get the lists of dependents of point A and point B this.label = Label.draw(false); // app/component-registry/label.js : draw(lower = false) => this.pushUpper(); // this.middlePoint = new MiddlePointModel(this.pointA, this.pointB, this.label, -1); // now create Segment - 'drawByStates(konvaObject)' already created the MidPoint pointC // Now create this MidPoint this.middlePoint = new MiddlePointModel(this.pointA, this.pointB, this.label); // now create Segment - 'drawByStates(konvaObject)' already created the MidPoint pointC this.drawByMiddlePoint(this.middlePoint); this.reset(); } catch (error) { console.log("middle-point-drawer.js!drawByPoints(.): " + error); } console.log("middle-point-drawer.js!drawByPoints(.): final"); } // drawByPoints(points, aggregators) drawByMiddlePoint (middlePoint, draggable, selectable) { try { this.middlePoint = middlePoint; this.middlePoint.backgroundColor = "#f54260"; const group = SelectableDrawer.getKonvaGroup(false); const text = MiddlePointDrawer.getKonvaText(middlePoint, middlePoint.label); // app/component-registry/label.js : // const midpoint = MiddlePointDrawer.getKonvaCircle(middlePoint); const midpoint = MiddlePointDrawer.getKonvaCircle(middlePoint, draggable, selectable); // apos introd. param. ", draggable, selectable" midpoint.selectable = true; // const circle = PointDrawer.getKonvaCircle(point, draggable, selectable); group.add(text); group.add(midpoint); super.setKonvaObject(group); const aggregator = new DrawerAggregator( this, this.middlePoint, group, ELEMENTS_CLASS.MIDDLE_POINT ); console.log("middle-point-drawer.js!drawByMiddlePoint(.): insert this C=MidPoint(A,B) in the list of dependents of A or of B"); //DEBUG try { // Insert this MidPoint C=MidPoint(A,B) in the list of drawers dependents of A and of B (in app/core/drawers/drawer.js) //D "C:=MidPoint(A,B); D:=MidPoint(C,B);" could launch error "TypeError: cyclic object value", try/catch allow running with no error super.addAggregator(aggregator); // PointDrawer (app/components/point-component/drawers/point-drawer.js) extends SelectableDrawer } catch (error) { console.log("middle-point-drawer.js!drawByMiddlePoint(.): error in 'super.addAggregator(aggregator): " + error); } const aggregators = this.resolveAggregators([this.middlePoint.pointA, this.middlePoint.pointB], undefined); aggregators[1].addAggregator(aggregator); // Insert this MidPoint C in the list of dependents of point A aggregators[0].addAggregator(aggregator); // Insert this MidPoint C in the list of dependents of point B //D console.log("app/components/middle-point/drawers/middle-point-drawer.js: drawByMiddlePoint"); //leo SelectableDrawer.drawObject(this.konvaObject); // this.konvaObject.zIndex(1); super.batchDraw(); // ../../../core/drawers/drawer-aggregator.js SelectableDrawer.setMaxIndex(aggregators[0].konvaObject); SelectableDrawer.setMaxIndex(aggregators[1].konvaObject); } catch (error) { console.log("middle-point-drawer.js!drawByMiddlePoint(middlePoint): " + error); } } // drawByMiddlePoint(middlePoint) resolveAggregators (points, aggregators, selected) { this.pointA = points[0]; this.pointB = points[1]; if (aggregators == undefined && selected == true) aggregators = Selector.getSelectedPointsAggregators(); else { aggregators = [ Objects.getByGenericObject(this.pointA)[0], Objects.getByGenericObject(this.pointB)[0], ]; } return aggregators; } //DEBUG distancePointMouseclick (midPoint, e) { var distX = midPoint.posX-e.evt.offsetX, distY = midPoint.posY-e.evt.offsetY; return ((distX*distX + distY*distY)); // this MidPoint only small distance! } // Update MidPoint after any movement of one point that impact this MidPoint // @calledby ./src/app/core/drawers/drawer-aggregator.js!updateAggregators(aggregators,e): aggregator.drawer.update(aggregator, e); update (aggregator, e) { //D if (MiddlePointDrawer.count2debug==2) { //D //D console.log(" * middle-point-drawer!update(.): aggregator.id="+(aggregator!=undefined ? aggregator.id : "<>")+", count2debug="+MiddlePointDrawer.count2debug); //D console.trace(); //D } //D if (!aggregator.visible) { console.log(" * middle-point-drawer!update(.): aggregator.id=" + (aggregator!=undefined ? aggregator.id : "<>") + " with !aggregator.visible"); //D return; } var aux = "\n[1], ", aux2; //D try { const pointA = aggregator.genericObject.pointA; // initial point that define MidPoint const pointB = aggregator.genericObject.pointB; // final point aux += "[2], "; //D const coord = aggregator.genericObject.getMiddlePoint(); // app/components/middle-point/models/middle-point-model.js aux += "[3], "; //D // console.log(" * middle-point-drawer!update(.): A.id=" + pointA.id + "=" + this.pointA.id + ", B.id=" + pointB.id + ", C.id="+pointC.id+", : " + aux); aggregator.konvaObject.children[0].x(coord.posX); // Konva.Text : used to the MidPoint label X coord. aggregator.konvaObject.children[0].y(coord.posY - 20); // used to the MidPoint label Y coord. var point = aggregator.konvaObject.children[1]; // Konva.Circle : used to draw the point //D aux2 = point.attrs; // atributes of KonvaObject //D aux += "[4], children[1]=(" + aux2.x + "," + aux2.y + "), " + point.className; // JSON.stringify(point); //D // Now update the coordinates of this midpoint: need to use KonvaObject (type Point) functions "point.x(.)" and "point.y(.)" //this.posX = coord.posX; // xxx no effect! //this.posY = coord.posY; // xxx no effect! point.x(coord.posX); // update X coord. of the label of this MidPoint point.y(coord.posY); // update Y coord. of the label of this MidPoint aggregator.genericObject.posX = coord.posX; // really update internal X coord. of this MidPoint aggregator.genericObject.posY = coord.posY; // really update internal Y coord. of this MidPoint //D console.log("middle-point-drawer.js!update(aggregator, e): this.id=" + this.id + ", aggregator.genericObject.id=" + aggregator.genericObject.id + " : MP=MidPoint[" + this.pp(aggregator.genericObject) + "], A=" + this.pp(pointA) + ", B=" + this.pp(pointB) + ""); // + aux } catch (error) { console.log("middle-point-drawer.js!update(.): error = " + error + "\n" + aux); } super.batchDraw(); // app/core/drawers/drawer.js: batchDraw(): Drawer.stageBatchDraw(); | static stageBatchDraw(): DrawerManager.batchDraw(); // app/core/drawers/drawer-manager.js: batchDraw() } insertPoint (aggregator) { //REMOVER const pointA = aggregator.genericObject.pointA; const pointB = aggregator.genericObject.pointB; const pointCAggregator = this.pointDrawer.drawPoint(); aggregator.konvaObject.points([ pointA.posX, pointA.posY, pointB.posX, pointB.posY ]); super.batchDraw(); } static getKonvaText (MiddlePoint, label) { const pos = MiddlePoint.getMiddlePoint(); return new Konva.Text({ x: pos.posX, y: pos.posY - 20, text: label, fontSize: 14, fontFamily: "Calibri", fill: "#434a45", stroke: "#ffffff", strokeWidth: 0.2, draggable: false, resizeEnabled: false, transformEnabled: false, selectable: false }); } static getKonvaLine (pointA, pointB, useLabel) { const points = [pointA.posX, pointA.posY, pointB.posX, pointB.posY]; const line = new Konva.Line({ points: points, stroke: "grey", strokeWidth: 2, lineJoin: "round", draggable: false, strokeScaleEnabled: false, class: ELEMENTS_CLASS.LINE_SEGMENT, connections: [], index: 1, selectable: false, draggable: false, style: { stroke: "grey", fill: "grey" } }); SelectableDrawer.setSelectableIfIntersectionChanged(line); return line; } static drawKonvaLine(pointA, pointB) { const line = MiddlePointDrawer.getKonvaLine(pointA, pointB); return line; } }