123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- <template>
- <Teleport to="#layout-app">
- <RightFillPano class="edit-path-point">
- <div v-show="!~activePointNdx">
- <ui-group
- :title="`${isTemploraryID(data.id) ? '创建' : '编辑'}路线`"
- borderBottom
- >
- <ui-group-option class="item">
- <span class="label">路径名称</span>
- <span class="oper"> <Switch v-model:checked="data.showName" /> </span>
- </ui-group-option>
- <ui-group-option class="item">
- <ui-input
- width="100%"
- type="text"
- placeholder="路径名称"
- v-model="data.name"
- :maxlength="60"
- />
- </ui-group-option>
- <ui-group-option class="item">
- <span class="label">路径粗细</span>
- <span class="oper">
- <InputNumber
- style="width: 120px"
- v-model:value="data.lineWidth"
- :max="100"
- :min="1"
- :controls="false"
- >
- <template #addonBefore>
- <span
- class="fun-ctrl"
- @click="data.lineWidth = Math.max(1, data.lineWidth - 1)"
- >-</span
- >
- </template>
- <template #addonAfter>
- <span
- class="fun-ctrl"
- @click="data.lineWidth = Math.min(100, data.lineWidth + 1)"
- >+</span
- >
- </template>
- </InputNumber>
- </span>
- </ui-group-option>
- <ui-group-option class="item">
- <span class="label">路径颜色</span>
- <span class="oper">
- <ui-input
- type="color"
- width="24px"
- height="24px"
- v-model="data.lineColor"
- />
- </span>
- </ui-group-option>
- <ui-group-option class="item">
- <span class="label">路径箭头</span>
- <span class="oper">
- <Switch v-model:checked="data.showDirection" />
- </span>
- </ui-group-option>
- <ui-group-option class="item" v-if="data.showDirection">
- <span class="label">箭头反向</span>
- <span class="oper"> <Switch v-model:checked="data.reverseDirection" /> </span>
- </ui-group-option>
- </ui-group>
- <ui-group borderBottom>
- <ui-group-option>
- <span>文字大小</span>
- <Slider v-model:value="data.fontSize" :min="12" :max="60" :step="0.1" />
- </ui-group-option>
- </ui-group>
- <ui-group borderBottom>
- <ui-group-option>
- <SignItem
- label="可见范围"
- v-if="!data.globalVisibility"
- @apply-global="$emit('applyGlobal', 'visibilityRange')"
- >
- <Slider
- v-model:value="data.visibilityRange"
- :min="1"
- :max="1000"
- :step="0.1"
- />
- </SignItem>
- </ui-group-option>
- <ui-group-option>
- <SignItem @apply-global="$emit('applyGlobal', 'globalVisibility')">
- <template v-slot:label>
- <ui-input
- type="checkbox"
- label="全部范围可见"
- :modelValue="!!data.globalVisibility"
- @update:modelValue="(v: boolean) => data.globalVisibility = v"
- />
- </template>
- </SignItem>
- </ui-group-option>
- </ui-group>
- <Button
- block
- type="primary"
- ghost
- size="large"
- @click="switchPlay"
- v-if="data.points.length"
- >
- {{ isScenePathPlayIng ? "停止" : "" }} 预览路径
- </Button>
- </div>
- <div v-if="~activePointNdx">
- <ui-group title="编辑点" borderBottom>
- <ui-group-option>描述:</ui-group-option>
- <ui-group-option>
- <ui-input
- class="input"
- width="100%"
- height="158px"
- v-model="data.points[activePointNdx].name"
- placeholder="特征描述:"
- type="richtext"
- :maxlength="200"
- />
- </ui-group-option>
- </ui-group>
- <Button block danger type="primary" ghost size="large" @click="deletePoint">
- 删除
- </Button>
- </div>
- </RightFillPano>
- <span
- @click="unKeepAdding ? unKeepAdding() : keepAdding()"
- class="pin-position strengthen fun-ctrl"
- v-if="node"
- >
- <ui-icon
- :style="{ color: unKeepAdding ? 'var(--color-main-normal)' : 'currentColor' }"
- type="pin1"
- size="22px"
- />
- </span>
- </Teleport>
- </template>
- <script setup lang="ts">
- import {
- showLeftCtrlPanoStack,
- showLeftPanoStack,
- showRightCtrlPanoStack,
- showRightPanoStack,
- } from "@/env";
- import { computed, onUnmounted, ref, shallowRef, watch, watchEffect } from "vue";
- import { isTemploraryID, Path } from "@/store";
- import { RightFillPano } from "@/layout";
- import { useViewStack } from "@/hook";
- import { togetherCallback } from "@/utils";
- import { Switch, Slider, Button, InputNumber } from "ant-design-vue";
- import SignItem from "@/views/tagging-position/sign-item.vue";
- import { Message } from "bill/expose-common";
- import {
- getPathNode,
- isScenePathPlayIng,
- pauseScenePath,
- playScenePath,
- } from "@/sdk/association/path";
- const props = defineProps<{ data: Path }>();
- defineEmits<{
- (e: "applyGlobal", k: string | string[]): void;
- }>();
- const node = computed(() => getPathNode(props.data.id));
- watch(node, () => {
- if (props.data.points.length) {
- node.value?.fly();
- }
- });
- const activePointNdx = ref(-1);
- watchEffect((onCleanup) => {
- if (!node.value) return;
- const $node = node.value;
- const handler = (ndx: number) => {
- activePointNdx.value = ndx;
- };
- $node.bus.on("activePoint", handler);
- onCleanup(() => $node.bus.off("activePoint", handler));
- });
- const deletePoint = () => {
- props.data.points.splice(activePointNdx.value, 1);
- activePointNdx.value = -1;
- };
- let unKeepAdding = shallowRef<() => void>();
- const keepAdding = () => {
- unKeepAdding.value && unKeepAdding.value();
- node.value?.changeCanEdit(true);
- const hide = Message.show({ msg: "请在模型上单击选择路径点位置", type: "warning" });
- unKeepAdding.value = () => {
- node.value?.changeCanEdit(false);
- hide();
- unKeepAdding.value = void 0;
- };
- };
- onUnmounted(() => unKeepAdding.value && unKeepAdding.value());
- useViewStack(() =>
- togetherCallback([
- showRightPanoStack.push(ref(false)),
- showLeftCtrlPanoStack.push(ref(false)),
- showLeftPanoStack.push(ref(false)),
- showRightCtrlPanoStack.push(ref(false)),
- ])
- );
- const switchPlay = () => {
- if (isScenePathPlayIng.value) {
- pauseScenePath();
- } else {
- playScenePath(props.data);
- }
- };
- </script>
- <style lang="scss" scoped>
- .edit-path-point {
- position: absolute;
- right: 0;
- height: 100%;
- top: 0;
- --editor-menu-right: 0px;
- }
- .item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- }
- .pin-position {
- position: absolute;
- left: 50%;
- transform: translate(-50%);
- width: 64px;
- height: 64px;
- background: rgba(27, 27, 28, 0.8);
- border-radius: 50%;
- bottom: 20px;
- z-index: 9;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- </style>
|