text.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <template>
  2. <GeoTeleport :menus="menus" class="geo-teleport-use">
  3. <template v-slot="{ data }">
  4. <template v-if="data.key === 'color'">
  5. <Color v-model:color="color">
  6. <span class="color" :style="{ backgroundColor: color }"></span>
  7. </Color>
  8. </template>
  9. <template v-if="data.key === 'fontSize'">
  10. <ui-input
  11. type="select"
  12. :options="sizeOption"
  13. class="geo-input"
  14. dire="top"
  15. floatingClass="select-floating"
  16. v-model="size"
  17. />
  18. <span class="font-size">{{ size }}</span>
  19. </template>
  20. </template>
  21. </GeoTeleport>
  22. <div class="text-model" v-if="updateText">
  23. <div class="text-input">
  24. <ui-input
  25. ref="inputTextRef"
  26. v-model="text"
  27. width="100%"
  28. :maxlength="20"
  29. height="64px"
  30. @blur="updateText = false"
  31. />
  32. </div>
  33. </div>
  34. </template>
  35. <script setup lang="ts">
  36. import GeoTeleport from "@/views/graphic/geos/geo-teleport.vue";
  37. import UiInput from "@/components/base/components/input/index.vue";
  38. import UiIcon from "@/components/base/components/icon/index.vue";
  39. import { FocusVector, drawRef, useChange } from "@/hook/useGraphic";
  40. import { computed, ref, watch, watchEffect } from "vue";
  41. import { dataService } from "@/graphic/Service/DataService";
  42. import { debounce } from "@/utils";
  43. import GeoActions from "@/graphic/enum/GeoActions";
  44. import Color from "@/components/color/index.vue";
  45. import VectorCategory from "@/graphic/enum/VectorCategory";
  46. const props = defineProps<{ geo: FocusVector }>();
  47. const inputTextRef = ref();
  48. const updateText = ref(false);
  49. const vector = computed(() => {
  50. let vectorId = props.geo.vectorId;
  51. if (props.geo.category === VectorCategory.Point.FixPoint) {
  52. vectorId = dataService.getPoint(props.geo.vectorId)?.linkedTextId;
  53. }
  54. return dataService.getText(vectorId);
  55. });
  56. const text = ref("");
  57. const color = ref("#000000");
  58. const size = ref(18);
  59. const syncVector = ([text, size, color]) => {
  60. console.log(text, size, color);
  61. vector.value.setValue(text);
  62. vector.value.setColor(color);
  63. vector.value.setFontSize(size);
  64. drawRef.value.renderer.autoRedraw();
  65. drawRef.value.history.save();
  66. };
  67. watchEffect(() => {
  68. if (inputTextRef.value) {
  69. inputTextRef.value.vmRef.input.focus();
  70. }
  71. });
  72. useChange(() => {
  73. console.log(vector.value);
  74. color.value = vector.value.color;
  75. size.value = vector.value.fontSize;
  76. text.value = vector.value.value;
  77. });
  78. watch(() => [text.value, size.value, color.value], debounce(syncVector, 500));
  79. const sizeOption = [];
  80. for (let i = 10; i < 30; i++) {
  81. sizeOption.push({ label: i, value: i });
  82. }
  83. const menus = [
  84. {
  85. key: "color",
  86. icon: "del",
  87. text: "颜色",
  88. },
  89. {
  90. key: "fontSize",
  91. text: "文字大小",
  92. },
  93. {
  94. key: "text",
  95. icon: "edit",
  96. text: "修改文字",
  97. onClick: () => (updateText.value = true),
  98. },
  99. {
  100. key: "del",
  101. icon: "del",
  102. text: "删除",
  103. onClick: () => {
  104. drawRef.value.uiControl.handleGeo(GeoActions.DeleteAction);
  105. },
  106. },
  107. ];
  108. </script>
  109. <style scoped lang="scss">
  110. .color {
  111. width: 18px;
  112. height: 18px;
  113. border: 2px solid #fff;
  114. border-radius: 50%;
  115. display: inline-block;
  116. }
  117. .font-size {
  118. font-size: 16px;
  119. font-weight: bold;
  120. color: #fff;
  121. }
  122. .del-icon {
  123. font-size: 16px;
  124. }
  125. .geo-input {
  126. position: absolute;
  127. left: 0;
  128. right: 0;
  129. top: 0;
  130. bottom: 0;
  131. z-index: 1;
  132. opacity: 0;
  133. }
  134. .text-model {
  135. position: fixed;
  136. left: 0;
  137. top: 0;
  138. right: 0;
  139. bottom: 0;
  140. background-color: rgba(0, 0, 0, 0.8);
  141. z-index: 4;
  142. }
  143. .text-input {
  144. width: 785px;
  145. height: 64px;
  146. display: block;
  147. margin: 176px auto 0;
  148. }
  149. </style>
  150. <style lang="scss">
  151. .select-floating.select-float.dire-top {
  152. margin-top: -10px;
  153. }
  154. .text-input .ui-input .text input {
  155. font-size: 16px;
  156. padding: 16px 21px;
  157. }
  158. </style>