temp-arrow.vue 4.2 KB

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