123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- <template>
- <!-- -->
- <ui-group-option
- :class="`sign-guide ${hover || focus ? 'active' : ''} `"
- @click.stop="clickHandler"
- @mouseenter="enterHandler"
- @mouseleave="leaveHandler"
- >
- <div class="info">
- <div class="guide-cover">
- <span class="img">
- <ui-icon type="pic_path" class="path-icon" />
- </span>
- <!-- @click="playSceneGuide(paths, undefined, true)" -->
- <ui-icon
- type="preview"
- class="icon"
- ctrl
- @click="playScenePath(path, true)"
- v-if="path.points.length"
- />
- </div>
- <div>
- <p>{{ path.name }}</p>
- </div>
- </div>
- <div class="actions" v-if="edit" @click.stop>
- <ui-more
- :options="menus"
- style="margin-left: 20px"
- @click="(action: keyof typeof actions) => actions[action]()"
- />
- </div>
- </ui-group-option>
- </template>
- <script setup lang="ts">
- import { Path } from "@/store";
- import { getPathNode, playScenePath } from "@/sdk/association/path";
- import { computed, ref, watch, watchEffect } from "vue";
- import { custom } from "@/env";
- const props = withDefaults(defineProps<{ path: Path; edit?: boolean }>(), {
- edit: true,
- });
- const emit = defineEmits<{
- (e: "delete"): void;
- (e: "edit"): void;
- }>();
- const menus = [
- { label: "编辑", value: "edit" },
- { label: "删除", value: "delete" },
- ];
- const actions = {
- edit: () => emit("edit"),
- delete: () => emit("delete"),
- };
- const focus = ref(false);
- const hover = ref(false);
- const node = computed(() => getPathNode(props.path.id));
- watchEffect((onCleanup) => {
- if (!node.value) return;
- const $node = node.value;
- const focusHandler = (f: boolean) => {
- // node.value?.fly();
- focus.value = f;
- console.error("focus", f);
- };
- const leaveHandler = () => {
- hover.value = false;
- };
- const enterHandler = () => {
- hover.value = true;
- };
- $node.bus.on("enter", enterHandler);
- $node.bus.on("leave", leaveHandler);
- $node.bus.on("focus", focusHandler);
- onCleanup(() => $node.bus.off("focus", focusHandler));
- });
- const leaveHandler = () => {
- hover.value = false;
- node.value?.highlight && node.value?.highlight(false);
- };
- const enterHandler = () => {
- hover.value = true;
- node.value?.highlight && node.value?.highlight(true);
- };
- const clickHandler = () => {
- node.value?.fly();
- };
- </script>
- <style lang="scss" scoped>
- .sign-guide {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px 0;
- margin-bottom: 0;
- border-bottom: 1px solid var(--colors-border-color);
- position: relative;
- cursor: pointer;
- &:first-child {
- border-top: 1px solid var(--colors-border-color);
- }
- &.active::after {
- content: "";
- position: absolute;
- pointer-events: none;
- inset: 0 -20px;
- background-color: rgba(0, 200, 175, 0.16);
- }
- .info {
- flex: 1;
- display: flex;
- align-items: center;
- .guide-cover {
- position: relative;
- &::after {
- content: "";
- position: absolute;
- inset: 0;
- background: rgba(0, 0, 0, 0.2);
- }
- .icon {
- position: absolute;
- z-index: 1;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- font-size: 16px;
- }
- .path-icon {
- color: rgba(255, 255, 255, 0.2);
- font-size: 30px;
- }
- .img {
- width: 48px;
- height: 48px;
- object-fit: cover;
- border-radius: 4px;
- overflow: hidden;
- background-color: #535555;
- display: block;
- }
- }
- div {
- margin-left: 10px;
- p {
- color: #fff;
- word-break: break-all;
- font-size: 14px;
- margin-bottom: 6px;
- }
- }
- }
- .actions {
- flex: none;
- }
- }
- </style>
|