EditPolygonItem.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. import {
  2. SGraphItem,
  3. SGraphPointListDelete,
  4. SGraphPointListInsert,
  5. SGraphPointListUpdate,
  6. SLineStyle
  7. } from "@persagy-web/graph/lib";
  8. import { SKeyCode, SMouseEvent, SUndoStack } from "@persagy-web/base/";
  9. import { SColor, SLine, SLineCapStyle, SPainter, SPoint, SPolygonUtil, SRect } from "@persagy-web/draw";
  10. import { SItemStatus } from "@persagy-web/big";
  11. import { SMathUtil } from "@persagy-web/big/lib/utils/SMathUtil";
  12. /**
  13. * 编辑多边形
  14. *
  15. * @author 韩耀龙
  16. */
  17. export class EditPolygonItem extends SGraphItem {
  18. /** X坐标最小值 */
  19. private minX = Number.MAX_SAFE_INTEGER;
  20. /** X坐标最大值 */
  21. private maxX = Number.MIN_SAFE_INTEGER;
  22. /** Y坐标最小值 */
  23. private minY = Number.MAX_SAFE_INTEGER;
  24. /** Y坐标最大值 */
  25. private maxY = Number.MIN_SAFE_INTEGER;
  26. /** 轮廓线坐标 */
  27. private pointList: SPoint[] = [];
  28. // 获取当前状态
  29. get getPointList(): SPoint[] {
  30. return this.pointList;
  31. }
  32. // 编辑当前状态
  33. set setPointList(arr: SPoint[]) {
  34. this.pointList = arr;
  35. this.update();
  36. }
  37. /** 是否垂直水平绘制 */
  38. private _verAndLeve: Boolean = false;
  39. get verAndLeve(): Boolean {
  40. return this._verAndLeve;
  41. }
  42. set verAndLeve(bool: Boolean) {
  43. this._verAndLeve = bool;
  44. this.update();
  45. }
  46. // 当前状态
  47. protected _status: number = SItemStatus.Normal;
  48. // 获取当前状态
  49. get status(): SItemStatus {
  50. return this._status;
  51. }
  52. // 编辑当前状态
  53. set status(value: SItemStatus) {
  54. this._status = value;
  55. this.undoStack.clear();
  56. this.update();
  57. }
  58. /** 边框颜色 */
  59. _strokeColor: SColor = new SColor("#0091FF");
  60. /** 画笔颜色 */
  61. get strokeColor(): SColor {
  62. return this._strokeColor;
  63. }
  64. set strokeColor(v: SColor) {
  65. this._strokeColor = v;
  66. this.update();
  67. }
  68. /** 填充颜色 */
  69. _fillColor: SColor = new SColor("#1EE887");
  70. get fillColor(): SColor {
  71. return this._fillColor;
  72. }
  73. set fillColor(v: SColor) {
  74. this._fillColor = v;
  75. this.update();
  76. }
  77. /** 边框样式 */
  78. _lineStyle: SLineStyle = SLineStyle.Solid;
  79. get lineStyle(): SLineStyle {
  80. return this._lineStyle;
  81. }
  82. set lineStyle(v: SLineStyle) {
  83. this._lineStyle = v;
  84. this.update();
  85. }
  86. /** 边框的宽 只可输入像素宽*/
  87. _lineWidth: number = 4;
  88. get lineWidth(): number {
  89. return this._lineWidth;
  90. }
  91. set lineWidth(v: number) {
  92. this._lineWidth = v;
  93. this.update();
  94. }
  95. /** 是否闭合 */
  96. closeFlag: boolean = false;
  97. /** 鼠标移动点 */
  98. private lastPoint: SPoint | null = null;
  99. /** 当前鼠标获取顶点对应索引 */
  100. private curIndex: number = -1;
  101. /** 当前鼠标获取顶点对应坐标 */
  102. private curPoint: null | SPoint = null;
  103. /** 灵敏像素 */
  104. private len: number = 10;
  105. /** 场景像素 内部将灵敏像素换算为场景实际距离 */
  106. private scenceLen: number = 15;
  107. /** 场景像素 */
  108. private isAlt: boolean = false;
  109. /** undoredo堆栈 */
  110. protected undoStack: SUndoStack = new SUndoStack();
  111. /**
  112. * 构造函数
  113. *
  114. * @param parent 指向父对象
  115. */
  116. constructor(parent: SGraphItem | null) {
  117. super(parent);
  118. }
  119. //////////////////
  120. // 以下为对pointList 数组的操作方法
  121. /**
  122. * 储存新的多边形顶点
  123. *
  124. * @param x 点位得x坐标
  125. * @param y 点位得y坐标
  126. * @param i 储存所在索引
  127. * @return SPoint。添加的顶点
  128. */
  129. insertPoint(x: number, y: number, i: number | null = null): SPoint {
  130. const point = new SPoint(x, y);
  131. if (i == null) {
  132. this.pointList.push(point);
  133. } else {
  134. this.pointList.splice(i, 0, point);
  135. }
  136. this.update();
  137. return point;
  138. }
  139. /**
  140. * 删除点位
  141. *
  142. * @param i 删除点所在的索引
  143. * @return SPoint|null。索引不在数组范围则返回null
  144. */
  145. deletePoint(i: number | null = null): SPoint | null {
  146. let point = null;
  147. if (i != null) {
  148. if (i >= this.pointList.length || i < 0) {
  149. point = null;
  150. } else {
  151. point = new SPoint(this.pointList[i].x, this.pointList[i].y);
  152. this.pointList.splice(i, 1);
  153. }
  154. } else {
  155. if (this.pointList.length) {
  156. point = this.pointList[this.pointList.length - 1];
  157. this.pointList.pop();
  158. } else {
  159. point = null;
  160. }
  161. }
  162. this.curIndex = -1;
  163. this.curPoint = null;
  164. this.update();
  165. return point;
  166. }
  167. /**
  168. * 多边形顶点的移动位置
  169. *
  170. * @param x 点位得x坐标
  171. * @param y 点位得y坐标
  172. * @param i 点位得i坐标
  173. * @return 移动对应得点。如果索引无法找到移动顶点,则返回null
  174. */
  175. movePoint(x: number, y: number, i: number): SPoint | null {
  176. let point = null;
  177. if (i >= this.pointList.length || i < 0) {
  178. return null;
  179. }
  180. if (this.pointList.length) {
  181. this.pointList[i].x = x;
  182. this.pointList[i].y = y;
  183. }
  184. point = this.pointList[i];
  185. return point;
  186. }
  187. /**
  188. * 打印出多边形数组
  189. *
  190. * @return 顶点数组
  191. */
  192. PrintPointList(): SPoint[] {
  193. return this.pointList;
  194. }
  195. ////////////
  196. // 以下为三种状态下的绘制多边形方法
  197. /**
  198. * 展示状态 --绘制多边形数组
  199. *
  200. * @param painter 绘制类
  201. * @param pointList 绘制多边形数组
  202. */
  203. protected drawShowPolygon(painter: SPainter, pointList: SPoint[]): void {
  204. painter.save();
  205. painter.pen.lineCapStyle = SLineCapStyle.Square;
  206. painter.pen.color = this.strokeColor;
  207. painter.brush.color = this.fillColor;
  208. painter.pen.lineWidth = painter.toPx(this.lineWidth);
  209. if (this.lineStyle == SLineStyle.Dashed) {
  210. painter.pen.lineDash = [
  211. painter.toPx(this.lineWidth * 3),
  212. painter.toPx(this.lineWidth * 7)
  213. ];
  214. } else if (this.lineStyle == SLineStyle.Dotted) {
  215. painter.pen.lineDash = [
  216. painter.toPx(this.lineWidth),
  217. painter.toPx(this.lineWidth)
  218. ];
  219. }
  220. if (this.selected) {
  221. painter.shadow.shadowBlur = 10;
  222. painter.shadow.shadowColor = new SColor(`#00000033`);
  223. painter.shadow.shadowOffsetX = 5;
  224. painter.shadow.shadowOffsetY = 5;
  225. } else {
  226. painter.shadow.shadowColor = SColor.Transparent;
  227. }
  228. painter.drawPolygon([...pointList]);
  229. painter.restore();
  230. }
  231. /**
  232. * 创建状态 --绘制多边形数组
  233. *
  234. * @param painter 绘制类
  235. * @param pointList 绘制多边形数组
  236. */
  237. protected drawCreatePolygon(painter: SPainter, pointList: SPoint[]): void {
  238. painter.pen.lineCapStyle = SLineCapStyle.Square;
  239. painter.pen.color = this.strokeColor;
  240. painter.pen.lineWidth = painter.toPx(this.lineWidth);
  241. if (this.lastPoint && pointList.length) {
  242. painter.drawLine(
  243. pointList[pointList.length - 1].x,
  244. pointList[pointList.length - 1].y,
  245. this.lastPoint.x,
  246. this.lastPoint.y
  247. );
  248. }
  249. painter.drawPolyline(pointList);
  250. painter.pen.color = SColor.Transparent;
  251. painter.brush.color = new SColor(this.fillColor.value);
  252. painter.pen.lineWidth = painter.toPx(this.lineWidth);
  253. if (this.lastPoint) {
  254. painter.drawPolygon([...pointList, this.lastPoint]);
  255. // 绘制顶点块
  256. painter.pen.color = SColor.Black;
  257. painter.brush.color = SColor.White;
  258. pointList.forEach(item => {
  259. painter.drawCircle(item.x, item.y, painter.toPx(this.len / 2));
  260. });
  261. // 如果最后一个点在第一个点的灵敏度范围内,第一个点填充变红
  262. if (this.pointList.length) {
  263. if (
  264. SMathUtil.pointDistance(
  265. this.lastPoint.x,
  266. this.lastPoint.y,
  267. this.pointList[0].x,
  268. this.pointList[0].y
  269. ) < this.scenceLen
  270. ) {
  271. // 绘制第一个点的顶点块
  272. painter.pen.color = SColor.Black;
  273. painter.brush.color = SColor.Red;
  274. painter.drawCircle(
  275. this.pointList[0].x,
  276. this.pointList[0].y,
  277. painter.toPx(this.len / 2)
  278. );
  279. }
  280. }
  281. } else {
  282. painter.drawPolygon(pointList);
  283. }
  284. }
  285. /**
  286. *
  287. * 编辑状态 --绘制多边形数组
  288. *
  289. * @param painter 绘制类
  290. * @param pointList 绘制多边形数组
  291. */
  292. protected drawEditPolygon(painter: SPainter, pointList: SPoint[]): void {
  293. // 展示多边形
  294. painter.pen.lineCapStyle = SLineCapStyle.Square;
  295. painter.pen.color = this.strokeColor;
  296. painter.pen.lineWidth = painter.toPx(this.lineWidth);
  297. painter.brush.color = new SColor(this.fillColor.value);
  298. painter.drawPolygon([...pointList]);
  299. // 绘制顶点块
  300. painter.pen.color = SColor.Black;
  301. painter.brush.color = SColor.White;
  302. pointList.forEach((item, index) => {
  303. painter.brush.color = SColor.White;
  304. if (index == this.curIndex) {
  305. painter.brush.color = new SColor("#2196f3");
  306. }
  307. painter.drawCircle(item.x, item.y, painter.toPx(this.len / 2));
  308. });
  309. }
  310. /**
  311. * 编辑状态操作多边形数组
  312. *
  313. * @param event 鼠标事件
  314. *
  315. *
  316. */
  317. protected editPolygonPoint(event: SMouseEvent): void {
  318. // 判断是否为删除状态 isAlt = true为删除状态
  319. if (this.isAlt) {
  320. // 1 判断是否点击在多边形顶点
  321. let lenIndex = -1; // 当前点击到的点位索引;
  322. let curenLen = this.scenceLen; // 当前的灵敏度
  323. this.pointList.forEach((item, index) => {
  324. let dis = SMathUtil.pointDistance(
  325. event.x,
  326. event.y,
  327. item.x,
  328. item.y
  329. );
  330. if (dis < curenLen) {
  331. curenLen = dis;
  332. lenIndex = index;
  333. }
  334. });
  335. // 若点击到,对该索引对应的点做删除
  336. if (lenIndex != -1) {
  337. if (this.pointList.length <= 3) {
  338. return;
  339. }
  340. const delePoint = new SPoint(
  341. this.pointList[lenIndex].x,
  342. this.pointList[lenIndex].y
  343. );
  344. this.deletePoint(lenIndex);
  345. // 记录顶点操作记录压入堆栈
  346. this.recordAction(SGraphPointListDelete, [
  347. this.pointList,
  348. delePoint,
  349. lenIndex
  350. ]);
  351. }
  352. } else {
  353. // 1 判断是否点击在多边形顶点
  354. this.curIndex = -1;
  355. this.curPoint = null;
  356. let lenIndex = -1; // 当前点击到的点位索引;
  357. let curenLen = this.scenceLen; // 当前的灵敏度
  358. this.pointList.forEach((item, index) => {
  359. let dis = SMathUtil.pointDistance(
  360. event.x,
  361. event.y,
  362. item.x,
  363. item.y
  364. );
  365. if (dis < curenLen) {
  366. curenLen = dis;
  367. lenIndex = index;
  368. }
  369. });
  370. this.curIndex = lenIndex;
  371. // 2判断是否点击在多边形得边上
  372. if (-1 == lenIndex) {
  373. let len = SMathUtil.pointToLine(
  374. new SPoint(event.x, event.y),
  375. new SLine(this.pointList[0], this.pointList[1])
  376. ),
  377. index = 0;
  378. if (this.pointList.length > 2) {
  379. for (let i = 1; i < this.pointList.length; i++) {
  380. let dis = SMathUtil.pointToLine(
  381. new SPoint(event.x, event.y),
  382. new SLine(this.pointList[i], this.pointList[i + 1])
  383. );
  384. if (i + 1 == this.pointList.length) {
  385. dis = SMathUtil.pointToLine(
  386. new SPoint(event.x, event.y),
  387. new SLine(this.pointList[i], this.pointList[0])
  388. );
  389. }
  390. if (dis.MinDis < len.MinDis) {
  391. len = dis;
  392. index = i;
  393. }
  394. }
  395. }
  396. // 判断是否有点
  397. if (len.Point) {
  398. // 点在了多边形的边上
  399. if (len.MinDis <= this.scenceLen) {
  400. this.pointList.splice(index + 1, 0, len.Point);
  401. // 记录新增顶点操作记录压入堆栈
  402. this.recordAction(SGraphPointListInsert, [
  403. this.pointList,
  404. len.Point,
  405. index + 1
  406. ]);
  407. } else {
  408. //没点在多边形边上也没点在多边形顶点上
  409. super.onMouseDown(event);
  410. }
  411. }
  412. } else {
  413. // 当捕捉到顶点后 ,记录当前点的xy坐标,用于undo、redo操作
  414. this.curPoint = new SPoint(
  415. this.pointList[this.curIndex].x,
  416. this.pointList[this.curIndex].y
  417. );
  418. }
  419. // 刷新视图
  420. this.update();
  421. }
  422. }
  423. /////////////////////
  424. // undo、redo相关操作
  425. /**
  426. * 记录相关动作并推入栈中
  427. * @param SGraphCommand 相关命令类
  428. * @param any 对应传入参数
  429. */
  430. protected recordAction(SGraphCommand: any, any: any[]): void {
  431. // 记录相关命令并推入堆栈中
  432. const sgraphcommand = new SGraphCommand(this.scene, this, ...any);
  433. this.undoStack.push(sgraphcommand);
  434. }
  435. /**
  436. * 执行取消操作执行
  437. */
  438. undo(): void {
  439. if (this.status == SItemStatus.Normal) {
  440. return;
  441. }
  442. this.undoStack.undo();
  443. }
  444. /**
  445. * 执行重做操作执行
  446. */
  447. redo(): void {
  448. if (this.status == SItemStatus.Normal) {
  449. return;
  450. }
  451. this.undoStack.redo();
  452. }
  453. ///////////////////////////////
  454. // 以下为鼠标事件
  455. /**
  456. * 鼠标双击事件
  457. *
  458. * @param event 事件参数
  459. * @return boolean
  460. */
  461. onDoubleClick(event: SMouseEvent): boolean {
  462. // 如果位show状态 双击改对象则需改为编辑状态
  463. if (SItemStatus.Normal == this.status) {
  464. this.status = SItemStatus.Edit;
  465. this.grabItem(this);
  466. } else if (SItemStatus.Edit == this.status) {
  467. this.status = SItemStatus.Normal;
  468. this.releaseItem();
  469. }
  470. this.update();
  471. return true;
  472. } // Function onDoubleClick()
  473. /**
  474. * 键盘事件
  475. *
  476. * @param event 事件参数
  477. * @return boolean
  478. */
  479. onKeyDown(event: KeyboardEvent): boolean {
  480. if (this.status == SItemStatus.Normal) {
  481. return false;
  482. } else if (this.status == SItemStatus.Create) {
  483. if (event.code == "Enter") {
  484. // 当顶点大于二个时才又条件执行闭合操作并清空堆栈
  485. if (this.pointList.length > 2) {
  486. this.status = SItemStatus.Normal;
  487. //3 传递完成事件状态
  488. this.$emit("finishCreated");
  489. //1 grabItem 置为null
  490. this.releaseItem();
  491. }
  492. }
  493. } else if (this.status == SItemStatus.Edit) {
  494. if (event.key == "Alt") {
  495. this.isAlt = true;
  496. }
  497. }
  498. this.update();
  499. return true;
  500. } // Function onKeyDown()
  501. /**
  502. * 键盘键抬起事件
  503. *
  504. * @param event 事件参数
  505. * @return boolean
  506. */
  507. onKeyUp(event: KeyboardEvent): void {
  508. if (this.status == SItemStatus.Edit) {
  509. if (event.key == "Alt") {
  510. this.isAlt = false;
  511. } else if (event.keyCode == SKeyCode.Delete) {
  512. // 当多边形的顶点大于三个允许删除点
  513. if (this.pointList.length > 3) {
  514. this.deletePoint(this.curIndex);
  515. }
  516. }
  517. }
  518. this.update();
  519. } // Function onKeyUp()
  520. /**
  521. * 鼠标按下事件
  522. *
  523. * @param event 事件参数
  524. * @return boolean
  525. */
  526. onMouseDown(event: SMouseEvent): boolean {
  527. if (event.shiftKey || this.verAndLeve) {
  528. event = this.compare(event);
  529. }
  530. // 如果状态为编辑状态则添加点
  531. if (this.status == SItemStatus.Create) {
  532. // 新增顶点
  533. let len = -1;
  534. if (this.pointList.length) {
  535. len = SMathUtil.pointDistance(
  536. event.x,
  537. event.y,
  538. this.pointList[0].x,
  539. this.pointList[0].y
  540. );
  541. }
  542. if (this.pointList.length > 2 && len > 0 && len < this.scenceLen) {
  543. this.status = SItemStatus.Normal;
  544. //3 传递完成事件状态
  545. this.$emit("finishCreated");
  546. //1 grabItem 置为null
  547. this.releaseItem();
  548. } else {
  549. this.insertPoint(event.x, event.y);
  550. // 记录新增顶点操作记录压入堆栈
  551. let pos = new SPoint(event.x, event.y);
  552. this.recordAction(SGraphPointListInsert, [this.pointList, pos]);
  553. }
  554. } else if (this.status == SItemStatus.Edit) {
  555. // 对多边形数组做编辑操作
  556. this.editPolygonPoint(event);
  557. } else {
  558. return super.onMouseDown(event);
  559. }
  560. return true;
  561. } // Function onMouseDown()
  562. /**
  563. * 鼠标移入事件
  564. *
  565. * @param event 事件参数
  566. * @return boolean
  567. */
  568. onMouseEnter(event: SMouseEvent): boolean {
  569. return true;
  570. } // Function onMouseEnter()
  571. /**
  572. * 鼠标移出事件
  573. *
  574. * @param event 事件参数
  575. * @return boolean
  576. */
  577. onMouseLeave(event: SMouseEvent): boolean {
  578. return true;
  579. } // Function onMouseLeave()
  580. /**
  581. * 鼠标移动事件
  582. *
  583. * @param event 事件参数
  584. * @return boolean
  585. */
  586. onMouseMove(event: SMouseEvent): boolean {
  587. if (event.shiftKey || this.verAndLeve) {
  588. event = this.compare(event);
  589. }
  590. if (this.status == SItemStatus.Create) {
  591. this.lastPoint = new SPoint();
  592. this.lastPoint.x = event.x;
  593. this.lastPoint.y = event.y;
  594. this.update();
  595. } else if (this.status == SItemStatus.Edit) {
  596. if (event.buttons == 1) {
  597. if (-1 != this.curIndex) {
  598. this.pointList[this.curIndex].x = event.x;
  599. this.pointList[this.curIndex].y = event.y;
  600. }
  601. }
  602. this.update();
  603. } else {
  604. return super.onMouseMove(event);
  605. }
  606. return true;
  607. } // Function onMouseMove()
  608. /**
  609. * shift垂直水平创建或编辑
  610. *
  611. * @param event 事件
  612. */
  613. compare(event: SMouseEvent): SMouseEvent {
  614. if (this.pointList.length) {
  615. let last = new SPoint(event.x, event.y);
  616. if (this.status == SItemStatus.Create) {
  617. last = this.pointList[this.pointList.length - 1];
  618. } else if (this.status == SItemStatus.Edit) {
  619. if (this.curIndex > 1) {
  620. last = this.pointList[this.curIndex - 1];
  621. }
  622. }
  623. const dx = Math.abs(event.x - last.x);
  624. const dy = Math.abs(event.y - last.y);
  625. if (dy > dx) {
  626. event.x = last.x;
  627. } else {
  628. event.y = last.y;
  629. }
  630. }
  631. return event;
  632. } // Function compare()
  633. /**
  634. * 鼠标抬起事件
  635. *
  636. * @param event 事件参数
  637. * @return 是否处理
  638. */
  639. onMouseUp(event: SMouseEvent): boolean {
  640. if (this.status == SItemStatus.Edit) {
  641. if (-1 != this.curIndex) {
  642. const pos = new SPoint(
  643. this.pointList[this.curIndex].x,
  644. this.pointList[this.curIndex].y
  645. );
  646. this.recordAction(SGraphPointListUpdate, [
  647. this.pointList,
  648. this.curPoint,
  649. pos,
  650. this.curIndex
  651. ]);
  652. }
  653. } else if (this.status == SItemStatus.Normal) {
  654. this.moveToOrigin(this.x, this.y);
  655. return super.onMouseUp(event);
  656. }
  657. return true;
  658. } // Function onMouseUp()
  659. /**
  660. * 移动后处理所有坐标,并肩原点置为场景原点
  661. *
  662. * @param x x坐标
  663. * @param y y坐标
  664. */
  665. moveToOrigin(x: number, y: number): void {
  666. super.moveToOrigin(x, y);
  667. this.pointList = this.pointList.map(t => {
  668. t.x = t.x + x;
  669. t.y = t.y + y;
  670. return t;
  671. });
  672. this.x = 0;
  673. this.y = 0;
  674. } // Function moveToOrigin()
  675. /**
  676. * 适配事件
  677. *
  678. * @param event 事件参数
  679. * @return boolean
  680. */
  681. onResize(event: SMouseEvent): boolean {
  682. return true;
  683. } // Function onResize()
  684. /**
  685. * 取消操作
  686. *
  687. */
  688. cancelOperate(): void {
  689. // 当状态为展示状态
  690. if (this.status == SItemStatus.Create) {
  691. // 闭合多边形
  692. this.parent = null;
  693. } else if (this.status == SItemStatus.Edit) {
  694. // 编辑状态
  695. this.status = SItemStatus.Normal;
  696. }
  697. this.update();
  698. } // Function cancelOperate()
  699. /**
  700. * Item 对象边界区域
  701. *
  702. * @return 边界区域
  703. */
  704. boundingRect(): SRect {
  705. if (this.pointList.length) {
  706. this.minX = this.pointList[0].x;
  707. this.maxX = this.pointList[0].x;
  708. this.minY = this.pointList[0].y;
  709. this.maxY = this.pointList[0].y;
  710. this.pointList.forEach(it => {
  711. let x = it.x,
  712. y = it.y;
  713. if (x < this.minX) {
  714. this.minX = x;
  715. }
  716. if (y < this.minY) {
  717. this.minY = y;
  718. }
  719. if (x > this.maxX) {
  720. this.maxX = x;
  721. }
  722. if (y > this.maxY) {
  723. this.maxY = y;
  724. }
  725. });
  726. }
  727. return new SRect(
  728. this.minX,
  729. this.minY,
  730. this.maxX - this.minX,
  731. this.maxY - this.minY
  732. );
  733. } // Function boundingRect()
  734. /**
  735. * 判断点是否在区域内
  736. *
  737. * @param x
  738. * @param y
  739. */
  740. contains(x: number, y: number): boolean {
  741. let arr = this.pointList;
  742. if (arr.length < 3 || !SPolygonUtil.pointIn(x, y, arr)) {
  743. return false;
  744. }
  745. return true;
  746. } // Function contains()
  747. /**
  748. * Item绘制操作
  749. *
  750. * @param painter painter对象
  751. */
  752. onDraw(painter: SPainter): void {
  753. this.scenceLen = painter.toPx(this.len);
  754. // 当状态为展示状态
  755. if (this.status == SItemStatus.Normal) {
  756. // 闭合多边形
  757. this.drawShowPolygon(painter, this.pointList);
  758. } else if (this.status == SItemStatus.Create) {
  759. // 创建状态
  760. this.drawCreatePolygon(painter, this.pointList);
  761. } else {
  762. // 编辑状态
  763. this.drawEditPolygon(painter, this.pointList);
  764. }
  765. }
  766. }