temp-table.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <template>
  2. <v-group :config="matConfig" ref="shape">
  3. <v-rect
  4. name="repShape"
  5. :config="{
  6. x: -rang,
  7. y: -rang,
  8. width: data.width + 2 * rang,
  9. height: data.height + 2 * rang,
  10. }"
  11. >
  12. </v-rect>
  13. <v-line
  14. ref="line"
  15. :config="{
  16. points: getBorderPoints(),
  17. ...data,
  18. closed: true,
  19. zIndex: undefined,
  20. }"
  21. />
  22. <template v-for="(row, rowNdx) in data.content">
  23. <template v-for="(col, colNdx) in row">
  24. <ShareText
  25. :config="{
  26. ...defaultCollData,
  27. ...col,
  28. ...getBound(rowNdx, colNdx),
  29. text: col.content,
  30. fill: col.fontColor,
  31. }"
  32. :parent-id="data.id"
  33. :editer="editer && !col.readonly"
  34. @update-text="(val) => emit('updateContent', { rowNdx, colNdx, val })"
  35. @update:is-edit="(val) => emit('update:isEdit', { rowNdx, colNdx, val })"
  36. />
  37. </template>
  38. </template>
  39. </v-group>
  40. </template>
  41. <script lang="ts" setup>
  42. import ShareText from "../share/text.vue";
  43. import { defaultStyle, TableData, defaultCollData } from "./index.ts";
  44. import { computed, ref } from "vue";
  45. import { DC } from "@/deconstruction.js";
  46. import { Transform } from "konva/lib/Util";
  47. import { Group } from "konva/lib/Group";
  48. import { useStage } from "@/core/hook/use-global-vars.ts";
  49. import { Line } from "konva/lib/shapes/Line";
  50. import { useViewerInvertTransform, useViewerTransform } from "@/core/hook/use-viewer.ts";
  51. import { lineLen, Pos } from "@/utils/math.ts";
  52. const props = defineProps<{ data: TableData; addMode?: boolean; editer?: boolean }>();
  53. const data = computed(() => ({ ...defaultStyle, ...props.data }));
  54. const emit = defineEmits<{
  55. (e: "updateContent", data: { rowNdx: number; colNdx: number; val: string }): void;
  56. (e: "update:isEdit", data: { rowNdx: number; colNdx: number; val: boolean }): void;
  57. }>();
  58. const shape = ref<DC<Group>>();
  59. const line = ref<DC<Line>>();
  60. const getBound = (rowNdx: number, colNdx: number) => {
  61. let x = 0,
  62. y = 0;
  63. for (let i = 0; i < rowNdx; i++) {
  64. y += data.value.content[i][0].height;
  65. }
  66. for (let i = 0; i < colNdx; i++) {
  67. x += data.value.content[rowNdx][i].width;
  68. }
  69. const { width, height } = data.value.content[rowNdx][colNdx];
  70. return { x, y, width, height };
  71. };
  72. const getBorderPoints = () => {
  73. const points: number[] = [];
  74. const rows = data.value.content;
  75. let ry = 0;
  76. let rx = 0;
  77. for (let i = 0; i < rows.length; i++) {
  78. const cols = rows[i];
  79. for (let j = 0; j < cols.length; j++) {
  80. const { x, y, width, height } = getBound(i, j);
  81. points.push(x, y, x + width, y, x + width, y + height, x, y + height, x, y);
  82. ry = y + height;
  83. rx = x;
  84. }
  85. points.push(rx, ry);
  86. }
  87. points.push(0, ry);
  88. return points;
  89. };
  90. const matConfig = computed(() => {
  91. const mat = new Transform(data.value.mat);
  92. return mat.decompose();
  93. });
  94. let rang = 5;
  95. const stage = useStage();
  96. const viewInverTransform = useViewerInvertTransform();
  97. const viewTransform = useViewerTransform();
  98. const getMouseIntersect = (pos?: Pos) => {
  99. const $line = line.value?.getNode();
  100. if (!pos) {
  101. const $stage = stage.value?.getStage();
  102. pos = $stage?.getPointerPosition() as any;
  103. }
  104. if (!pos || !$line) return null;
  105. if (!$line.intersects(pos)) return null;
  106. pos = viewInverTransform.value.point(pos);
  107. pos = new Transform(data.value.mat).invert().point(pos);
  108. const swPixel = lineLen(
  109. viewTransform.value.point({ x: data.value.strokeWidth, y: 0 }),
  110. viewTransform.value.point({ x: 0, y: 0 })
  111. );
  112. const check = Math.max(rang, swPixel);
  113. let rowBorderNdx = -1;
  114. let colBorderNdx = -1;
  115. let rowNdx = -1;
  116. let colNdx = -1;
  117. for (let i = 0; i < data.value.content.length; i++) {
  118. const rb = getBound(i, 0);
  119. rb.x += matConfig.value.x;
  120. rb.x += matConfig.value.y;
  121. const td = pos.y - rb.y;
  122. const bd = pos.y - rb.y - rb.height;
  123. if (td < -check || bd > check) {
  124. continue;
  125. }
  126. if (Math.abs(td) < check) {
  127. rowBorderNdx = i;
  128. }
  129. if (Math.abs(bd) < check) {
  130. rowBorderNdx = i + 1;
  131. }
  132. rowNdx = i;
  133. const row = data.value.content[i];
  134. let j = 0;
  135. for (; j < row.length; j++) {
  136. const cb = getBound(i, j);
  137. const ld = pos.x - cb.x;
  138. const rd = pos.x - cb.x - cb.width;
  139. if (ld < -check || rd > check) {
  140. continue;
  141. }
  142. if (Math.abs(ld) < check) {
  143. colBorderNdx = j;
  144. }
  145. if (Math.abs(rd) < check) {
  146. colBorderNdx = j + 1;
  147. }
  148. colNdx = j;
  149. break;
  150. }
  151. if (j !== row.length) {
  152. break;
  153. }
  154. }
  155. return { rowBorderNdx, colBorderNdx, rowNdx, colNdx };
  156. };
  157. defineExpose({
  158. get shape() {
  159. return shape.value;
  160. },
  161. getMouseIntersect,
  162. });
  163. </script>