undo.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <template>
  2. <div class="edit-line">
  3. <div class="btn-list">
  4. <el-button
  5. :class="[cmdStatus=='createLine' ? 'heightLight' : '']"
  6. size="small"
  7. @click="create('createLine')"
  8. >画线</el-button>
  9. <el-button
  10. :class="[cmdStatus=='createText' ? 'heightLight' : '']"
  11. size="small"
  12. @click="create('createText')"
  13. >文本</el-button>
  14. <el-button
  15. :class="[cmdStatus=='createImage' ? 'heightLight' : '']"
  16. size="small"
  17. @click="create('createImage')"
  18. >图片</el-button>
  19. <el-button size="small" @click="undo">undo</el-button>
  20. <el-button size="small" @click="redo">redo</el-button>
  21. <!-- <el-tooltip class="item" effect="dark" content="双击 item 也可进入编辑状态" placement="top-start"> -->
  22. <!-- <el-button :class="[cmdStatus=='edit' ? 'heightLight' : '']" size="small" @click="edit">编辑</el-button> -->
  23. <!-- </el-tooltip> -->
  24. <el-button
  25. :class="[cmdStatus=='deleteItem' ? 'heightLight' : '']"
  26. size="small"
  27. @click="deleteItem"
  28. >删除</el-button>
  29. </div>
  30. <div class="content">
  31. <div class="left">
  32. <canvas id="edit_line" width="700" height="460" tabindex="0" />
  33. </div>
  34. </div>
  35. </div>
  36. </template>
  37. <script>
  38. import { SGraphScene, SGraphView, SLineStyle } from "@persagy-web/graph/";
  39. import { SItemStatus } from "@persagy-web/big/lib/enums/SItemStatus";
  40. import { SPoint } from "@persagy-web/draw/";
  41. import { SMouseEvent, SUndoStack } from "@persagy-web/base/lib";
  42. import { EditLineItem } from "./../../../../guides/edit/items/src/EditLineItem";
  43. import { EditImageItem } from "./../../../../guides/edit/items/src/EditImageItem";
  44. import { hexify } from "./../../../public/until/rgbaUtil";
  45. import { EditText } from "./../../../../guides/edit/items/src/EditText";
  46. import { SGraphAddCommand } from "./../../../../guides/edit/undo/src/SGraphAddCommand";
  47. class SScene extends SGraphScene {
  48. undoStack = new SUndoStack();
  49. editCmd = "";
  50. constructor() {
  51. super();
  52. this.editCmd = "";
  53. this.selectContainer.connect("listChange", this, this.listChange);
  54. }
  55. onMouseDown(event) {
  56. if (this.editCmd == "createLine") {
  57. this.addLine(event);
  58. this.clearCmdStatus();
  59. } else if (this.editCmd == "createText") {
  60. this.addText(event);
  61. this.clearCmdStatus();
  62. } else if (this.editCmd == "createImage") {
  63. this.addImage(event);
  64. this.clearCmdStatus();
  65. } else if (this.editCmd == "") {
  66. super.onMouseDown(event);
  67. }
  68. }
  69. // 清空命令
  70. clearCmdStatus() {
  71. this.editCmd = "";
  72. }
  73. // 新增线
  74. addLine(event) {
  75. const lineItem = new EditLineItem(null, []);
  76. lineItem.status = SItemStatus.Create;
  77. lineItem.selectable = true;
  78. lineItem.x = event.x;
  79. lineItem.y = event.y;
  80. lineItem.connect("finishCreated", this, this.finishCreated);
  81. this.addItem(lineItem);
  82. this.undoStack.push(new SGraphAddCommand(this, lineItem));
  83. this.grabItem = lineItem;
  84. }
  85. // 新增文本
  86. addText(event) {
  87. const textItem = new EditText(null);
  88. textItem.text = "测试文本";
  89. textItem.selectable = true;
  90. textItem.moveable = true;
  91. textItem.x = event.x;
  92. textItem.y = event.y;
  93. this.addItem(textItem);
  94. this.undoStack.push(new SGraphAddCommand(this, textItem));
  95. this.grabItem = textItem;
  96. textItem.connect("finishCreated", this, this.finishCreated);
  97. }
  98. // 新增图片
  99. addImage(event) {
  100. const imageItem = new EditImageItem(null);
  101. imageItem.url =
  102. "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591685374103&di=cd5a56b2e3f5e12d7145b967afbcfb7a&imgtype=0&src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201408%2F05%2F20140805191039_cuTPn.jpeg";
  103. imageItem.width = 100;
  104. imageItem.height = 100;
  105. imageItem.selectable = true;
  106. imageItem.moveable = true;
  107. imageItem.x = event.x;
  108. imageItem.y = event.y;
  109. this.addItem(imageItem);
  110. this.undoStack.push(new SGraphAddCommand(this, imageItem));
  111. }
  112. // 完成item绘制
  113. finishCreated() {
  114. this.grabItem = null;
  115. }
  116. undo() {
  117. this.undoStack.undo();
  118. this.view.update();
  119. }
  120. redo() {
  121. this.undoStack.redo();
  122. this.view.update();
  123. }
  124. listChange(list) {
  125. this.emitChoice(list);
  126. }
  127. delete() {
  128. let itemList = this.selectContainer.itemList;
  129. itemList.forEach((element) => {
  130. this.removeItem(element);
  131. });
  132. if (this.view) {
  133. this.view.update();
  134. }
  135. return itemList;
  136. }
  137. }
  138. //注: 开发者引入 SWallItem 包为: import {SWallItem} from "@persagy-web/edit/";
  139. export default {
  140. name: "editLine",
  141. data() {
  142. return {
  143. scene: null,
  144. view: null,
  145. isCreated: false, //是否创建完成
  146. cmdStatus: "", //选中状态
  147. };
  148. },
  149. mounted() {
  150. console.log(SGraphAddCommand);
  151. this.view = new SGraphView("edit_line");
  152. this.scene = new SScene();
  153. this.view.scene = this.scene;
  154. },
  155. methods: {
  156. create(val) {
  157. this.scene.editCmd = val;
  158. },
  159. undo() {
  160. this.scene.undo();
  161. },
  162. redo() {
  163. this.scene.redo();
  164. },
  165. deleteItem() {
  166. this.scene.delete();
  167. },
  168. },
  169. watch: {},
  170. beforeCreate() {},
  171. };
  172. </script>
  173. <style scoped lang="less">
  174. .edit-line {
  175. width: 100%;
  176. height: 500px;
  177. .content {
  178. display: flex;
  179. justify-content: flex-start;
  180. .left {
  181. margin-right: 20px;
  182. }
  183. .line-property {
  184. width: 300px;
  185. margin-top: 20px;
  186. .always {
  187. width: 100%;
  188. height: 100%;
  189. }
  190. .always-item {
  191. display: flex;
  192. margin-top: 10px;
  193. justify-content: space-between;
  194. }
  195. }
  196. }
  197. .heightLight {
  198. color: #409eff;
  199. border-color: #c6e2ff;
  200. background-color: #ecf5ff;
  201. }
  202. }
  203. </style>