selector.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import { APP_STATE } from "../enums/app-state-enum";
  2. import { stageManager as Stages } from "./stage-manager";
  3. import { state as State } from "../application/state";
  4. import { objects as Objects } from "../application/objects";
  5. import { ELEMENTS_CLASS } from "../enums/elements-class-enum";
  6. import { app as App } from "../../app";
  7. import { COMPONENT_TYPE } from "../enums/component-type-enum";
  8. export class Selector {
  9. constructor() {
  10. this._selectorPosStart;
  11. this._selectorPosNow;
  12. this._mode = "";
  13. this._stage = Stages.getCurrentKonvaStage();
  14. this._layer = Stages.getCurrentKonvaLayer();
  15. this._selectorRect = new Konva.Rect({
  16. x: 0,
  17. y: 0,
  18. width: 0,
  19. height: 0,
  20. stroke: "#33BCFF",
  21. dash: [2, 2]
  22. });
  23. }
  24. bootstrap() {
  25. this.configureSelectorEvents();
  26. this.addToLayer();
  27. }
  28. addToLayer() {
  29. this._selectorRect.listening(false);
  30. Stages.getCurrentKonvaLayer().add(this._selectorRect);
  31. }
  32. getSelectedAggregators() {
  33. return Objects.getSelectedObjects();
  34. }
  35. getSelectedKonvaObjects() {
  36. return this.getSelectedAggregators().map(function(aggregator) {
  37. if (aggregator.konvaObject.children == undefined) {
  38. return aggregator.konvaObject;
  39. } else {
  40. return aggregator.konvaObject.children.map(function(object) {
  41. return object;
  42. })[0];
  43. }
  44. });
  45. }
  46. getSelectedKonvaPoints() {
  47. const objects = this.getSelectedKonvaObjects();
  48. return objects.filter(
  49. x => x.attrs.class != undefined && x.attrs.class == ELEMENTS_CLASS.POINT
  50. );
  51. }
  52. getSelectedPoints() {
  53. const objects = this.getSelectedAggregators().filter(
  54. x =>
  55. x.elementClass === ELEMENTS_CLASS.POINT ||
  56. x.elementClass === ELEMENTS_CLASS.INTERSECTION_POINT
  57. );
  58. return objects.map(x => x.genericObject);
  59. }
  60. getSelectedPointsAggregators() {
  61. const objects = this.getSelectedAggregators().filter(
  62. x =>
  63. x.elementClass === ELEMENTS_CLASS.POINT ||
  64. x.elementClass === ELEMENTS_CLASS.INTERSECTION_POINT
  65. );
  66. return objects;
  67. }
  68. startDragSelector(posIn) {
  69. this._selectorPosStart = { x: posIn.x, y: posIn.y };
  70. this._selectorPosNow = { x: posIn.x, y: posIn.y };
  71. }
  72. updateDragSelector(posIn) {
  73. if (State.getCurrentState() != APP_STATE.NONE) return;
  74. App.clearSelectedTool();
  75. const currentObjects = Objects.get();
  76. const posRect = this.reverse(this._selectorPosStart, this._selectorPosNow);
  77. this._selectorPosNow = { x: posIn.x, y: posIn.y };
  78. this._selectorRect.x(posRect.x1);
  79. this._selectorRect.y(posRect.y1);
  80. this._selectorRect.width(posRect.x2 - posRect.x1);
  81. this._selectorRect.height(posRect.y2 - posRect.y1);
  82. this._selectorRect.visible(true);
  83. for (let i = 0; i < currentObjects.length; i = i + 1) {
  84. const aggregator = currentObjects[i];
  85. const object = aggregator.konvaObject;
  86. if (object == undefined) return;
  87. if (object.children != undefined && object.children.length > 0) {
  88. for (let j = 0; j < object.children.length; j++) {
  89. this.style(object.children[j], this._selectorRect, aggregator);
  90. }
  91. } else {
  92. this.style(object, this._selectorRect, aggregator);
  93. }
  94. }
  95. this._stage.draw();
  96. }
  97. style(object, selectorRect, aggregator) {
  98. if (object == undefined) return;
  99. if (object.attrs.selectable != undefined) {
  100. if (object.attrs.selectable == false) {
  101. return;
  102. }
  103. }
  104. if (this.hitCheck(object, selectorRect)) {
  105. object.stroke("#33BCFF");
  106. object.fill("#33BCFF");
  107. this.setObject(aggregator);
  108. } else {
  109. if (object.attrs.style != undefined) {
  110. this.removeObject(aggregator);
  111. object.stroke(object.attrs.style.stroke);
  112. object.fill(object.attrs.style.fill);
  113. } else {
  114. this.removeObject(aggregator);
  115. object.stroke("grey");
  116. }
  117. }
  118. }
  119. hitCheck(shape1, shape2) {
  120. let s1 = shape1.getClientRect();
  121. let s2 = shape2.getClientRect();
  122. let X = s1.x;
  123. let Y = s1.y;
  124. let A = s1.x + s1.width;
  125. let B = s1.y + s1.height;
  126. let X1 = s2.x;
  127. let A1 = s2.x + s2.width;
  128. let Y1 = s2.y;
  129. let B1 = s2.y + s2.height;
  130. if (A < X1 || A1 < X || B < Y1 || B1 < Y) {
  131. return false;
  132. } else {
  133. return true;
  134. }
  135. }
  136. setObject(object) {
  137. Objects.setSelectedOject(object);
  138. }
  139. removeObject(object) {
  140. Objects.removeSelectedOject(object);
  141. }
  142. reverse(r1, r2) {
  143. let r1x = r1.x,
  144. r1y = r1.y,
  145. r2x = r2.x,
  146. r2y = r2.y,
  147. d;
  148. if (r1x > r2x) {
  149. d = Math.abs(r1x - r2x);
  150. r1x = r2x;
  151. r2x = r1x + d;
  152. }
  153. if (r1y > r2y) {
  154. d = Math.abs(r1y - r2y);
  155. r1y = r2y;
  156. r2y = r1y + d;
  157. }
  158. return { x1: r1x, y1: r1y, x2: r2x, y2: r2y };
  159. }
  160. clear() {
  161. Objects.get().forEach(aggregator => {
  162. const object = aggregator.konvaObject;
  163. if (object == undefined) return;
  164. if (object.attrs.selectable != undefined) {
  165. if (object.attrs.selectable == false) {
  166. return;
  167. }
  168. }
  169. if (object.children != undefined && object.children.length > 0) {
  170. for (let j = 0; j < object.children.length; j++) {
  171. this.clearAggregator(object.children[j], aggregator);
  172. }
  173. } else {
  174. this.clearAggregator(object, aggregator);
  175. }
  176. });
  177. }
  178. clearAggregator(object, aggregator) {
  179. if (object == undefined) return;
  180. if (object.attrs.style != undefined) {
  181. this.removeObject(aggregator);
  182. object.stroke(object.attrs.style.stroke);
  183. object.fill(object.attrs.style.fill);
  184. } else {
  185. this.removeObject(aggregator);
  186. object.stroke("grey");
  187. }
  188. }
  189. configureSelectorEvents() {
  190. this._stage.on("mousedown touchstart", this.start.bind(this));
  191. this._stage.on("mousemove touchmove", this.move.bind(this));
  192. this._stage.on("mouseup touchend", this.end.bind(this));
  193. }
  194. start(event) {
  195. const tool = App.getSelectedTool();
  196. if (tool == undefined || tool.options.type != COMPONENT_TYPE.SELECTOR) {
  197. return;
  198. }
  199. const pos = {
  200. x: undefined,
  201. y: undefined
  202. };
  203. if (event.evt.type === "touchstart") {
  204. pos.x = event.target.pointerPos.x;
  205. pos.y = event.target.pointerPos.y;
  206. } else {
  207. pos.x = event.evt.layerX;
  208. pos.y = event.evt.layerY;
  209. }
  210. Stages.getCurrentKonvaLayer().add(this._selectorRect);
  211. this._mode = "drawing";
  212. this.startDragSelector(pos);
  213. }
  214. move(event) {
  215. const tool = App.getSelectedTool();
  216. if (tool == undefined || tool.options.type != COMPONENT_TYPE.SELECTOR) {
  217. return;
  218. }
  219. const pos = {
  220. x: undefined,
  221. y: undefined
  222. };
  223. if (event.evt.type === "touchmove") {
  224. pos.x = event.target.pointerPos.x;
  225. pos.y = event.target.pointerPos.y;
  226. } else {
  227. pos.x = event.evt.layerX;
  228. pos.y = event.evt.layerY;
  229. }
  230. if (this._mode === "drawing") {
  231. this.updateDragSelector(pos);
  232. }
  233. }
  234. end(event) {
  235. this._selectorRect.remove();
  236. this._mode = "";
  237. this._selectorRect.visible(false);
  238. this._stage.draw();
  239. }
  240. }
  241. export const selector = new Selector();