SGraphEditScene.ts 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /*
  2. * *********************************************************************************************************************
  3. *
  4. * !!
  5. * .F88X
  6. * X8888Y
  7. * .}888888N;
  8. * i888888N; .:! .I$WI:
  9. * R888888I .'N88~ i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
  10. * .R888888I .;N8888~ .X8' "8I.!,/8" !%NY8`"8I8~~8>,88I
  11. * +888888N; .8888888Y "&&8Y.}8,
  12. * ./888888N; .R888888Y .'}~ .>}'.`+> i}! "i' +/' .'i~ !11,.:">, .~]! .i}i
  13. * ~888888%: .I888888l .]88~`1/iY88Ii+1'.R$8$8]"888888888> Y8$ W8E X8E W8888'188Il}Y88$*
  14. * 18888888 E8888881 .]W%8$`R8X'&8%++N8i,8N%N8+l8%` .}8N:.R$RE%N88N%N$K$R 188,FE$8%~Y88I
  15. * .E888888I .i8888888' .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
  16. * 8888888I .,N888888~ ~88i"8W,!N8*.I88.}888%F,i$88"F88" 888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
  17. * i888888N' I888Y ]88;/EX*IFKFK88X K8R .l8W 88Y ~88}'88E&%8W.X8N``]88!.$8K .:W8I
  18. * .i888888N; I8Y .&8$ .X88! i881.:%888>I88 ;88] +88+.';;;;:.Y88X 18N.,88l .+88/
  19. * .:R888888I
  20. * .&888888I Copyright (c) 2016-2020. 博锐尚格科技股份有限公司
  21. * ~8888'
  22. * .!88~ All rights reserved.
  23. *
  24. * *********************************************************************************************************************
  25. */
  26. import { SGraphScene, SGraphItem, SAnchorItem } from "@persagy-web/graph";
  27. import { SPoint } from "@persagy-web/draw";
  28. import { SMouseEvent, SUndoStack } from "@persagy-web/base";
  29. import { SRectSelectItem, SItemStatus } from "@persagy-web/big";
  30. import {
  31. SBaseArrowEdit,
  32. SBasePolygonEdit,
  33. SBaseCircleEdit,
  34. SBaseLineEdit,
  35. SGraphEdit,
  36. SBaseIconTextEdit,
  37. SBasePolylineEdit,
  38. SBaseTextEdit,
  39. SBaseImageEdit,
  40. SBaseRectEdit,
  41. SBaseTriangleEdit
  42. } from "./";
  43. import { SMathUtil } from "@persagy-web/big/lib/utils/SMathUtil";
  44. /**
  45. * Graph 图形引擎编辑场景类
  46. *
  47. * @author 韩耀龙 <han_yao_long@126.com>
  48. */
  49. export class SGraphEditScene extends SGraphScene {
  50. //属性
  51. /** undo/redo 存储栈 */
  52. protected undoStack = new SUndoStack();
  53. /** 编辑命令 */
  54. _editCmd: string = "";
  55. get editCmd(): string {
  56. return this._editCmd;
  57. }
  58. set editCmd(val: string) {
  59. this._editCmd = val;
  60. }
  61. /** 是否可编辑 */
  62. _isEditStatus: boolean = true;
  63. set isEditStatus(bol: boolean) {
  64. this._isEditStatus = bol;
  65. }
  66. get isEditStatus(): boolean {
  67. return this._isEditStatus;
  68. }
  69. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  70. //函数
  71. /**
  72. * 构造函数
  73. */
  74. constructor() {
  75. super();
  76. // 选择绑定选额item事件
  77. this.selectContainer.connect("selectChange", this, this.selectChange);
  78. }
  79. /**
  80. * 选中 item 触发方法
  81. *
  82. * @param obj 变化后的对象
  83. */
  84. selectChange(obj: any) {
  85. // do nothing
  86. }
  87. /**
  88. * 新增基础类直线
  89. *
  90. * @param event 鼠标事件参数
  91. */
  92. addLine(event: SMouseEvent): void {
  93. const data = {
  94. /** 名称 */
  95. name: "基础直线",
  96. /** 图标(Image),线类型(Line) */
  97. type: "Line",
  98. /** 缩放比例(Image),线类型(Line) */
  99. scale: { x: 1, y: 1, z: 1 },
  100. /** 缩放比例(Image),线类型(Line) */
  101. rolate: { x: 0, y: 0, z: 0 },
  102. /** 位置 */
  103. pos: { x: 0, y: 0 },
  104. /** 由应用自己定义 */
  105. properties: {
  106. type: "BaseLine" // 自定义类型用于区分mark与node
  107. },
  108. style: {
  109. line: [{ x: event.x, y: event.y }],
  110. default: {}
  111. }
  112. };
  113. const lineItem = new SBaseLineEdit(null, data);
  114. lineItem.status = SItemStatus.Create;
  115. this.addItem(lineItem);
  116. lineItem.selectable = true;
  117. this.grabItem = lineItem;
  118. lineItem.connect("finishCreated", this, this.finishCreated);
  119. lineItem.connect("onContextMenu", this, this.getItem);
  120. // 视图存在
  121. if (this.view) {
  122. this.view.update();
  123. }
  124. }
  125. /**
  126. * 新增折线
  127. *
  128. * @param event 鼠标事件
  129. * @return 新增的折线
  130. */
  131. addPolyLine(event: SMouseEvent): SBasePolylineEdit {
  132. const data = {
  133. name: "基础折线",
  134. type: "line",
  135. pos: { x: 0, y: 0 },
  136. properties: {
  137. type: "BasePolyline"
  138. },
  139. style: {
  140. outLine: [{ x: event.x, y: event.y }],
  141. default: {}
  142. }
  143. };
  144. const item = new SBasePolylineEdit(null, data);
  145. item.status = SItemStatus.Create;
  146. item.selectable = true;
  147. this.addItem(item);
  148. this.grabItem = item;
  149. item.connect("finishCreated", this, this.finishCreated);
  150. item.connect("onContextMenu", this, this.getItem);
  151. // 视图存在
  152. if (this.view) {
  153. this.view.update();
  154. }
  155. return item;
  156. }
  157. /**
  158. * 新增基础类图片
  159. *
  160. * @param event 鼠标事件参数
  161. * @return 新增的基础类图片
  162. */
  163. addImageItem(event: SMouseEvent): SBaseImageEdit {
  164. const data = {
  165. /** 名称 */
  166. name: "基础图片",
  167. num: 1,
  168. /** 图标(Image),线类型(Line) */
  169. type: "Image",
  170. /** 位置 */
  171. pos: { x: event.x, y: event.y },
  172. /** 由应用自己定义 */
  173. properties: {
  174. type: "BaseImage"
  175. },
  176. style: {
  177. default: {
  178. strokecolor: "#c0ccda",
  179. url: ""
  180. }
  181. }
  182. };
  183. const item = new SBaseImageEdit(null, data);
  184. item.selectable = true;
  185. item.moveable = true;
  186. this.addItem(item);
  187. item.connect("onContextMenu", this, this.getItem);
  188. this.finishCreated(item);
  189. return item;
  190. }
  191. /**
  192. * 新增基础类文本
  193. *
  194. * @param event 鼠标事件参数
  195. * @return 新增的基础类文本
  196. */
  197. addTextItem(event: SMouseEvent): SBaseTextEdit {
  198. const data = {
  199. /** 名称 */
  200. name: "基础文本",
  201. /** 图标 */
  202. type: "Text",
  203. /** 位置 */
  204. pos: { x: event.x, y: event.y },
  205. size: { width: 0, height: 0 },
  206. /** 由应用自己定义 */
  207. properties: {
  208. type: "BaseText" // 自定义类型用于区分mark与node
  209. },
  210. style: {
  211. default: {
  212. text: "请在右侧属性栏输入文字!",
  213. color: "#646c73",
  214. font: 14,
  215. backgroundColor: "#f7f9fa00"
  216. }
  217. }
  218. };
  219. const item = new SBaseTextEdit(null, data);
  220. item.moveTo(event.x, event.y);
  221. item.moveable = true;
  222. this.addItem(item);
  223. this.grabItem = null;
  224. item.connect("onContextMenu", this, this.getItem);
  225. this.finishCreated(item);
  226. return item;
  227. }
  228. /**
  229. * 添加基本矩形 item
  230. *
  231. * @param event 鼠标事件
  232. * @return 添加的基本矩形
  233. */
  234. addRectItem(event: SMouseEvent): SBaseRectEdit {
  235. const data = {
  236. name: "基础矩形",
  237. /** 图标(Image),线类型(Line) */
  238. type: "Zone",
  239. /** 位置 */
  240. pos: { x: 0, y: 0 },
  241. properties: {
  242. type: "BaseRect"
  243. },
  244. style: {
  245. default: {
  246. line: [{ x: event.x, y: event.y }]
  247. }
  248. }
  249. };
  250. const rectItem = new SBaseRectEdit(null, data);
  251. rectItem.status = SItemStatus.Create;
  252. this.addItem(rectItem);
  253. rectItem.selectable = true;
  254. rectItem.moveable = true;
  255. this.grabItem = rectItem;
  256. rectItem.isTransform = true;
  257. rectItem.connect("finishCreated", this, this.finishCreated);
  258. rectItem.connect("onContextMenu", this, this.getItem);
  259. if (this.view) {
  260. this.view.update();
  261. }
  262. return rectItem;
  263. }
  264. /**
  265. * 添加基本三角形 item
  266. *
  267. * @param event 鼠标事件
  268. * @return 添加的基本三角形
  269. */
  270. addTriangleItem(event: SMouseEvent): SBaseTriangleEdit {
  271. const data = {
  272. name: "基础三角形",
  273. type: "Zone",
  274. pos: { x: 0, y: 0 },
  275. properties: {
  276. type: "BaseTriangle"
  277. },
  278. style: {
  279. default: {
  280. line: [{ x: event.x, y: event.y }]
  281. }
  282. }
  283. };
  284. const triangleItem = new SBaseTriangleEdit(null, data);
  285. triangleItem.status = SItemStatus.Create;
  286. this.addItem(triangleItem);
  287. // this.undoStack.push(new SGraphAddCommand(this, triangleItem));
  288. triangleItem.selectable = true;
  289. triangleItem.moveable = true;
  290. this.grabItem = triangleItem;
  291. triangleItem.connect("finishCreated", this, this.finishCreated);
  292. triangleItem.connect("onContextMenu", this, this.getItem);
  293. // 视图存在
  294. if (this.view) {
  295. this.view.update();
  296. }
  297. return triangleItem;
  298. }
  299. /**
  300. * 添加基本圆
  301. *
  302. * @param event 鼠标事件
  303. * @return 添加的基本圆
  304. */
  305. addCircleItem(event: SMouseEvent): SBaseCircleEdit {
  306. const data = {
  307. name: "基础圆形",
  308. type: "Zone",
  309. pos: { x: 0, y: 0 },
  310. properties: {
  311. type: "BaseCircle"
  312. },
  313. style: {
  314. default: {},
  315. line: [{ x: event.x, y: event.y }]
  316. }
  317. };
  318. const circleItem = new SBaseCircleEdit(null, data);
  319. circleItem.status = SItemStatus.Create;
  320. circleItem.selectable = true;
  321. this.grabItem = circleItem;
  322. this.addItem(circleItem);
  323. circleItem.connect("finishCreated", this, this.finishCreated);
  324. circleItem.connect("onContextMenu", this, this.getItem);
  325. // 视图存在
  326. if (this.view) {
  327. this.view.update();
  328. }
  329. return circleItem;
  330. }
  331. /**
  332. * 添加基本多边形
  333. *
  334. * @param event 鼠标事件
  335. * @return 添加基的本多边形
  336. */
  337. addPolygonItem(event: SMouseEvent): SBasePolygonEdit {
  338. const data = {
  339. name: "基础多边形",
  340. type: "Zone",
  341. pos: { x: 0, y: 0 },
  342. properties: {
  343. type: "BasePolygon"
  344. },
  345. style: {
  346. outLine: [{ x: event.x, y: event.y }],
  347. default: {}
  348. }
  349. };
  350. const polygonItem = new SBasePolygonEdit(null, data);
  351. polygonItem.status = SItemStatus.Create;
  352. polygonItem.selectable = true;
  353. this.addItem(polygonItem);
  354. // this.undoStack.push(new SGraphAddCommand(this, polygonItem));
  355. this.grabItem = polygonItem;
  356. polygonItem.connect("finishCreated", this, this.finishCreated);
  357. polygonItem.connect("onContextMenu", this, this.getItem);
  358. // 视图存在
  359. if (this.view) {
  360. this.view.update();
  361. }
  362. return polygonItem;
  363. }
  364. /**
  365. * 添加基本箭头 item (直线类)
  366. *
  367. * @param event 鼠标事件
  368. */
  369. addBaseArrowsItem(event: SMouseEvent): void {
  370. const data = {
  371. name: "基础箭头",
  372. type: "Zone",
  373. pos: { x: 0, y: 0 },
  374. properties: {
  375. type: "BaseArrow"
  376. },
  377. style: {
  378. default: {
  379. line: [{ x: event.x, y: event.y }]
  380. }
  381. }
  382. };
  383. const arrowItem = new SBaseArrowEdit(null, data);
  384. arrowItem.status = SItemStatus.Create;
  385. arrowItem.moveable = true;
  386. this.addItem(arrowItem);
  387. // this.undoStack.push(new SGraphAddCommand(this, arrowItem));
  388. arrowItem.selectable = true;
  389. this.grabItem = arrowItem;
  390. arrowItem.connect("finishCreated", this, this.finishCreated);
  391. arrowItem.connect("onContextMenu", this, this.getItem);
  392. // 视图存在
  393. if (this.view) {
  394. this.view.update();
  395. }
  396. }
  397. /**
  398. * 添加Icon类 item
  399. *
  400. * @param event 鼠标事件
  401. */
  402. addBaseIconTextItem(event: SMouseEvent): void {
  403. const data = {
  404. /** 名称 */
  405. name: "icon",
  406. /** 图标 */
  407. type: "Text",
  408. /** 位置 */
  409. pos: { x: event.x, y: event.y },
  410. size: { width: 50, height: 50 },
  411. /** 由应用自己定义 */
  412. properties: {
  413. type: "BaseText" // 自定义类型用于区分mark与node
  414. },
  415. style: {
  416. default: {
  417. textList: [],
  418. url:
  419. "data:image/png;base64,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"
  420. }
  421. }
  422. };
  423. const icon = new SBaseIconTextEdit(null, data);
  424. icon.status = SItemStatus.Create;
  425. icon.moveable = true;
  426. this.addItem(icon);
  427. icon.selectable = true;
  428. this.grabItem = icon;
  429. icon.connect("finishCreated", this, this.finishCreated);
  430. icon.connect("onContextMenu", this, this.getItem);
  431. icon.$emit("finishCreated");
  432. // 视图存在
  433. if (this.view) {
  434. this.view.update();
  435. }
  436. }
  437. /**
  438. * 划线时点击位置是否是锚点
  439. *
  440. * @param event 事件
  441. * @param len 限制距离
  442. * @return 点击的锚点
  443. */
  444. clickIsAnchor(event: SMouseEvent): SAnchorItem | null {
  445. let minAnchor = null;
  446. let len = -1;
  447. // 遍历场景中的对象
  448. this.root.children.forEach(item => {
  449. // 子对象是 icontext 类型,且存在锚点
  450. if (
  451. item instanceof SBaseIconTextEdit &&
  452. item.anchorList &&
  453. item.anchorList.length
  454. ) {
  455. // 该对象中有图片,且为基础图片类型
  456. if (item.img && item.img instanceof SBaseImageEdit) {
  457. let scenePoint = item.img.mapFromScene(event.x, event.y);
  458. // 点击点在图片区域内
  459. if (item.img.contains(scenePoint.x, scenePoint.y)) {
  460. let anchor = item.anchorList[0];
  461. let anchorPoint = anchor.mapToScene(0, 0);
  462. let dis = SMathUtil.pointDistance(
  463. event.x,
  464. event.y,
  465. anchorPoint.x,
  466. anchorPoint.y
  467. );
  468. // 第一次进入循环
  469. if (len < 0) {
  470. minAnchor = anchor;
  471. len = dis;
  472. }
  473. // 得到距离最小的锚点
  474. if (dis < len) {
  475. minAnchor = anchor;
  476. len = dis;
  477. }
  478. }
  479. }
  480. }
  481. });
  482. return minAnchor;
  483. }
  484. /**
  485. * 对齐指定 item
  486. *
  487. * @param v 对齐类型
  488. */
  489. changeAlignItem(v: any): void {
  490. this.selectContainer.layout(v);
  491. }
  492. /**
  493. * 保存数据
  494. *
  495. * @return 返回需要保存的数据
  496. */
  497. saveMsgItem(): any {
  498. // do nothing
  499. }
  500. /**
  501. * 重做
  502. */
  503. redo(): void {
  504. // do nothing
  505. }
  506. /**
  507. * 撤销
  508. */
  509. undo(): void {
  510. // do nothing
  511. }
  512. /**
  513. * 完成创建的回调函数
  514. *
  515. * @param item 完成创建的item
  516. */
  517. finishCreated(item: SGraphItem): void {
  518. // do nothing
  519. }
  520. /**
  521. * 复制
  522. */
  523. copy(): void {
  524. // do nothing
  525. }
  526. /**
  527. * 粘贴
  528. */
  529. paste(): void {}
  530. /**
  531. * 选中状态方法
  532. *
  533. * @param item 选中的 item
  534. */
  535. toggleItem(item: SGraphItem): void {
  536. this.selectContainer.clear();
  537. this.selectContainer.toggleItem(item);
  538. }
  539. /**
  540. * 框选
  541. */
  542. addRectSelect(event: SMouseEvent) {
  543. let point = new SPoint(event.x, event.y);
  544. let rect = new SRectSelectItem(null, point);
  545. this.addItem(rect);
  546. this.grabItem = rect;
  547. }
  548. /**
  549. * 获取 item (常用与场景外的调用)
  550. *
  551. * @param event SMouseEvent 鼠标事件
  552. * @param item SGraphEdit|null 返回 item
  553. *
  554. */
  555. getItem(item: SGraphEdit | null, event: SMouseEvent[]) {}
  556. }