temp-arrow.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <v-group ref="shape" :id="data.id">
  3. <v-arrow
  4. name="arrow"
  5. v-for="(_, ndx) in data.points.length - 1"
  6. :config="{
  7. ...data,
  8. zIndex: undefined,
  9. hitFunc: hitFunc,
  10. stroke: data.fill,
  11. fill: data.fill,
  12. hitStrokeWidth: data.strokeWidth + 10,
  13. pointerWidth: data.pointerLength,
  14. closed: false,
  15. id: void 0,
  16. points: flatPositions([data.points[ndx], data.points[ndx + 1]]),
  17. ...eConfig,
  18. opacity: addMode ? 0.3 : data.opacity,
  19. }"
  20. />
  21. <v-circle
  22. v-if="zeroEq(lineLen(data.points[0], data.points[1]))"
  23. :config="{
  24. ...data.points[0],
  25. radius: data.strokeWidth * 2,
  26. opacity: 0,
  27. fill: 'red',
  28. offset: { x: data.strokeWidth, y: 0 },
  29. }"
  30. />
  31. <!-- <EditPolygon
  32. :data="{ ...data, stroke: data.fill, strokeWidth: data.strokeWidth + 5 }"
  33. :shape="shape"
  34. :addMode="false"
  35. :canEdit="canEdit"
  36. @update:position="(data) => emit('update:position', data)"
  37. @update="emit('update')"
  38. @deletePoint="(ndx) => emit('deletePoint', ndx)"
  39. @addPoint="(data) => emit('addPoint', data)"
  40. v-if="shape"
  41. /> -->
  42. <v-group>
  43. <template
  44. v-if="(status.hover || status.active || addMode) && !operMode.mulSelection"
  45. >
  46. <Point
  47. v-for="(_, ndx) in data.points"
  48. :size="data.strokeWidth + 6"
  49. :points="data.points"
  50. :ndx="ndx"
  51. :closed="false"
  52. :id="data.id"
  53. :disable="addMode"
  54. :color="data.fill"
  55. @update:position="(p) => emit('update:position', { ndx, val: p })"
  56. @dragend="emit('update')"
  57. notDelete
  58. />
  59. </template>
  60. </v-group>
  61. <SizeLine
  62. v-if="config.showComponentSize"
  63. :points="data.points"
  64. :strokeWidth="data.strokeWidth"
  65. :stroke="data.fill"
  66. />
  67. </v-group>
  68. </template>
  69. <script lang="ts" setup>
  70. import SizeLine from "../share/size-line.vue";
  71. // import EditPolygon from "../share/edit-polygon.vue";
  72. import Point from "../share/edit-point.vue";
  73. import { ArrowData, defaultStyle, PointerPosition } from "./index.ts";
  74. import { DC } from "@/deconstruction.js";
  75. import { computed, ref, watchEffect } from "vue";
  76. import { flatPositions } from "@/utils/shared.ts";
  77. import { Arrow } from "konva/lib/shapes/Arrow";
  78. import { lineLen, Pos, zeroEq } from "@/utils/math.ts";
  79. import { LineConfig } from "konva/lib/shapes/Line";
  80. import { Group } from "konva/lib/Group";
  81. import { useConfig } from "@/core/hook/use-config.ts";
  82. import { useMouseShapeStatus } from "@/core/hook/use-mouse-status.ts";
  83. import { useOperMode } from "@/core/hook/use-status.ts";
  84. const props = defineProps<{ data: ArrowData; canEdit?: boolean; addMode?: boolean }>();
  85. const emit = defineEmits<{
  86. (e: "update:position", data: { ndx: number; val: Pos }): void;
  87. (e: "update"): void;
  88. (e: "deletePoint", ndx: number): void;
  89. (e: "addPoint", data: { ndx: number; val: Pos }): void;
  90. }>();
  91. const shape = ref<DC<Group>>();
  92. const config = useConfig();
  93. const data = computed(() => ({ ...defaultStyle, ...props.data }));
  94. const hitFunc: LineConfig["hitFunc"] = (con, shape) => {
  95. con.beginPath();
  96. con.moveTo(data.value.points[0].x, data.value.points[0].y);
  97. for (let i = 1; i < data.value.points.length; i++) {
  98. con.lineTo(data.value.points[i].x, data.value.points[i].y);
  99. }
  100. con.closePath();
  101. con.fillStrokeShape(shape);
  102. };
  103. const status = useMouseShapeStatus(computed(() => shape.value));
  104. const operMode = useOperMode();
  105. watchEffect(
  106. (onCleanup) => {
  107. const $shape = shape.value?.getNode();
  108. if ($shape) {
  109. const timeout = setTimeout(() => {
  110. $shape.findOne<Arrow>(".arrow")?.fill(data.value.fill);
  111. });
  112. onCleanup(() => clearTimeout(timeout));
  113. }
  114. },
  115. { flush: "post" }
  116. );
  117. const eConfig = computed(() => {
  118. const position =
  119. "pointerPosition" in data.value
  120. ? data.value.pointerPosition!
  121. : defaultStyle.pointerPosition;
  122. const eStart = [PointerPosition.all, PointerPosition.start].includes(position);
  123. const eEnd = [PointerPosition.all, PointerPosition.end].includes(position);
  124. return {
  125. pointerAtBeginning: eStart,
  126. pointerAtEnding: eEnd,
  127. };
  128. });
  129. defineExpose({
  130. get shape() {
  131. return shape.value;
  132. },
  133. });
  134. </script>