Home Reference Source Repository

src/app/components/line-segment-component/drawers/line-segment-drawer.js

/*
 * iGeom by LInE
 * Geometric Object: Segment
 * Drawer to Segment
 * www.matematica.br/igeom
 * ./app/components/line-segment-component/drawers/line-segment-drawer.js
 * @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 { LineSegmentModel } from "../models/line-segment-model";
import { PointDrawer } from "../../point-component/drawers/point-drawer";
import { objects as Objects } from "../../../core/application/objects";
import { SelectableDrawer } from "../../../core/drawers/selectable-drawer";

export class LineSegmentDrawer extends SelectableDrawer {

  static FIRST_POINT_STATE() {
    return "FIRST_POINT";
  }

  static SECOND_POINT_STATE() {
    return "SECOND_POINT";
  }

  constructor() {
    super();
    this.pointA;
    this.pointB;
    this.aggregatorA;
    this.aggregatorB;
    this.label;
    this.states = [LineSegmentDrawer.FIRST_POINT_STATE, LineSegmentDrawer.SECOND_POINT_STATE];
    this.lineSegment;
    this.pointDrawer = new PointDrawer();
    super.setElementClass(ELEMENTS_CLASS.LINE_SEGMENT);
  }

  setPointA(point) {
    this.pointA = point;
  }
  setPointB(point) {
    this.pointB = point;
  }
  setAggregatorA(aggregator) {
    this.aggregatorA = aggregator;
    this.setPointA(aggregator.genericObject);
  }
  setAggregatorB(aggregator) {
    this.aggregatorB = aggregator;
    this.setPointB(aggregator.genericObject);
  }

  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)) {
        this.drawByStates(e.target);
        return;
      }
      else if (e.attrs != undefined && e.attrs.genericObject != undefined) {
        this.drawByLineSegment(e.attrs.genericObject)
        return;
      }
    }
    const points = Selector.getSelectedPoints();
    if (points == undefined || points.length == 0) {
      this.drawByStates();
      return;
    }
    this.drawByPoints(points);
  }


  drawByStates(konvaObject) {
    let aggregator = undefined;
    if (konvaObject != undefined) {
      aggregator = Objects.getByKonvaObject(konvaObject)[0];
    }
    if (this.state == undefined) {
      super.setState(LineSegmentDrawer.FIRST_POINT_STATE);
    }
    else if (this.state == LineSegmentDrawer.FIRST_POINT_STATE) {
      aggregator = aggregator != undefined ? aggregator : this.pointDrawer.drawPoint();
      this.setAggregatorA(aggregator);
      super.setState(LineSegmentDrawer.SECOND_POINT_STATE);
    }
    else if (this.state == LineSegmentDrawer.SECOND_POINT_STATE) {
      aggregator = aggregator != undefined ? aggregator : this.pointDrawer.drawPoint();
      this.setAggregatorB(aggregator);
      this.drawByPoints([this.pointA, this.pointB], [this.aggregatorA, this.aggregatorB]);
      super.setState(LineSegmentDrawer.FIRST_POINT_STATE);
    }
  }

  drawByPoints(points, aggregators) {
    if (points == undefined || points.length < 1) return;
    this.setPointA(points[0]);
    this.setPointB(points[1]);
    aggregators = this.resolveAggregators(points, aggregators, true);
    this.label = Label.draw(true);
    this.lineSegment = new LineSegmentModel(this.pointA, this.pointB, this.label);
    this.drawByLineSegment(this.lineSegment);
    this.reset();
  }

  drawByLineSegment(lineSegment) {
    this.lineSegment = lineSegment;
    const group = SelectableDrawer.getKonvaGroup(false);
    const text = LineSegmentDrawer.getKonvaText(lineSegment, lineSegment.label);
    group.add(text);
    const konvaObject = LineSegmentDrawer.getKonvaLine(lineSegment.pointA, lineSegment.pointB);
    group.add(konvaObject);
    super.setKonvaObject(group);
    const aggregator = new DrawerAggregator(
      this, this.lineSegment,
      group, ELEMENTS_CLASS.LINE_SEGMENT
    );
    super.addAggregator(aggregator);
    const aggregators = this.resolveAggregators([this.lineSegment.pointA, this.lineSegment.pointB], undefined);
    aggregators[1].addAggregator(aggregator);
    aggregators[0].addAggregator(aggregator);

    //D console.log("./app/components/line-segment-component/drawers/line-segment-drawer.js: drawByLineSegment"); //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);
  }

  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;
  }

  update(aggregator, e) {
    if (!aggregator.visible) return;
    const pointA = aggregator.genericObject.pointA;
    const pointB = aggregator.genericObject.pointB;
    const pos = aggregator.genericObject.getMiddlePoint();
    aggregator.konvaObject.children[0].x(pos.posX);
    aggregator.konvaObject.children[0].y(pos.posY - 20);
    aggregator.konvaObject.children[1].points([
      pointA.posX, pointA.posY,
      pointB.posX, pointB.posY
    ]);
    super.batchDraw();
  }

  insertPoint(aggregator) {
    const pointA = aggregator.genericObject.pointA;
    const pointB = aggregator.genericObject.pointB;
    const pointCAggregator = this.pointDrawer.drawPoint();
    const pointC = pointCAggregator.genericObject;
    aggregator.konvaObject.points([
      pointA.posX, pointA.posY,
      pointB.posX, pointB.posY,
      pointC.posX, pointC.posY
    ]);
    super.batchDraw();
  }

  static getKonvaText(lineSegment, label) {
    const pos = lineSegment.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 = LineSegmentDrawer.getKonvaLine(pointA, pointB);
    return line;
  }

}