123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- <template>
- <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"
- >
- <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)"
- :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]()"
- />
- </template>
- </div>
- </ui-group-option>
- </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,
- getFuseModel,
- getFuseModelShowVariable,
- getTaggingIsShow
- } from '@/store'
- import type { Tagging } from '@/store'
- const props = withDefaults(
- defineProps<{ tagging: Tagging, selected?: boolean, edit?: boolean }>(),
- { edit: true }
- )
- 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 menus = [
- { label: '编辑', value: 'edit' },
- { label: '删除', value: 'delete' },
- ]
- const actions = {
- edit: () => emit('edit'),
- delete: () => emit('delete')
- }
- const flyTaggingPositions = (tagging: Tagging, callback?: () => void) => {
- const positions = getTaggingPositions(tagging)
- let isStop = false
- const flyIndex = (i: number) => {
- if (isStop || i >= positions.length) {
- callback && nextTick(callback)
- return;
- }
- const position = positions[i]
- const model = getFuseModel(position.modelId)
- if (!model || !getFuseModelShowVariable(model).value) {
- flyIndex(i + 1)
- return;
- }
- const pop = showTaggingPositionsStack.push(ref(new WeakSet([position])))
- sdk.comeTo({
- position: position.localPos,
- modelId: position.modelId,
- dur: 300,
- distance: 3
- })
-
- setTimeout(() => {
- 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()
- document.documentElement.addEventListener('keyup', keyupHandler, false)
- onCleanup(() => {
- stop()
- document.documentElement.removeEventListener('keyup', keyupHandler, false)
- })
- }
- })
- </script>
- <style lang="scss" scoped src="./style.scss"></style>
|