single-line.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <template>
  2. <!-- @dragstart="emit('dragLineStart', props.line)"
  3. @update:line="(ps) => emit('dragLine', props.line, ps)"
  4. @dragend="emit('dragLineEnd', props.line)" -->
  5. <EditLine
  6. :ref="(d: any) => shape = d?.shape"
  7. :data="lineData"
  8. :opacity="0"
  9. :points="points"
  10. :closed="false"
  11. :id="line.id"
  12. :disablePoint="true"
  13. :ndx="0"
  14. @dragstart="dragstartHandler(points.map((item) => item.id))"
  15. @update:line="
  16. (p) => {
  17. emit('updatePoint', { ...points[0], ...p[0] });
  18. emit('updatePoint', { ...points[1], ...p[1] });
  19. }
  20. "
  21. @dragend="dragendHandler"
  22. @add-point="addPoint"
  23. />
  24. <v-line
  25. v-for="polygon in polygons"
  26. :config="{
  27. opacity: drawProps ? 0.7 : 1,
  28. points: flatPositions(polygon),
  29. fill: isDrawIng ? themeColor : style.stroke,
  30. closed: true,
  31. listening: false,
  32. }"
  33. />
  34. <!-- v-if="status.active" -->
  35. <!-- <v-text :config="{ ...pointsCenter(points), text: line.id }" /> -->
  36. <template
  37. v-if="
  38. status.active ||
  39. config.showComponentSize ||
  40. isDrawIng ||
  41. dragPointIds?.includes(line.a) ||
  42. dragPointIds?.includes(line.b)
  43. "
  44. >
  45. <v-group>
  46. <template v-if="gd.steps.value.length">
  47. <SizeLine
  48. :points="line"
  49. :strokeWidth="style.strokeWidth"
  50. :stroke="style.stroke"
  51. v-for="line in [...gd.steps.value, ...gd.subSteps.value]"
  52. />
  53. </template>
  54. <SizeLine
  55. :points="points"
  56. :strokeWidth="style.strokeWidth"
  57. :stroke="style.stroke"
  58. v-else
  59. />
  60. </v-group>
  61. </template>
  62. <PropertyUpdate
  63. :describes="describes"
  64. :data="line"
  65. :target="shape"
  66. :name="shapeName"
  67. @change="
  68. () => {
  69. emit('updateBefore', []);
  70. emit('updateLine', { ...line });
  71. emit('update');
  72. }
  73. "
  74. @delete="delHandler"
  75. />
  76. <Operate :target="shape" :menus="menus" />
  77. <template v-if="drawProps">
  78. <SingleLine
  79. :data="drawProps.data"
  80. :line="drawProps.prev"
  81. :drawMode="drawProps.point"
  82. :get-extend-polygon="drawGetExtendPolygon"
  83. />
  84. <singlePoint
  85. :data="drawProps.data"
  86. :line="drawProps.prev"
  87. :drawMode="drawProps.point"
  88. />
  89. <SingleLine
  90. :data="drawProps.data"
  91. :line="drawProps.next"
  92. :drawMode="drawProps.point"
  93. :get-extend-polygon="drawGetExtendPolygon"
  94. />
  95. <singlePoint
  96. :data="drawProps.data"
  97. :line="drawProps.next"
  98. :drawMode="drawProps.point"
  99. />
  100. </template>
  101. </template>
  102. <script lang="ts" setup>
  103. import EditLine from "../share/edit-line.vue";
  104. import singlePoint from "./single-point.vue";
  105. import { computed, ref } from "vue";
  106. import { getMouseStyle, LineData, LineDataLine, shapeName } from "./index.ts";
  107. import { flatPositions, onlyId } from "@/utils/shared.ts";
  108. import { pointsCenter, Pos } from "@/utils/math.ts";
  109. import { Line } from "konva/lib/shapes/Line";
  110. import { DC } from "@/deconstruction.js";
  111. import SizeLine from "../share/size-line.vue";
  112. import { useConfig } from "@/core/hook/use-config.ts";
  113. import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
  114. import {
  115. useAnimationMouseStyle,
  116. useMouseShapeStatus,
  117. } from "@/core/hook/use-mouse-status.ts";
  118. import { themeColor } from "@/constant";
  119. import { useGetDiffLineIconPolygons, useGetExtendPolygon } from "./attach-view.ts";
  120. import {
  121. getLinePoints,
  122. useDrawLinePoint,
  123. useLineDataSnapInfos,
  124. useLineDescribes,
  125. } from "./attach-server.ts";
  126. import { useStore } from "@/core/store/index.ts";
  127. import { useHistory } from "@/core/hook/use-history.ts";
  128. const props = defineProps<{
  129. line: LineDataLine;
  130. addMode?: boolean;
  131. canEdit?: boolean;
  132. data: LineData;
  133. dragPointIds?: string[];
  134. drawMode?: LineData["points"][number];
  135. getExtendPolygon: (line: LineDataLine) => Pos[];
  136. }>();
  137. const emit = defineEmits<{
  138. (e: "updatePoint", value: LineData["points"][number]): void;
  139. (e: "addPoint", value: LineData["points"][number]): void;
  140. (e: "addLine", value: LineDataLine): void;
  141. (e: "delLine"): void;
  142. (e: "updateLine", value: LineDataLine): void;
  143. (e: "updateBefore", value: string[]): void;
  144. (e: "update"): void;
  145. (e: "dragLineStart", value: LineDataLine): void;
  146. (e: "dragLine", line: LineDataLine, move: Pos[]): void;
  147. (e: "dragLineEnd", value: LineDataLine): void;
  148. }>();
  149. const polygon = computed(() => props.getExtendPolygon(line.value));
  150. const line = computed(() => props.line);
  151. const points = computed(() => getLinePoints(props.data, props.line));
  152. const gd = useGetDiffLineIconPolygons(line.value, points);
  153. const polygons = computed(() => gd.diff(polygon.value));
  154. const shape = ref<DC<Line>>();
  155. const lineData = computed(() => props.line);
  156. const describes = useLineDescribes(lineData);
  157. const delHandler = () => {
  158. emit("updateBefore", [props.line.a, props.line.b]);
  159. emit("delLine");
  160. emit("update");
  161. };
  162. const store = useStore();
  163. const history = useHistory();
  164. const { drawProps, enter: enterDrawLinePoint } = useDrawLinePoint(
  165. computed(() => props.data),
  166. props.line,
  167. (data) => {
  168. emit("updateBefore", [props.line.a, props.line.b]);
  169. emit("addPoint", data.point);
  170. emit("addLine", data.prev);
  171. emit("addLine", data.next);
  172. emit("delLine");
  173. history.preventTrack(() => {
  174. data.oldIcons.forEach((icon) => store.delItem("lineIcon", icon.id));
  175. store.addItems("lineIcon", data.newIcons);
  176. });
  177. emit("update");
  178. }
  179. );
  180. const drawGetExtendPolygon = useGetExtendPolygon(computed(() => drawProps.value?.data));
  181. const menus = [
  182. { label: "加点", handler: enterDrawLinePoint },
  183. { label: "删除", handler: delHandler },
  184. ];
  185. const status = useMouseShapeStatus(shape);
  186. const [style] = useAnimationMouseStyle({
  187. shape,
  188. getMouseStyle,
  189. data: lineData as any,
  190. });
  191. const isDrawIng = computed(
  192. () =>
  193. (props.addMode &&
  194. props.data.lines.indexOf(props.line) === props.data.lines.length - 1) ||
  195. props.drawMode
  196. );
  197. const addPoint = (pos: Pos) => {
  198. emit("updateBefore", []);
  199. emit("addPoint", { ...points.value[0], ...pos, id: onlyId() });
  200. emit("update");
  201. };
  202. const lDataSnap = useLineDataSnapInfos();
  203. const config = useConfig();
  204. const dragstartHandler = (eIds: string[]) => {
  205. emit("updateBefore", eIds);
  206. lDataSnap.update(eIds);
  207. };
  208. const dragendHandler = () => {
  209. emit("update");
  210. lDataSnap.clear();
  211. };
  212. defineExpose({
  213. get shape() {
  214. return shape.value;
  215. },
  216. });
  217. </script>