edittext.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <template>
  2. <div class="edit-line">
  3. <!-- 所有按钮 -->
  4. <div class="btn-list">
  5. <textarea ref="aaa" autofocus class="text"></textarea>
  6. <!-- <el-button @click="create">创建文本</el-button>
  7. <el-button @click="undo">删除文本</el-button>
  8. <el-button @click="undo">Undo</el-button>
  9. <el-button @click="redo">Redo</el-button>
  10. <el-button @click="reset">Reset</el-button>-->
  11. </div>
  12. <div class="content">
  13. <div class="left">
  14. <canvas @click="onMouseUp" id="edit_polygon" width="700" height="460" tabindex="0" />
  15. </div>
  16. <div class="line-property">
  17. <el-card shadow="always">
  18. <div slot="header" class="clearfix">
  19. <span>属性修改</span>
  20. </div>
  21. <div class="always-item">
  22. <span>字号:</span>
  23. <el-input-number size="small" v-model="size" @change="updateSize" :min="1" :max="50"></el-input-number>
  24. </div>
  25. <div class="always-item">
  26. <span>文本框:</span>
  27. <el-input
  28. v-model="text"
  29. @change="handleChangeText"
  30. type="textarea"
  31. :autosize="{ minRows: 1, maxRows: 1}"
  32. placeholder="请输入内容"
  33. style="width:200px;"
  34. ></el-input>
  35. </div>
  36. <div class="always-item">
  37. <span>线颜色:</span>
  38. <el-color-picker v-model="lineColor" @change="changeColor" show-alpha></el-color-picker>
  39. </div>
  40. </el-card>
  41. </div>
  42. </div>
  43. </div>
  44. </template>
  45. <script>
  46. import {
  47. SGraphScene,
  48. SGraphView,
  49. SGraphPropertyCommand,
  50. SGraphMoveCommand
  51. } from "@persagy-web/graph/";
  52. import { SUndoStack } from "@persagy-web/base/lib";
  53. import { SFont } from "@persagy-web/draw/lib";
  54. import { SPoint, SColor } from "@persagy-web/draw/";
  55. //注: 开发者引入 SImageItem 包为: import {SImageItem} from "@persagy-web/edit/";
  56. import { EditText } from "./../../../../../guides/edit/items/src/EditText";
  57. import { hexify } from "./../../../../public/until/rgbaUtil";
  58. class SScene extends SGraphScene {
  59. undoStack = new SUndoStack();
  60. textItem = new EditText(null);
  61. constructor() {
  62. super();
  63. this.textItem.moveable = true;
  64. this.textItem.x = 100;
  65. this.textItem.y = 100;
  66. this.addItem(this.textItem);
  67. this.textItem.connect("onMove", this, this.onItemMove.bind(this));
  68. }
  69. updateText(str) {
  70. if (this.textItem.text !== str) {
  71. let old = this.textItem.text;
  72. this.textItem.text = str;
  73. this.undoStack.push(
  74. new SGraphPropertyCommand(this, this.textItem, "text", old, str)
  75. );
  76. }
  77. }
  78. updateColor(color) {
  79. if (this.textItem.color !== color) {
  80. let old = this.textItem.color;
  81. this.textItem.color = color;
  82. this.undoStack.push(
  83. new SGraphPropertyCommand(this, this.textItem, "color", old, color)
  84. );
  85. }
  86. }
  87. updateSize(size) {
  88. if (this.textItem.font.size !== size) {
  89. let old = new SFont(this.textItem.font);
  90. let font = new SFont(this.textItem.font);
  91. font.size = size;
  92. this.textItem.font = font;
  93. this.undoStack.push(
  94. new SGraphPropertyCommand(this, this.textItem, "font", old, font)
  95. );
  96. }
  97. }
  98. onItemMove(item, ...arg) {
  99. this.undoStack.push(
  100. new SGraphMoveCommand(this, item, arg[0][0], arg[0][1])
  101. );
  102. }
  103. }
  104. class TestView extends SGraphView {
  105. constructor() {
  106. super("edit_polygon");
  107. }
  108. }
  109. export default {
  110. name: "edittext",
  111. data() {
  112. return {
  113. scene: new SScene(),
  114. text: "测试文本",
  115. size: 20,
  116. color: "#333333"
  117. };
  118. },
  119. mounted() {
  120. let view = new TestView();
  121. this.scene.updateText(this.text);
  122. this.scene.updateColor(this.color);
  123. this.scene.updateSize(this.size);
  124. view.scene = this.scene;
  125. // this.scene.onMouseUp = this.onMouseUp;
  126. },
  127. methods: {
  128. handleChangeText(text) {
  129. this.scene.updateText(text);
  130. },
  131. handleChangeColor(color) {
  132. this.scene.updateColor(color);
  133. },
  134. handleChangeSize(size) {
  135. this.scene.updateSize(size);
  136. },
  137. undo() {
  138. this.scene.undoStack.undo();
  139. },
  140. redo() {
  141. this.scene.undoStack.redo();
  142. },
  143. reset() {
  144. this.text = "测试文本";
  145. this.size = 20;
  146. this.color = "#333333";
  147. this.scene.updateText(this.text);
  148. this.scene.updateColor(this.color);
  149. this.scene.updateSize(this.size);
  150. },
  151. // 改变颜色
  152. changeColor(val) {
  153. this.scene.updateColor(hexify(val));
  154. },
  155. // 设置tooltip位置
  156. /**
  157. * raduis 灵敏范围
  158. * e 鼠标事件对象
  159. * tipDom 浮动得dom
  160. * boxDom 最外层盒子
  161. * offset 偏移量
  162. */
  163. toolTipPosition(radius, e, tipDom, offset = 0) {
  164. // 滚动高度
  165. const screenTop =
  166. document.documentElement.scrollTop || document.body.scrollTop;
  167. const screenLeft =
  168. document.documentElement.scrollLeft || document.body.scrollLeft;
  169. radius = radius + offset;
  170. const mapBox = document.getElementById("edit_polygon");
  171. // 测试边界mousePosition = 1(右下) 2 (右上)3 (左上) 4 (左下)
  172. const mousePosition = this.Boxboundary(radius, e, mapBox);
  173. const absPosition = this.offsetTL(mapBox);
  174. const absPositionLeft = absPosition.left;
  175. const absPositionTop = absPosition.top;
  176. const mClientY = e.clientY + screenTop;
  177. const mClientX = e.clientX + screenLeft;
  178. const fuzzy_model_width = tipDom.offsetWidth;
  179. const fuzzy_model_height = tipDom.offsetHeight;
  180. // let offsetTL
  181. if (mousePosition == 2) {
  182. tipDom.style.left = `${mClientX - absPositionLeft + offset}px`;
  183. tipDom.style.top = `${mClientY -
  184. fuzzy_model_height -
  185. absPositionTop -
  186. offset}px`;
  187. } else if (mousePosition == 3) {
  188. tipDom.style.left = `${mClientX -
  189. fuzzy_model_width -
  190. absPositionLeft -
  191. offset}px`;
  192. tipDom.style.top = `${mClientY -
  193. fuzzy_model_height -
  194. absPositionTop -
  195. offset}px`;
  196. } else if (mousePosition == 4) {
  197. tipDom.style.left = `${mClientX -
  198. fuzzy_model_width -
  199. absPositionLeft -
  200. offset}px`;
  201. tipDom.style.top = `${mClientY - absPositionTop + offset}px`;
  202. } else {
  203. tipDom.style.left = `${mClientX - absPositionLeft + offset}px`;
  204. tipDom.style.top = `${mClientY - absPositionTop + offset}px`;
  205. }
  206. },
  207. Boxboundary(radius, event, box) {
  208. const screenTop =
  209. document.documentElement.scrollTop || document.body.scrollTop;
  210. const boxWidth = Number(box.style.width.slice(0, -2));
  211. const boxHeight = Number(box.style.height.slice(0, -2));
  212. const absPosition = this.offsetTL(box);
  213. const boxClientX = absPosition.left;
  214. const boxClientY = absPosition.top;
  215. const mouseX = event.clientX;
  216. const mouseY = event.clientY + screenTop;
  217. if (mouseY >= boxClientY + boxHeight - radius) {
  218. if (mouseX <= radius + boxClientX) {
  219. return 2;
  220. } else if (mouseX >= boxClientX + boxWidth - radius) {
  221. return 3;
  222. } else {
  223. return 2;
  224. }
  225. } else if (mouseX >= boxClientX + boxWidth - radius) {
  226. return 4;
  227. } else {
  228. return 1;
  229. }
  230. },
  231. offsetTL(obj) {
  232. //获取到body的offsetTop和offsetLeft
  233. var t = 0,
  234. l = 0;
  235. while (obj) {
  236. t = t + obj.offsetTop;
  237. l = l + obj.offsetLeft;
  238. obj = obj.offsetParent;
  239. }
  240. return {
  241. top: t,
  242. left: l
  243. };
  244. },
  245. onMouseUp(event) {
  246. const dom = this.$refs.aaa;
  247. console.log('eventevent',event)
  248. this.toolTipPosition(1, event, dom, 0);
  249. }
  250. },
  251. watch: {
  252. // cmdStatus(val) {
  253. // this.scene.cmdStatus = val;
  254. // }
  255. }
  256. };
  257. </script>
  258. <style scoped lang="less">
  259. .text {
  260. // border: 0px;
  261. max-height: 300px;
  262. max-height: 100px;
  263. min-width: 20px; /*自动适应父布局宽度*/
  264. overflow: auto;
  265. word-break: break-all;
  266. outline: none;
  267. // background: #409eff;
  268. position: absolute;
  269. left: 0;
  270. top: 0;
  271. }
  272. .edit-line {
  273. width: 100%;
  274. height: 500px;
  275. position: relative;
  276. .content {
  277. display: flex;
  278. justify-content: flex-start;
  279. .left {
  280. margin-right: 20px;
  281. }
  282. .line-property {
  283. width: 300px;
  284. margin-top: 20px;
  285. .always {
  286. width: 100%;
  287. height: 100%;
  288. }
  289. .always-item {
  290. display: flex;
  291. margin-top: 10px;
  292. justify-content: space-between;
  293. }
  294. }
  295. }
  296. .heightLight {
  297. color: #409eff;
  298. border-color: #c6e2ff;
  299. background-color: #ecf5ff;
  300. }
  301. }
  302. </style>