|
@@ -1,33 +1,30 @@
|
|
|
<template>
|
|
|
- <ui-group-option
|
|
|
- class="sign-tagging"
|
|
|
- :class="{active: selected, edit}"
|
|
|
+ <ui-group-option
|
|
|
+ class="sign-tagging"
|
|
|
+ :class="{ active: selected, edit }"
|
|
|
@click="edit && getTaggingIsShow(tagging) && emit('select', true)"
|
|
|
>
|
|
|
<div class="info">
|
|
|
- <img
|
|
|
- :src="getResource(getFileUrl(tagging.images[0]))"
|
|
|
- v-if="tagging.images.length"
|
|
|
- >
|
|
|
+ <img :src="getResource(getFileUrl(findImage))" v-if="findImage" />
|
|
|
<div>
|
|
|
<p>{{ tagging.title }}</p>
|
|
|
<span>放置:{{ positions.length }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="actions" @click.stop>
|
|
|
- <ui-icon
|
|
|
- v-if="!edit"
|
|
|
- type="pin"
|
|
|
- ctrl
|
|
|
- @click.stop="$emit('select', true)"
|
|
|
+ <ui-icon
|
|
|
+ v-if="!edit"
|
|
|
+ type="pin"
|
|
|
+ ctrl
|
|
|
+ @click.stop="$emit('select', true)"
|
|
|
:class="{ disabled: !getTaggingIsShow(tagging) }"
|
|
|
/>
|
|
|
<template v-else>
|
|
|
<ui-icon type="pin1" ctrl @click.stop="$emit('fixed')" tip="放置" />
|
|
|
- <ui-more
|
|
|
- :options="menus"
|
|
|
- style="margin-left: 20px"
|
|
|
- @click="(action: keyof typeof actions) => actions[action]()"
|
|
|
+ <ui-more
|
|
|
+ :options="menus"
|
|
|
+ style="margin-left: 20px"
|
|
|
+ @click="(action: keyof typeof actions) => actions[action]()"
|
|
|
/>
|
|
|
</template>
|
|
|
</div>
|
|
@@ -35,88 +32,94 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { getFileUrl } from '@/utils'
|
|
|
-import { computed, ref, watchEffect, nextTick } from 'vue';
|
|
|
-import { getResource, showTaggingPositionsStack } from '@/env'
|
|
|
-import { sdk } from '@/sdk'
|
|
|
-import {
|
|
|
- getTaggingStyle,
|
|
|
- getTaggingPositions,
|
|
|
+import { getFileUrl, getUrlType, MetaType } from "@/utils";
|
|
|
+import { computed, ref, watchEffect, nextTick } from "vue";
|
|
|
+import { getResource, showTaggingPositionsStack } from "@/env";
|
|
|
+import { sdk } from "@/sdk";
|
|
|
+import {
|
|
|
+ getTaggingStyle,
|
|
|
+ getTaggingPositions,
|
|
|
getFuseModel,
|
|
|
getFuseModelShowVariable,
|
|
|
- getTaggingIsShow
|
|
|
-} from '@/store'
|
|
|
+ getTaggingIsShow,
|
|
|
+} from "@/store";
|
|
|
|
|
|
-import type { Tagging } from '@/store'
|
|
|
+import type { Tagging } from "@/store";
|
|
|
|
|
|
const props = withDefaults(
|
|
|
- defineProps<{ tagging: Tagging, selected?: boolean, edit?: boolean }>(),
|
|
|
+ defineProps<{ tagging: Tagging; selected?: boolean; edit?: boolean }>(),
|
|
|
{ edit: true }
|
|
|
-)
|
|
|
-const style = computed(() => getTaggingStyle(props.tagging.styleId))
|
|
|
-const positions = computed(() => getTaggingPositions(props.tagging))
|
|
|
+);
|
|
|
+const style = computed(() => getTaggingStyle(props.tagging.styleId));
|
|
|
+const positions = computed(() => getTaggingPositions(props.tagging));
|
|
|
|
|
|
-const emit = defineEmits<{
|
|
|
- (e: 'delete'): void
|
|
|
- (e: 'edit'): void
|
|
|
- (e: 'select', selected: boolean): void
|
|
|
- (e: 'fixed'): void
|
|
|
-}>()
|
|
|
+const emit = defineEmits<{
|
|
|
+ (e: "delete"): void;
|
|
|
+ (e: "edit"): void;
|
|
|
+ (e: "select", selected: boolean): void;
|
|
|
+ (e: "fixed"): void;
|
|
|
+}>();
|
|
|
+
|
|
|
+const findImage = computed(() => {
|
|
|
+ return props.tagging.images.find(
|
|
|
+ (a) => getUrlType(getResource(getFileUrl(a))) === MetaType.image
|
|
|
+ );
|
|
|
+});
|
|
|
|
|
|
const menus = [
|
|
|
- { label: '编辑', value: 'edit' },
|
|
|
- { label: '删除', value: 'delete' },
|
|
|
-]
|
|
|
+ { label: "编辑", value: "edit" },
|
|
|
+ { label: "删除", value: "delete" },
|
|
|
+];
|
|
|
const actions = {
|
|
|
- edit: () => emit('edit'),
|
|
|
- delete: () => emit('delete')
|
|
|
-}
|
|
|
+ edit: () => emit("edit"),
|
|
|
+ delete: () => emit("delete"),
|
|
|
+};
|
|
|
|
|
|
const flyTaggingPositions = (tagging: Tagging, callback?: () => void) => {
|
|
|
- const positions = getTaggingPositions(tagging)
|
|
|
+ const positions = getTaggingPositions(tagging);
|
|
|
|
|
|
- let isStop = false
|
|
|
+ let isStop = false;
|
|
|
const flyIndex = (i: number) => {
|
|
|
if (isStop || i >= positions.length) {
|
|
|
- callback && nextTick(callback)
|
|
|
+ callback && nextTick(callback);
|
|
|
return;
|
|
|
}
|
|
|
- const position = positions[i]
|
|
|
- const model = getFuseModel(position.modelId)
|
|
|
+ const position = positions[i];
|
|
|
+ const model = getFuseModel(position.modelId);
|
|
|
if (!model || !getFuseModelShowVariable(model).value) {
|
|
|
- flyIndex(i + 1)
|
|
|
+ flyIndex(i + 1);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- const pop = showTaggingPositionsStack.push(ref(new WeakSet([position])))
|
|
|
- sdk.comeTo({
|
|
|
- position: position.localPos,
|
|
|
+ const pop = showTaggingPositionsStack.push(ref(new WeakSet([position])));
|
|
|
+ sdk.comeTo({
|
|
|
+ position: position.localPos,
|
|
|
modelId: position.modelId,
|
|
|
dur: 300,
|
|
|
- distance: 3
|
|
|
- })
|
|
|
-
|
|
|
+ distance: 3,
|
|
|
+ });
|
|
|
+
|
|
|
setTimeout(() => {
|
|
|
- pop()
|
|
|
- flyIndex(i + 1)
|
|
|
- }, 2000)
|
|
|
- }
|
|
|
- flyIndex(0)
|
|
|
- return () => isStop = true
|
|
|
-}
|
|
|
+ pop();
|
|
|
+ flyIndex(i + 1);
|
|
|
+ }, 2000);
|
|
|
+ };
|
|
|
+ flyIndex(0);
|
|
|
+ return () => (isStop = true);
|
|
|
+};
|
|
|
watchEffect((onCleanup) => {
|
|
|
if (props.selected) {
|
|
|
- const success = () => emit('select', false)
|
|
|
- const stop = flyTaggingPositions(props.tagging, success)
|
|
|
- const keyupHandler = (ev: KeyboardEvent) => ev.code === 'Escape' && success()
|
|
|
+ const success = () => emit("select", false);
|
|
|
+ const stop = flyTaggingPositions(props.tagging, success);
|
|
|
+ const keyupHandler = (ev: KeyboardEvent) => ev.code === "Escape" && success();
|
|
|
|
|
|
- document.documentElement.addEventListener('keyup', keyupHandler, false)
|
|
|
+ document.documentElement.addEventListener("keyup", keyupHandler, false);
|
|
|
onCleanup(() => {
|
|
|
- stop()
|
|
|
- document.documentElement.removeEventListener('keyup', keyupHandler, false)
|
|
|
- })
|
|
|
+ stop();
|
|
|
+ document.documentElement.removeEventListener("keyup", keyupHandler, false);
|
|
|
+ });
|
|
|
}
|
|
|
-})
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped src="./style.scss"></style>
|
|
|
+<style lang="scss" scoped src="./style.scss"></style>
|