index.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <RightFillPano>
  3. <h3>{{ tagging?.title }}放置位置</h3>
  4. <Collapse v-model:activeKey="showId" ghost accordion expandIconPosition="end">
  5. <PositionSign
  6. v-for="(position, i) in positions"
  7. :key="position.id"
  8. :position="position"
  9. :title="`位置${i + 1}`"
  10. @applyGlobal="(keys) => applyGlobal(position, keys)"
  11. @delete="deletePosition(position)"
  12. />
  13. </Collapse>
  14. </RightFillPano>
  15. </template>
  16. <script lang="ts" setup>
  17. import PositionSign from "./sign.vue";
  18. import { router } from "@/router";
  19. import { Dialog, Message } from "bill/index";
  20. import { RightFillPano } from "@/layout";
  21. import { asyncTimeout } from "@/utils";
  22. import { useViewStack } from "@/hook";
  23. import { computed, nextTick, onUnmounted, ref, watch, watchEffect } from "vue";
  24. import { sdk } from "@/sdk";
  25. import { showTaggingPositionsStack } from "@/env";
  26. import {
  27. autoSaveTaggings,
  28. getFuseModel,
  29. getFuseModelShowVariable,
  30. getTaggingPositions,
  31. taggingPositions,
  32. createTaggingPosition,
  33. getTagging,
  34. enterEdit,
  35. } from "@/store";
  36. import { Collapse, CollapsePanel } from "ant-design-vue";
  37. import type { TaggingPosition } from "@/store";
  38. import { distance } from "@/utils/math";
  39. const showId = ref<TaggingPosition["id"]>();
  40. const tagging = computed(() => getTagging(router.currentRoute.value.params.id as string));
  41. const positions = computed(() => tagging.value && getTaggingPositions(tagging.value));
  42. watch(showId, (id) => {
  43. const position = positions.value?.find((item) => item.id === id);
  44. position && flyTaggingPosition(position);
  45. });
  46. let pop: () => void;
  47. const flyTaggingPosition = (position: TaggingPosition) => {
  48. pop && pop();
  49. const model = getFuseModel(position.modelId);
  50. if (!model || !getFuseModelShowVariable(model).value) {
  51. return;
  52. }
  53. pop = showTaggingPositionsStack.push(ref(new WeakSet([position])));
  54. sdk.comeTo({
  55. position: position.localPos,
  56. modelId: position.modelId,
  57. dur: 300,
  58. distance: 3,
  59. });
  60. // setTimeout(pop, 2000);
  61. };
  62. onUnmounted(() => pop && pop());
  63. const deletePosition = (position: TaggingPosition) => {
  64. const index = taggingPositions.value.indexOf(position);
  65. if (~index) {
  66. taggingPositions.value.splice(index, 1);
  67. }
  68. };
  69. const applyGlobal = async (position: TaggingPosition, keys: string | string[]) => {
  70. if (!(await Dialog.confirm("确定要将此属性应用到所有位置?"))) return;
  71. keys = Array.isArray(keys) ? keys : [keys];
  72. for (const current of positions.value!) {
  73. let val: any = current;
  74. let newVal: any = position;
  75. for (let i = 0; i < keys.length; i++) {
  76. if (i === keys.length - 1) {
  77. val[keys[i]] = newVal[keys[i]];
  78. } else {
  79. val = val[keys[i]];
  80. newVal = newVal[keys[i]];
  81. }
  82. }
  83. }
  84. };
  85. // const cameraPos = ref<SceneLocalPos>();
  86. // sdk.sceneBus.on("cameraChange", (pos) => (cameraPos.value = pos));
  87. let unKeepAdding: () => void;
  88. const keepAdding = () => {
  89. const hide = Message.show({ msg: "请在模型上单击选择标签位置", type: "warning" });
  90. const clickHandler = async (ev: MouseEvent) => {
  91. await nextTick();
  92. await asyncTimeout();
  93. const position = sdk.getPositionByScreen({
  94. x: ev.clientX,
  95. y: ev.clientY,
  96. });
  97. if (!position) {
  98. Message.error("当前位置无法添加");
  99. } else {
  100. const storePosition = createTaggingPosition({
  101. ...position,
  102. taggingId: tagging.value!.id,
  103. });
  104. taggingPositions.value.push(storePosition);
  105. showId.value = storePosition.id;
  106. // if (cameraPos.value && distance(cameraPos.value, position.worldPos) > 8) {
  107. // flyTaggingPosition(storePosition);
  108. // }
  109. }
  110. };
  111. sdk.layout.addEventListener("click", clickHandler, false);
  112. unKeepAdding = () => {
  113. hide();
  114. sdk.layout.removeEventListener("click", clickHandler, false);
  115. };
  116. };
  117. useViewStack(autoSaveTaggings);
  118. </script>
  119. <style lang="scss" scoped>
  120. h3 {
  121. font-family: Microsoft YaHei, Microsoft YaHei;
  122. font-weight: bold;
  123. font-size: 16px;
  124. color: #999999;
  125. margin-bottom: 4px;
  126. }
  127. </style>
  128. <style lang="scss">
  129. .position-group .group-title {
  130. margin-bottom: 0;
  131. }
  132. </style>