renderer.vue 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <template>
  2. <div class="draw-layout" @contextmenu.prevent :style="{ cursor: cursorStyle }">
  3. <div class="mount-mask" :id="DomMountId" />
  4. <v-stage ref="stage" :config="size">
  5. <v-layer :config="viewerConfig" id="formal">
  6. <!-- 不可去除,去除后移动端拖拽会有溢出 -->
  7. <!-- <v-rect
  8. :config="{
  9. ...size,
  10. fill: 'rgba(0,0,0,0)',
  11. listener: false,
  12. ...invertViewerConfig,
  13. }"
  14. /> -->
  15. <ShapeGroup v-for="type in types" :type="type" :key="type" />
  16. </v-layer>
  17. <!-- 临时组,提供临时绘画,以及高频率渲染 -->
  18. <v-layer :config="viewerConfig" id="temp">
  19. <template v-if="mode.include(Mode.add)">
  20. <TempShapeGroup v-for="type in types" :type="type" :key="type" />
  21. </template>
  22. </v-layer>
  23. <v-layer id="helper">
  24. <ActiveBoxs />
  25. <SnapLines />
  26. </v-layer>
  27. </v-stage>
  28. </div>
  29. </template>
  30. <script lang="ts" setup>
  31. import ShapeGroup from "./group.vue";
  32. import TempShapeGroup from "./draw-group.vue";
  33. import { DrawData, ShapeType, components } from "../components";
  34. import { useCursor, useMode, useStage } from "../hook/use-global-vars.ts";
  35. import { useViewerTransformConfig } from "../hook/use-viewer.ts";
  36. import { useListener, useResize } from "../hook/use-event.ts";
  37. import { useExpose } from "../hook/use-expose.ts";
  38. import { DomMountId } from "../../constant";
  39. import ActiveBoxs from "../helper/active-boxs.vue";
  40. import SnapLines from "../helper/snap-lines.vue";
  41. import { useStore } from "../store/index.ts";
  42. import { useInteractiveAddShapeAPI } from "../hook/use-add.ts";
  43. import { Mode } from "@/constant/mode.ts";
  44. import { computed } from "vue";
  45. const props = defineProps<{
  46. data: DrawData;
  47. }>();
  48. const store = useStore();
  49. store.setStore(props.data);
  50. const stage = useStage();
  51. const size = useResize();
  52. const viewerConfig = useViewerTransformConfig();
  53. const types = Object.keys(components) as ShapeType[];
  54. const mode = useMode();
  55. // 退出添加模式
  56. const { quitMouseAddShape } = useInteractiveAddShapeAPI();
  57. useListener(
  58. "contextmenu",
  59. (ev) => {
  60. if (ev.button === 2) {
  61. quitMouseAddShape();
  62. }
  63. },
  64. document.documentElement
  65. );
  66. const cursor = useCursor();
  67. const cursorStyle = computed(() => {
  68. if (cursor.value.includes(".")) {
  69. return `url(${cursor.value}), auto`;
  70. } else {
  71. return cursor.value;
  72. }
  73. });
  74. defineExpose(useExpose());
  75. </script>
  76. <style scoped lang="scss">
  77. .draw-layout {
  78. width: 100%;
  79. height: 100%;
  80. overflow: hidden;
  81. position: relative;
  82. }
  83. .mount-mask {
  84. position: absolute;
  85. inset: 0;
  86. overflow: hidden;
  87. pointer-events: none;
  88. z-index: 999;
  89. }
  90. </style>