time.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <v-group v-if="shapeConfig">
  3. <v-line v-for="line in shapeConfig.lines" :config="line" />
  4. <v-text v-for="texConfig in shapeConfig.texts" :config="{ ...texConfig }" />
  5. <v-line
  6. :config="{
  7. points: [0, 0, size?.width, 0],
  8. strokeWidth: 30,
  9. stroke: '#fff',
  10. opacity: 0,
  11. ...invConfig,
  12. }"
  13. ref="line"
  14. />
  15. <slot />
  16. </v-group>
  17. </template>
  18. <script setup lang="ts">
  19. import { computed, ref } from "vue";
  20. import {
  21. useClickHandler,
  22. useGlobalResize,
  23. useGlobalVar,
  24. useHoverPointer,
  25. useStage,
  26. useViewerInvertTransform,
  27. useViewerInvertTransformConfig,
  28. useViewerTransform,
  29. } from "../drawing/hook";
  30. import { formatDate } from "@/utils";
  31. import { TextConfig } from "konva/lib/shapes/Text";
  32. import { Transform } from "konva/lib/Util";
  33. import { Line, LineConfig } from "konva/lib/shapes/Line";
  34. import { DC } from "../drawing/dec";
  35. const { misPixel } = useGlobalVar();
  36. const emit = defineEmits<{ (e: "updateCurrentTime", num: number): void }>();
  37. const getText = (mis: number) => {
  38. const date = new Date(0);
  39. date.setHours(0);
  40. date.setSeconds(mis);
  41. const h = date.getHours();
  42. return h ? formatDate(date, "hh:mm:ss") : formatDate(date, "mm:ss");
  43. };
  44. const viewMat = useViewerTransform();
  45. const invMat = useViewerInvertTransform();
  46. const invConfig = useViewerInvertTransformConfig();
  47. const { size } = useGlobalResize();
  48. const timeRange = computed(() => {
  49. if (!size.value) return;
  50. const start = viewMat.value.point({ x: 0, y: 0 }).x;
  51. const lt = { x: start > 0 ? start : 0, y: 0 };
  52. const rt = { x: size.value!.width, y: 0 };
  53. const startPixel = invMat.value.point(lt).x;
  54. const endPixel = invMat.value.point(rt).x;
  55. const startTime = Math.floor(startPixel / misPixel);
  56. const endTime = Math.ceil(endPixel / misPixel);
  57. return { startTime, endTime };
  58. });
  59. const strokeWidth = 1;
  60. const color = "#999";
  61. const shapeConfig = computed(() => {
  62. if (!timeRange.value) return;
  63. const texts: TextConfig[] = [];
  64. const lines: LineConfig[] = [];
  65. for (let i = timeRange.value.startTime; i < timeRange.value.endTime; i++) {
  66. const x = i * misPixel;
  67. const line: LineConfig = {
  68. ...new Transform()
  69. .translate(x, 0)
  70. .scale(invConfig.value.scaleX, 1)
  71. .translate(-x, 0)
  72. .decompose(),
  73. stroke: color,
  74. hitStrokeWidth: 5,
  75. strokeWidth,
  76. };
  77. if (i % 10) {
  78. line.points = [x, 0, x, 4];
  79. } else {
  80. line.points = [x, 0, x, 12];
  81. texts.push({
  82. ...new Transform()
  83. .translate(x + 5 * invConfig.value.scaleX, 5)
  84. .scale(invConfig.value.scaleX, 1)
  85. .decompose(),
  86. text: getText(i),
  87. fontSize: strokeWidth * 12,
  88. fill: color,
  89. align: "left",
  90. verticalAlign: "top",
  91. });
  92. }
  93. lines.push(line);
  94. }
  95. return { texts, lines };
  96. });
  97. const line = ref<DC<Line>>();
  98. useHoverPointer(line);
  99. const stage = useStage();
  100. const clickHandler = () => {
  101. const pos = stage.value!.getNode().pointerPos!;
  102. const x = invMat.value.point(pos).x;
  103. emit("updateCurrentTime", x / misPixel);
  104. };
  105. useClickHandler(line, clickHandler);
  106. </script>