gemercheung 2 lat temu
rodzic
commit
fbcd7359a7

+ 53 - 7
src/App.vue

@@ -1,18 +1,38 @@
 <script setup lang="ts">
-import { onMounted, ref, h } from "vue";
+import { onMounted, ref, h, computed, unref, watchEffect } from "vue";
 import { createApp } from "/@/hooks/userApp";
 import tagView from "/@/components/custom/tagView.vue";
 import LoadingLogo from "/@/components/basic/loading.vue";
 import MiniMap from "/@/components/basic/miniMap.vue";
+import FloorplanView from "/@/components/basic/floorplan.vue";
 import { useSceneStore } from "./store/modules/scene";
 import type { FloorsType } from "./store/modules/scene";
 import { useAppStore } from "./store/modules/app";
 const sceneStore = useSceneStore();
 const appStore = useAppStore();
-
+const dataLoaded = ref(false);
 const scene$ = ref<HTMLElement | null>(null);
 const refMiniMap = ref<Nullable<string>>(null);
+const flying = computed(() => appStore.flying);
+const player = computed(() => appStore.player);
+const metadata = computed(() => sceneStore.metadata);
+const mode = computed(() => appStore.mode);
+const controls = computed(() => {
+  return metadata.value.controls;
+});
+const floorplanViewShow = computed(() => {
+  return (
+    Boolean(controls.value.showDollhouse) &&
+    Boolean(controls.value.showFloorplan) &&
+    mode.value !== "panorama"
+  );
+});
 const show = ref(false);
+
+watchEffect(() => {
+  console.warn("mode", mode);
+});
+
 onMounted(async () => {
   const app = await createApp({
     dom: scene$.value as HTMLElement,
@@ -45,6 +65,7 @@ onMounted(async () => {
   app.Scene.on("loaded", (pano) => {
     refMiniMap.value = "[xui_min_map]";
     appStore.setFloorId(pano.floorIndex);
+
     // store.commit("setFloorId", pano.floorIndex);
     // store.commit("rtc/setShowdaogou", true);
 
@@ -57,7 +78,7 @@ onMounted(async () => {
     if (!metadata.controls.showMap) {
       app.MinMap.hide(true);
     }
-    // dataLoaded.value = true;
+    dataLoaded.value = true;
   });
   app.store.on("floorcad", ({ floors }: { floors: FloorsType[] }) => {
     if (floors?.length) {
@@ -65,16 +86,41 @@ onMounted(async () => {
     }
   });
 });
+
+// method
+const changeMode = (name: string) => {
+  if (!flying.value) {
+    appStore.setMode(name);
+  } else {
+    appStore.setMode(name);
+  }
+};
 </script>
 
 <template>
   <LoadingLogo :thumb="true" />
   <div class="ui-view-layout" :class="{ show: show }">
     <div class="scene" ref="scene$"></div>
-    <!-- 小地图 start -->
-    <MiniMap :show="true" :to="refMiniMap" />
-    <!-- 小地图 end -->
+    <template v-if="dataLoaded">
+      <!-- 小地图 start -->
+      <MiniMap
+        :show="!!unref(refMiniMap) && player.showWidgets"
+        :show-dollhouse="Boolean(controls.showDollhouse)"
+        :to="refMiniMap"
+        @change-mode="changeMode"
+      />
+      <!-- 小地图 end -->
+      <!-- 平面图 start -->
+      <FloorplanView
+        :show="floorplanViewShow"
+        :mode="mode"
+        @change-mode="changeMode"
+      />
+      <!-- 平面图 end -->
+    </template>
   </div>
 </template>
 
-<style lang="scss"></style>
+<style lang="scss">
+@import "./app.scss";
+</style>

+ 162 - 0
src/app.scss

@@ -0,0 +1,162 @@
+.tab-layer {
+  width: 100%;
+  text-align: center;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 10;
+  position: fixed;
+  left: 50%;
+  transform: translateX(-50%);
+  top: 2.3rem;
+  pointer-events: none;
+}
+.tabs {
+  pointer-events: auto;
+  position: relative;
+  display: flex;
+  background: #222222;
+  border-radius: 6px;
+  padding: 2px;
+  justify-content: center;
+  align-items: center;
+  border: 1px solid rgba(255, 255, 255, 0.1);
+  box-shadow: inset 0px 0px 6px 0px rgba(0, 0, 0, 0.5);
+  .background {
+    position: absolute;
+    left: 2px;
+    top: 2px;
+    bottom: 2px;
+    width: 50%;
+    border-radius: 4px;
+    background: #444444;
+    box-shadow: 2px 0px 4px 0px rgba(0, 0, 0, 0.3);
+    z-index: 0;
+    transition: left 0.3s;
+  }
+  span {
+    flex: 1;
+    color: #fff;
+    opacity: 0.5;
+    border-radius: 6px;
+    height: 0.94737rem;
+    font-size: 0.36842rem;
+    transition: all 0.3s ease;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding-left: 10px;
+    padding-right: 10px;
+    white-space: nowrap;
+    z-index: 1;
+    i {
+      font-size: 0.47368rem;
+      margin-right: 4px;
+      pointer-events: none;
+    }
+  }
+
+  span.active {
+    opacity: 1;
+  }
+}
+
+[xui_tags_view] {
+  .tag-body {
+    /* display: none; */
+    position: absolute;
+    left: 50%;
+    bottom: 50px;
+    transform: translateX(-50%) scale(0);
+    transform-origin: bottom;
+    transition: all 0.3s cubic-bezier(0.35, 0.32, 0.65, 0.63);
+    // pointer-events: none;
+    .tag-commodity {
+      min-width: 230px;
+      height: 76px;
+      background: rgba(255, 255, 255, 0.8);
+      box-shadow: 0px 3px 6px 0px rgba(0, 0, 0, 0.16);
+      border-radius: 2px;
+      position: relative;
+      margin-bottom: 30px;
+      &::before {
+        content: "";
+        display: inline-block;
+        left: 50%;
+        transform: translateX(-50%);
+        width: 2px;
+        height: 28px;
+        bottom: -30px;
+        background: linear-gradient(
+          145deg,
+          rgba(255, 255, 255, 0.8),
+          rgba(255, 255, 255, 0)
+        );
+        position: absolute;
+      }
+      .tag-avatar {
+        position: absolute;
+        z-index: 99;
+        width: 80px;
+        height: 80px;
+        background: #ffffff;
+        box-shadow: 0px 3px 6px 0px rgb(0 0 0 / 16%);
+        border-radius: 2px;
+        top: -14px;
+        left: -12px;
+        background-size: cover;
+        pointer-events: none;
+      }
+      > p {
+        color: #131d34;
+        font-size: 16px;
+        pointer-events: none;
+      }
+      .tag-title {
+        font-weight: bold;
+        color: #131d34;
+        padding: 10px 10px 10px 76px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        width: 240px;
+        font-size: 14px;
+      }
+      .tag-info {
+        color: #444444;
+        padding: 0 20px 0 76px;
+        font-size: 12px;
+        width: 240px;
+        > div {
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          max-width: 240px;
+        }
+      }
+    }
+    &.show {
+      transform: translateX(-50%) scale(1);
+    }
+  }
+}
+
+.gudieDisabled {
+  pointer-events: none !important;
+  * {
+    pointer-events: none !important;
+  }
+}
+
+@media (orientation: landscape) {
+  .tab-layer {
+    top: 1.2rem;
+    .tabs {
+      height: 0.7rem;
+      > span {
+        height: 0.7rem;
+        font-size: 0.25rem;
+      }
+    }
+  }
+}

+ 86 - 0
src/components/basic/floorplan.vue

@@ -0,0 +1,86 @@
+<template>
+  <div
+    :class="{
+      disabled: disabled,
+      // gudieDisabled: isshoppingguide && role != 'leader',
+    }"
+    class="tab-layer"
+  >
+    <div class="tabs" v-if="show">
+      <span
+        :class="{ active: isFloorplan }"
+        ref="floorplan_ref"
+        @click="changeMode('floorplan')"
+      >
+        <i
+        :class="{
+            'icon-show_plane_selected': isFloorplan,
+            'icon-show_plane_normal': !isFloorplan,
+          }"
+          class="iconfont ui-kankan-icon icon tip-h-center tip-v-bottom  iconzm-show_plane_normal"
+        ></i>
+
+        <!-- <ui-icon
+          :type="
+            mode == 'floorplan' ? 'show_plane_selected' : 'show_plane_normal'
+          "
+        ></ui-icon> -->
+        二维
+      </span>
+      <span
+        :class="{ active: isDollhouse }"
+        ref="dollhouse_ref"
+        @click="changeMode('dollhouse')"
+      >
+        <i
+          :class="{
+            'icon-show_3d_selected': isDollhouse,
+            'icon-show_3d_normal': !isDollhouse,
+          }"
+          class="iconfont ui-kankan-icon icon tip-h-center tip-v-bottom iconzm-show_3d_selected"
+        ></i>
+        <!-- <ui-icon
+          :type="mode == 'dollhouse' ? 'show_3d_selected' : 'show_3d_normal'"
+        ></ui-icon> -->
+        三维
+      </span>
+      <div class="background" ref="background"></div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { computed, defineComponent, ref, watchEffect } from "vue";
+import { propTypes } from "/@/utils/propTypes";
+const refMiniMap = ref<Nullable<string>>(null);
+const ifShow = ref(false);
+
+export default defineComponent({
+  name: "floorplan",
+  props: {
+    mode: propTypes.string.def(""),
+    disabled: propTypes.bool.def(false),
+    show: propTypes.bool.def(false),
+  },
+  emits: ["changeMode", "toggleMap"],
+  setup(props, { emit }) {
+    const isFloorplan = computed(() => props.mode === "floorplan");
+    const isDollhouse = computed(() => props.mode === "dollhouse");
+    watchEffect(() => {
+      console.log("floorplan", isFloorplan);
+    });
+
+    const changeMode = (eventName: string) => {
+      emit("changeMode", eventName);
+    };
+
+    return {
+      changeMode,
+      refMiniMap,
+      ifShow,
+      isFloorplan,
+      isDollhouse,
+    };
+  },
+});
+</script>

+ 36 - 12
src/components/basic/miniMap.vue

@@ -1,35 +1,57 @@
 <template>
-  <teleport v-if="show" :to="to">
+  <teleport v-show="show" v-if="ifShow" :to="refMiniMap">
     <span class="button-switch" @click.stop="toggleMap">
-      <!-- <ui-icon type="show_map_collect"></ui-icon> -->
+      <i
+        class="iconfont ui-kankan-icon icon tip-h-center tip-v-bottom icon-show_map_collect iconzm-show_map_collect"
+      />
     </span>
     <div v-if="showDollhouse" class="change" @click="changeMode">
-      <!-- <ui-icon type="show_3d_normal"></ui-icon> -->
+      <i
+        class="iconfont ui-kankan-icon icon tip-h-center tip-v-bottom icon-show_3d_normal iconzm-show_3d_normal"
+      />
       <span> 3D模型</span>
     </div>
   </teleport>
 </template>
 <script lang="ts">
-import { defineComponent, watchEffect } from "vue";
+import { defineComponent, onMounted, watchEffect, ref } from "vue";
 import { propTypes } from "/@/utils/propTypes";
+const refMiniMap = ref<Nullable<string>>(null);
+const ifShow = ref(false);
+const isCollapse = ref(false);
 
 export default defineComponent({
   name: "minMap",
   props: {
-    show: propTypes.bool.def(false),
+    show: propTypes.bool.def(true),
     showDollhouse: propTypes.bool.def(false),
-    to: propTypes.string.def(""),
+    to: {
+      type: String as PropType<Nullable<string>>,
+      default: null,
+    },
   },
   emits: ["changeMode", "toggleMap"],
   setup(props, { emit }) {
-    watchEffect(() => {
-      if (props.to?.length) {
-        debugger;
-      }
+    onMounted(() => {
+      watchEffect(() => {
+        if (props.to?.length) {
+          ifShow.value = true;
+          refMiniMap.value = props.to;
+        }
+      });
     });
-    // debugger
+
     const toggleMap = () => {
-      emit("toggleMap");
+      isCollapse.value = !isCollapse.value;
+      emit("toggleMap", isCollapse.value);
+      let $minmap = document.querySelector("[xui_min_map]");
+      if ($minmap) {
+        if (!isCollapse.value) {
+          $minmap.classList.remove("collapse");
+        } else {
+          $minmap.classList.add("collapse");
+        }
+      }
     };
     const changeMode = () => {
       emit("changeMode", "dollhouse");
@@ -38,6 +60,8 @@ export default defineComponent({
     return {
       toggleMap,
       changeMode,
+      refMiniMap,
+      ifShow,
     };
   },
 });

+ 2 - 1
src/main.ts

@@ -3,13 +3,14 @@ import './style.css'
 import "/@/assets/theme.editor.scss";
 import { setupStore } from '/@/store';
 import App from './App.vue'
+// import Components from "./global_components";
 
 async function bootstrap() {
     const app = createApp(App);
 
     // Configure store
     setupStore(app);
-
+    // app.use(Components)
 
     app.mount('#app');
 }

+ 1 - 0
src/store/modules/app.ts

@@ -55,6 +55,7 @@ export const useAppStore = defineStore({
             this.shoppingguide = payload
         },
         setMode(payload: string): void {
+            console.log('setMode', payload)
             if (payload == this.mode) {
                 return
             }