TextItem.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <template>
  2. <div>
  3. <el-row>
  4. <el-input v-model="input" @keyup.native="handleKeyup" style="width:200px;" placeholder="请输入内容"></el-input>
  5. <el-button @click="undo">Undo</el-button>
  6. <el-button @click="redo">Redo</el-button>
  7. </el-row>
  8. <canvas id="TextItem1" width="400" height="400" />
  9. </div>
  10. </template>
  11. <script lang="ts">
  12. import { SMouseEvent, SUndoStack } from "@saga-web/base";
  13. import { SColor, SPainter, SRect, SFont, SSize, STextBaseLine } from "@saga-web/draw";
  14. import { SObjectItem } from "@saga-web/big/lib/items/SObjectItem";
  15. import { SGraphItem, SGraphScene, SGraphView } from "@saga-web/graph";
  16. import { SGraphCommand } from "@saga-web/graph/lib";
  17. import { SUndoCommand } from "@saga-web/base/lib";
  18. import { SPoint } from "@saga-web/draw/lib";
  19. class TextItem extends SObjectItem {
  20. /** 文本内容 */
  21. private _text: string = "";
  22. get text(): string {
  23. return this._text;
  24. }
  25. set text(v: string) {
  26. this._text = v;
  27. this.update();
  28. }
  29. /** 文本颜色 */
  30. private _color: string ="#333333";
  31. get color():string {
  32. return this._color;
  33. }
  34. set color(v: string) {
  35. this._color = v;
  36. this.update();
  37. }
  38. /** 字体 */
  39. private _font: SFont;
  40. get font():SFont {
  41. return this._font;
  42. }
  43. set font(v: SFont) {
  44. this._font = v;
  45. this.update();
  46. }
  47. /** 文本绘制最大宽 */
  48. maxWidth: number | undefined = undefined;
  49. /**
  50. * 构造函数
  51. *
  52. * @param parent 指向父Item
  53. * @param str 文本内容
  54. */
  55. constructor(parent: SGraphItem | null = null, str: string = "") {
  56. super(parent);
  57. this._text = str;
  58. this._font = new SFont();
  59. this.moveable = true;
  60. this.selectable = true;
  61. this.selected = true;
  62. }
  63. /**
  64. * 对象边界区域
  65. *
  66. * @return 边界区域
  67. */
  68. boundingRect(): SRect {
  69. return new SRect(this.x, this.y, this.width, this.height);
  70. }
  71. protected onResize(oldSize: SSize, newSize: SSize) {
  72. console.log("resize",oldSize,newSize)
  73. }
  74. /**
  75. * Item绘制操作
  76. *
  77. * @param canvas 画布
  78. */
  79. onDraw(canvas: SPainter): void {
  80. // this.width = canvas.toPx(canvas.textWidth(this.text));
  81. // this.height = canvas.toPx(this.font.size);
  82. // canvas.font.textBaseLine = this.font.textBaseLine;
  83. // canvas.font.textDirection = this.font.textDirection;
  84. // canvas.font.textAlign = this.font.textAlign;
  85. // canvas.font.name = this.font.name;
  86. // canvas.font.size = canvas.toPx(this.font.size);
  87. // canvas.brush.color = new SColor(this.color);
  88. // canvas.drawText(this.text, 0, 0, this.maxWidth);
  89. canvas.brush.color = SColor.White;
  90. canvas.drawRect(this.x, this.y, this.width, this.height);
  91. //绘制文本
  92. canvas.brush.color = new SColor(this.color);
  93. canvas.font = this.font;
  94. canvas.drawText(this.text, this.x, this.y , this.maxWidth);
  95. }
  96. }
  97. class SScene extends SGraphScene {
  98. undoStack = new SUndoStack();
  99. textItem: SGraphItem = new TextItem(null);
  100. constructor() {
  101. super();
  102. this.addItem(this.textItem);
  103. this.textItem.connect("onMove", this, this.onItemMove.bind(this));
  104. }
  105. updateText(str: string): void {
  106. if(this.textItem.text !== str) {
  107. let old = this.textItem.text;
  108. this.textItem.text = str;
  109. this.undoStack.push(new SGraphPropertyCommand(this, this.textItem, "text", old, str));
  110. }
  111. }
  112. onItemMove(item: SGraphItem, ...arg: any): void {
  113. this.undoStack.push(new SGraphMoveCommand(this, item, arg[0][0] as SPoint, arg[0][1] as SPoint));
  114. }
  115. }
  116. class TestView extends SGraphView {
  117. constructor() {
  118. super("TextItem1");
  119. }
  120. }
  121. /**
  122. * 属性修改命令类
  123. *
  124. * @author 张宇(taohuzy@163.com)
  125. */
  126. class SGraphPropertyCommand<T> extends SGraphCommand {
  127. item: SGraphItem;
  128. /** 属性名称 */
  129. propName: string;
  130. /** 属性旧值 */
  131. oldProp: T;
  132. /** 属性新值 */
  133. newProp: T;
  134. /**
  135. * 构造函数
  136. *
  137. * @param scene 命令所属的场景类
  138. * @param item 命令所属的item类
  139. * @param propName 修改的属性名称
  140. * @param oldProp 修改前的属性值
  141. * @param newProp 修改后的属性值
  142. */
  143. constructor(scene: SGraphScene, item: SGraphItem, propName: string, oldProp: T, newProp: T) {
  144. super(scene);
  145. this.item = item;
  146. this.propName = propName;
  147. this.oldProp = oldProp;
  148. this.newProp = newProp;
  149. }
  150. /**
  151. * redo操作
  152. */
  153. redo(): void {
  154. this.item[this.propName] = this.newProp;
  155. this.item.update();
  156. }
  157. /**
  158. * undo操作
  159. */
  160. undo(): void {
  161. this.item[this.propName] = this.oldProp;
  162. this.item.update();
  163. }
  164. }
  165. class SGraphMoveCommand extends SGraphCommand {
  166. item: SGraphItem;
  167. old: SPoint;
  168. pos: SPoint;
  169. constructor(scene: SGraphScene, item: SGraphItem, old: SPoint, pos: SPoint) {
  170. super(scene);
  171. this.item = item;
  172. this.old = old;
  173. this.pos = pos;
  174. }
  175. mergeWith(command: SUndoCommand): boolean {
  176. if (command instanceof SGraphMoveCommand && command.item == this.item) {
  177. command.pos = this.pos;
  178. return true;
  179. }
  180. return false;
  181. }
  182. redo(): void {
  183. this.item.pos = new SPoint(this.pos.x, this.pos.y);
  184. this.item.update();
  185. }
  186. undo(): void {
  187. this.item.pos = new SPoint(this.old.x, this.old.y);
  188. this.item.update();
  189. }
  190. }
  191. export default {
  192. mounted(): void {
  193. let view = new TestView();
  194. this.scene.updateText(this.input);
  195. view.scene = this.scene;
  196. },
  197. data() {
  198. return {
  199. scene: new SScene(),
  200. input: '测试文本',
  201. }
  202. },
  203. methods: {
  204. handleKeyup(value): void {
  205. this.scene.updateText(this.input);
  206. },
  207. undo(): void {
  208. this.scene.undoStack.undo();
  209. },
  210. redo(): void {
  211. this.scene.undoStack.redo();
  212. }
  213. },
  214. }
  215. </script>
  216. <style scoped>
  217. </style>