Undo1.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <template>
  2. <div>
  3. <el-button @click="addCircle">Circle</el-button>
  4. <el-button @click="addRect">Rect</el-button>
  5. <el-button @click="deleteItem">Delete</el-button>
  6. <el-button @click="undo">Undo</el-button>
  7. <el-button @click="redo">Redo</el-button>
  8. <el-button @click="log">日志</el-button>
  9. <canvas id="undoFrame" width="800" height="400"/>
  10. </div>
  11. </template>
  12. <script lang="ts">
  13. import { SMouseEvent, SUndoStack } from "@persagy-web/base";
  14. import { SColor, SPainter, SRect } from "@persagy-web/draw";
  15. import { SGraphAddCommand, SGraphItem, SGraphMoveCommand, SGraphScene, SGraphView } from "@persagy-web/graph";
  16. import { SPoint } from "@persagy-web/draw/lib";
  17. /**
  18. * Undo/Redo
  19. *
  20. * @author 郝洁 <haojie@persagy.com>
  21. */
  22. class RectItem extends SGraphItem {
  23. width = 100;
  24. height = 100;
  25. id = new Date().getTime() + '';
  26. constructor(parent: SGraphItem | null) {
  27. super(parent);
  28. this.moveable = true;
  29. this.selectable = true;
  30. this.selected = true;
  31. this.isTransform = true;
  32. this.rotate = 60;
  33. }
  34. boundingRect(): SRect {
  35. return new SRect(0, 0, this.width, this.height);
  36. }
  37. /**
  38. * Item 绘制操作
  39. * @param canvas 绘制对象
  40. */
  41. onDraw(canvas: SPainter): void {
  42. canvas.pen.color = SColor.Blue;
  43. canvas.pen.lineWidth = 5;
  44. canvas.brush.color = this.selected ? SColor.Red : SColor.Green;
  45. canvas.drawRect(0, 0, this.width, this.height)
  46. }
  47. }
  48. class CircleItem extends SGraphItem {
  49. r = 50;
  50. id = new Date().getTime() + ""
  51. constructor(parent: SGraphItem | null) {
  52. super(parent);
  53. this.moveable = true;
  54. this.selectable = true;
  55. this.isTransform = false;
  56. }
  57. boundingRect(): SRect {
  58. return new SRect(0, 0, this.r * 2, this.r * 2);
  59. }
  60. /**
  61. * Item 绘制操作
  62. * @param canvas 绘制对象
  63. */
  64. onDraw(canvas: SPainter): void {
  65. canvas.pen.color = SColor.Blue;
  66. canvas.pen.lineWidth = 5;
  67. canvas.brush.color = this.selected ? SColor.Red : SColor.Green;
  68. canvas.drawCircle(this.r, this.r, this.r);
  69. }
  70. }
  71. class SScene extends SGraphScene {
  72. undoStack = new SUndoStack();
  73. /** 定义命令 */
  74. cmd = 0;
  75. /**
  76. * 构造函数
  77. */
  78. constructor() {
  79. super();
  80. }
  81. onMouseUp(event: SMouseEvent): boolean {
  82. switch (this.cmd) {
  83. case 1:
  84. this.addCircle(event.x, event.y);
  85. break;
  86. case 2:
  87. this.addRect(event.x, event.y);
  88. break;
  89. default:
  90. super.onMouseUp(event);
  91. }
  92. this.cmd = 0;
  93. return false
  94. }
  95. private addCircle(x: number, y: number): void {
  96. let item = new CircleItem(null);
  97. item.moveTo(x - 50, y - 50);
  98. this.addItem(item);
  99. this.undoStack.push(new SGraphAddCommand(this, item));
  100. item.connect("onMove", this, this.onItemMove.bind(this));
  101. }
  102. private addRect(x: number, y: number): void {
  103. let item = new RectItem(null);
  104. item.moveTo(x - 50, y - 50);
  105. this.addItem(item);
  106. this.undoStack.push(new SGraphAddCommand(this, item));
  107. item.connect("onMove", this, this.onItemMove.bind(this));
  108. }
  109. onItemMove(item: SGraphItem, ...arg: any): void {
  110. this.undoStack.push(new SGraphMoveCommand(this, item, arg[0][0] as SPoint, arg[0][1] as SPoint));
  111. }
  112. }
  113. class TestView extends SGraphView {
  114. constructor(undoFrame) {
  115. super(undoFrame);
  116. }
  117. }
  118. export default {
  119. data() {
  120. return {
  121. scene: new SScene(),
  122. }
  123. },
  124. /**
  125. * 页面挂载
  126. */
  127. mounted(): void {
  128. let view = new TestView('undoFrame');
  129. view.scene = this.scene;//new SScene(); //this.data.scene;
  130. },
  131. methods: {
  132. addCircle() {
  133. this.scene.cmd = 1;
  134. },
  135. addRect() {
  136. this.scene.cmd = 2;
  137. },
  138. deleteItem() {
  139. },
  140. undo() {
  141. this.scene.undoStack.undo();
  142. },
  143. redo() {
  144. this.scene.undoStack.redo();
  145. },
  146. log() {
  147. let str = this.scene.undoStack.toLog();
  148. console.log(str)
  149. }
  150. }
  151. }
  152. </script>
  153. <style scoped>
  154. </style>