whole-line-line-helper.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import konva from "konva";
  2. import {
  3. WholeLineLineAttrib,
  4. WholeLineLineProps,
  5. } from "../view/whole-line-line";
  6. import { getLineDireAngle } from "../../../shared/math";
  7. import { MathUtils } from "three";
  8. import { WholeLineAttrib } from "../view/whole-line";
  9. import { Entity } from "../../entity";
  10. import { Group } from "konva/lib/Group";
  11. import { Label } from "konva/lib/shapes/Label";
  12. import { Arrow } from "konva/lib/shapes/Arrow";
  13. import { Text } from "konva/lib/shapes/Text";
  14. export class WholeLineLineHelper extends Entity<WholeLineLineAttrib, Group> {
  15. static namespace = "line-helper";
  16. private config: WholeLineAttrib;
  17. constructor(props: WholeLineLineProps) {
  18. props.zIndex = props.zIndex || 4;
  19. props.name = props.name || WholeLineLineHelper.namespace + props.attrib.id;
  20. super(props);
  21. }
  22. setConfig(config: WholeLineAttrib) {
  23. this.config = config;
  24. }
  25. initShape() {
  26. const label = new konva.Label({
  27. opacity: 0.75,
  28. name: "label",
  29. listening: false,
  30. });
  31. label.add(
  32. new konva.Tag({
  33. name: "tag",
  34. fill: "rgba(0, 0, 0, 0.8)",
  35. pointerDirection: "down",
  36. pointerWidth: 5,
  37. pointerHeight: 5,
  38. lineJoin: "round",
  39. shadowColor: "black",
  40. shadowBlur: 10,
  41. shadowOffsetX: 10,
  42. shadowOffsetY: 10,
  43. shadowOpacity: 0.5,
  44. listening: false,
  45. }),
  46. new konva.Text({
  47. name: "text",
  48. text: `text`,
  49. fontFamily: "Calibri",
  50. fontSize: 10,
  51. padding: 3,
  52. fill: "white",
  53. listening: false,
  54. })
  55. );
  56. const arrowSize = 8;
  57. const shape = new konva.Group();
  58. shape.add(label).add(
  59. new konva.Arrow({
  60. name: "arrow-1",
  61. visible: false,
  62. points: [0, 0],
  63. pointerLength: arrowSize,
  64. pointerWidth: arrowSize,
  65. fill: "black",
  66. stroke: "black",
  67. strokeWidth: 4,
  68. listening: false,
  69. }),
  70. new konva.Arrow({
  71. name: "arrow-2",
  72. visible: false,
  73. points: [0, 0],
  74. pointerLength: arrowSize,
  75. pointerWidth: arrowSize,
  76. fill: "black",
  77. stroke: "black",
  78. strokeWidth: 4,
  79. listening: false,
  80. })
  81. );
  82. return shape;
  83. }
  84. diffRedraw(): void {
  85. const points = this.attrib.pointIds.map((id) =>
  86. this.config.points.find((point) => point.id === id)
  87. );
  88. if (points.some((point) => !point)) {
  89. return null;
  90. }
  91. let twoWay = false;
  92. const labels: string[] = [];
  93. for (const polygon of this.config.polygons) {
  94. for (const lineId of polygon.lineIds) {
  95. const line = this.config.lines.find(({ id }) => id === lineId);
  96. if (
  97. line.pointIds.includes(this.attrib.pointIds[0]) &&
  98. line.pointIds.includes(this.attrib.pointIds[1])
  99. ) {
  100. labels.push(`${line.id} [${line.pointIds.join(",")}]`);
  101. twoWay = twoWay || line.pointIds[0] === this.attrib.pointIds[1];
  102. }
  103. }
  104. }
  105. const coords: number[] = [];
  106. points.forEach(({ x, y }, ndx) => {
  107. coords[ndx * 2] = x;
  108. coords[ndx * 2 + 1] = y;
  109. });
  110. const angle = MathUtils.radToDeg(getLineDireAngle(coords, [0, 1]));
  111. this.shape
  112. .findOne<Label>(".label")
  113. .x((coords[0] + coords[2]) / 2)
  114. .y((coords[1] + coords[3]) / 2)
  115. .rotation(angle < 0 ? angle + 90 : angle - 90);
  116. this.shape
  117. .findOne<Arrow>(".arrow-1")
  118. .x(coords[2])
  119. .y(coords[3])
  120. .rotation(angle + 90)
  121. .visible(true);
  122. if (twoWay) {
  123. this.shape
  124. .findOne<Arrow>(".arrow-2")
  125. .x(coords[0])
  126. .y(coords[1])
  127. .rotation(angle - 90)
  128. .visible(true);
  129. } else {
  130. this.shape.findOne<Arrow>(".arrow-2").visible(false);
  131. }
  132. this.shape.findOne<Text>(".text").text(labels.join(" | "));
  133. }
  134. }