current.vue 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <v-arrow
  3. ref="arrow"
  4. :config="{
  5. points: [currentX, 0, currentX, 10],
  6. fill: currentColor,
  7. stroke: currentColor,
  8. strokeWidth: 1,
  9. pointerLength: 10,
  10. hitStrokeWidth: 10,
  11. pointerWidth: 10,
  12. ...currentMat,
  13. }"
  14. />
  15. <v-line
  16. :config="{
  17. points: [currentX, size!.height, currentX, 10],
  18. stroke: currentColor,
  19. strokeWidth: 2,
  20. listening: false,
  21. ...currentMat
  22. }"
  23. />
  24. </template>
  25. <script setup lang="ts">
  26. import { computed, ref, watch, watchEffect } from "vue";
  27. import {
  28. useDrag,
  29. useGlobalResize,
  30. useGlobalVar,
  31. useViewer,
  32. useViewerInvertTransformConfig,
  33. useViewerTransform,
  34. } from "../drawing/hook";
  35. import { Transform } from "konva/lib/Util";
  36. import { Arrow } from "konva/lib/shapes/Arrow";
  37. import { DC } from "../drawing/dec";
  38. const props = withDefaults(defineProps<{ currentTime: number; follow?: boolean }>(), {
  39. follow: false,
  40. });
  41. const currentColor = "#fff";
  42. const { misPixel } = useGlobalVar();
  43. const emit = defineEmits<{ (e: "update:currentTime", num: number): void }>();
  44. const arrow = ref<DC<Arrow>>();
  45. const { drag } = useDrag(arrow);
  46. watch(drag, (drag) => {
  47. if (!drag) return;
  48. const offsetX = drag.x;
  49. const currentX = props.currentTime * misPixel + offsetX;
  50. currentX >= 0 && emit("update:currentTime", currentX / misPixel);
  51. });
  52. const invConfig = useViewerInvertTransformConfig();
  53. const currentX = computed(() => props.currentTime * misPixel);
  54. const currentMat = computed(() => {
  55. return new Transform()
  56. .translate(currentX.value, 0)
  57. .scale(invConfig.value.scaleX, 1)
  58. .translate(-currentX.value, 0)
  59. .decompose();
  60. });
  61. const { viewer } = useViewer();
  62. const { size } = useGlobalResize();
  63. const viewerMat = useViewerTransform();
  64. watch(
  65. () => {
  66. if (!props.follow || !size.value) return;
  67. return currentX.value;
  68. },
  69. (x) => {
  70. if (typeof x !== "number") return;
  71. const currentPixel = viewerMat.value.point({ x: currentX.value, y: 0 }).x;
  72. const offsetX = size.value!.width / 2 - currentPixel;
  73. viewer.movePixel({ x: offsetX, y: 0 });
  74. }
  75. );
  76. </script>