浏览代码

feat: 增加1.6.0 遮罩 earth功能

gemercheung 1 年之前
父节点
当前提交
eb7aeef91f

+ 2 - 2
packages/qjkankan-editor/public/static/template/skin/vtourskin.xml

@@ -1389,9 +1389,9 @@
       </action>
 
       <!-- 底部logo -->
-      <hotspot name="nadirlogo" awlays="true" renderer="css3d" visible="false" keep="true" url="masking.png" ath="0" atv="90" width="50%" handcursor="false" zoom="true" height="prop" distorted="true" scale="1" rotate="0.0" />
+      <hotspot width="32%" name="nadirlogo" awlays="true" renderer="css3d" visible="false" keep="true" url="masking.png" ath="0" atv="90"  handcursor="false" zoom="true" height="prop" distorted="true" scale="1" rotate="0.0" />
 
       <!-- 顶部logo -->
-      <hotspot name="peaklogo" awlays="true" renderer="css3d" visible="true" keep="true" url="masking.png" ath="0" atv="-90" width="50%" height="prop" handcursor="false" zoom="true" distorted="true" scale="1" rotate="0.0" />
+      <hotspot width="32%" name="peaklogo" awlays="true" renderer="css3d" visible="true" keep="true" url="masking.png" ath="0" atv="-90"  height="prop" handcursor="false" zoom="true" distorted="true" scale="1" rotate="0.0" />
 
 </krpano>

+ 5 - 0
packages/qjkankan-editor/src/Store/index.js

@@ -36,6 +36,8 @@ const store = new Vuex.Store({
       type: "", // 'topologyGroupLevel1': 拓扑结构中一级分组;'topologyGroupLevel2': 拓扑结构中二级分组;'scene': 场景(全景图和三维场景)
       node: {},
     },
+    // 1.6.0 导航锁V4不能选
+    isLockV4Scene: false,
   },
   getters: {
     userAvatar: (state) => state.userAvatar,
@@ -249,6 +251,9 @@ const store = new Vuex.Store({
       state.editorNavDragInfo.type = "";
       state.editorNavDragInfo.node = {};
     },
+    lockNavV4Scene(state, status) {
+      state.isLockV4Scene = status;
+    },
   },
   actions: {
     refreshUserInfo(context) {

+ 20 - 6
packages/qjkankan-editor/src/Store/modules/scene.js

@@ -1,5 +1,10 @@
 import { i18n } from "@/lang";
 
+const initCustomMask = {
+  sky: { isShow: false, icon: "", scale: 1, fodderId: "" },
+  earth: { isShow: false, icon: "", scale: 1, fodderId: "" },
+};
+
 export default {
   namespaced: true,
   state() {
@@ -8,10 +13,7 @@ export default {
       list: [],
       //当前场景
       currentScene: {
-        customMask: {
-          sky: { isShow: false, icon: "", scale: 1, fodderId: "" },
-          earth: { isShow: false, icon: "", scale: 1, fodderId: "" },
-        },
+        customMask: initCustomMask,
       },
       //访问密码
       password: "",
@@ -39,6 +41,18 @@ export default {
   },
   mutations: {
     setScenes(state, payload) {
+      /**
+       * 1.6.0 补数据 customMask数据体
+       */
+      if (Array.isArray(payload)) {
+        payload.forEach((item, index) => {
+          if (!("customMask" in item)) {
+            console.log("item", item);
+            payload[index]["customMask"] = initCustomMask;
+          }
+        });
+      }
+
       state.list = payload;
     },
     setPassword(state, payload) {
@@ -46,8 +60,8 @@ export default {
     },
 
     // 设置当前场景
-    setCurrentScene(state, payload, rootState) {
-      state.currentScene = Object.assign({}, state.currentScene, payload);
+    setCurrentScene(state, payload) {
+      state.currentScene = payload;
     },
     // 设置当前二级分组
     setCurrentSecondary(state, payload) {

+ 9 - 3
packages/qjkankan-editor/src/framework/play/pano/components/list.vue

@@ -25,6 +25,7 @@
             class="swiper-slide"
             :class="{
               active: currentScene.id == item.id,
+              disabled: isLockV4Scene,
               // loopspan:
               //   item.sceneTitle.length > spanlength &&
               //   currentScene.id == item.id,
@@ -86,6 +87,7 @@
             @click="tabSecondary(item)"
             :class="{
               active: currentSecondary.id == item.id,
+              disabled: isLockV4Scene,
               loopspan:
                 fixTitle(item.name).length > spanlength &&
                 currentSecondary.id == item.id,
@@ -93,7 +95,7 @@
             v-for="(item, i) in secondaryList"
             :key="i"
           >
-          <marquee-text
+            <marquee-text
               :duration="Math.ceil(fixTitle(item.name).length / 10) * 5"
               :key="item.id"
               :repeat="1"
@@ -124,6 +126,7 @@
           class="swiper-slide"
           :class="{
             active: currentCatalogRoot.id == item.id,
+            disabled: isLockV4Scene,
             loopspan:
               fixTitle(item.name).length > spanlength &&
               currentCatalogRoot.id == item.id,
@@ -132,7 +135,7 @@
           v-for="(item, i) in metadata.catalogRoot"
           :key="i"
         >
-        <marquee-text
+          <marquee-text
             :duration="Math.ceil(fixTitle(item.name).length / 10) * 5"
             :key="item.id"
             :repeat="1"
@@ -153,7 +156,7 @@
 </template>
 
 <script>
-import { mapGetters } from "vuex";
+import { mapGetters, mapState } from "vuex";
 import { debounce } from "lodash";
 import MarqueeText from "vue-marquee-text-component";
 
@@ -223,6 +226,9 @@ export default {
     },
   },
   computed: {
+    ...mapState({
+      isLockV4Scene: "isLockV4Scene",
+    }),
     ...mapGetters({
       metadata: "scene/metadata",
       scenes: "scene/list",

+ 18 - 0
packages/qjkankan-editor/src/framework/play/pano/index.vue

@@ -135,6 +135,7 @@ export default {
             const { sky, earth } = newVal.customMask;
             this.handleVisual(visual);
             this.handleSkyCover(sky);
+            this.handleEarthCover(earth);
           } catch (error) {
             console.error(error);
           }
@@ -241,6 +242,23 @@ export default {
         }
       }
     },
+    /**
+     * 1.6 处理遮罩层
+     * @param {*} sky
+     */
+    handleEarthCover(earth) {
+      if (earth) {
+        if (earth.isShow) {
+          this.$getKrpano().set("hotspot[nadirlogo].visible", true);
+          earth.icon &&
+            this.$getKrpano().set("hotspot[nadirlogo].url", earth.icon);
+          earth.scale &&
+            this.$getKrpano().set("hotspot[nadirlogo].scale", earth.scale);
+        } else {
+          this.$getKrpano().set("hotspot[nadirlogo].visible", false);
+        }
+      }
+    },
     handleRouterCoverForCap(isRoute) {
       if (isRoute) {
         this.$getKrpano().set("hotspot[peaklogo].visible", false);

+ 189 - 56
packages/qjkankan-editor/src/views/cover/setting.vue

@@ -1,50 +1,121 @@
 <template>
   <div class="cover-panel">
-    <div class="title">
-      <!-- {{ $i18n.t("explanation.explanation_settings") }} -->
-      遮罩设置
-      <i
-        class="iconfont icon-help_i tool-tip-for-editor"
-        v-tooltip="$i18n.t('explanation.explanation_tips')"
-      />
-    </div>
+    <template v-if="currentScene.type !== '4dkk'">
+      <div class="title">
+        <!-- {{ $i18n.t("explanation.explanation_settings") }} -->
+        遮罩设置
+        <i
+          class="iconfont icon-help_i tool-tip-for-editor"
+          v-tooltip="$i18n.t('explanation.explanation_tips')"
+        />
+      </div>
+      <!-- sky start -->
+      <div class="swi-col">
+        <span> 天空遮罩 </span>
+        <switcher
+          :value="sky.isShow"
+          @change="(value) => (sky.isShow = Boolean(value))"
+        ></switcher>
+      </div>
+      <div class="swi-col update-col">
+        <SelectedImage
+          :imgSrc="sky.icon"
+          :defaultImgSrc="
+            require(`@/assets/images/default/mask_bg_${$lang}.png`)
+          "
+          @cancel="onClickCancelSkyLogo"
+        ></SelectedImage>
+        <div class="action">
+          <button @click="onSelectPic('sky')" class="ui-button submit">
+            选择图片
+          </button>
+          <div
+            class="ui-remark"
+            v-html="$i18n.t(`edit_settings.mask_size`)"
+          ></div>
+        </div>
+      </div>
 
-    <div class="swi-col">
-      <span> 天空遮罩 </span>
-      <switcher
-        :value="sky.isShow"
-        @change="(value) => (sky.isShow = Boolean(value))"
-      ></switcher>
-    </div>
-    <div class="swi-col update-col">
-      <SelectedImage
-        :imgSrc="sky.icon"
-        :defaultImgSrc="require(`@/assets/images/default/mask_bg_${$lang}.png`)"
-        @cancel="onClickCancelSkyLogo"
-      ></SelectedImage>
-      <div class="action">
-        <button @click="onSelectPic('sky')" class="ui-button submit">
-          选择图片
-        </button>
-        <div
-          class="ui-remark"
-          v-html="$i18n.t(`edit_settings.mask_size`)"
-        ></div>
+      <div class="up-col">
+        <span> 缩放比例 </span>
+
+        <slider
+          v-model="sky.scale"
+          show-stops
+          :marks="scaleMarks"
+          :step="0.1"
+          :min="0.5"
+          :max="2"
+        />
+      </div>
+      <!-- sky end -->
+      <div style="margin: 30px 0"></div>
+      <!-- earth start -->
+      <div class="swi-col">
+        <span> 地面遮罩 </span>
+        <switcher
+          :value="earth.isShow"
+          @change="(value) => (earth.isShow = Boolean(value))"
+        ></switcher>
+      </div>
+      <div class="swi-col update-col">
+        <SelectedImage
+          :imgSrc="earth.icon"
+          :defaultImgSrc="
+            require(`@/assets/images/default/mask_bg_${$lang}.png`)
+          "
+          @cancel="onClickCancelSkyLogo"
+        ></SelectedImage>
+        <div class="action">
+          <button @click="onSelectPic('earth')" class="ui-button submit">
+            选择图片
+          </button>
+          <div
+            class="ui-remark"
+            v-html="$i18n.t(`edit_settings.mask_size`)"
+          ></div>
+        </div>
       </div>
-    </div>
 
-    <div class="up-col">
-      <span> 缩放比例 </span>
+      <div class="up-col">
+        <span> 缩放比例 </span>
 
-      <slider
-        v-model="sky.scale"
-        show-stops
-        :marks="scaleMarks"
-        :step="0.1"
-        :min="0.5"
-        :max="2"
-      />
+        <slider
+          v-model="earth.scale"
+          show-stops
+          :marks="scaleMarks"
+          :step="0.1"
+          :min="0.5"
+          :max="2"
+        />
+      </div>
+      <!-- earth end -->
+
+      <div class="swi-col" style="padding-top: 15px">
+        <span> 应用到全部全景图 </span>
+        <switcher
+          :value="isApplyToAll"
+          @change="(value) => (isApplyToAll = Boolean(value))"
+        ></switcher>
+      </div>
+    </template>
+    <div class="goto-4dkk-tip" v-if="currentScene.type === '4dkk'">
+      <div class="img-wrap">
+        <img
+          class=""
+          src="@/assets/images/default/goto-4dage.png"
+          alt=""
+          draggable="false"
+        />
+        <div class="tip-text">
+          {{ $i18n.t("screen.goto_4dkk_edit_tips") }}
+        </div>
+      </div>
+      <button class="ui-button submit" @click="onClickGo4dkk">
+        {{ $i18n.t("navigation.go_scene_editor") }}
+      </button>
     </div>
+
     <div class="dialog" style="z-index: 2000" v-if="isShowSelectionWindow">
       <MaterialSelector
         :title="$i18n.t(`gather.select_material`)"
@@ -76,6 +147,7 @@ export default {
   },
   data() {
     return {
+      isApplyToAll: false,
       isShowSelectionWindow: false,
       isSelect: "",
       scaleMarks: {
@@ -103,37 +175,56 @@ export default {
         if (this.currentScene.type === "pano" && val) {
           this.currentScene.customMask.sky = val;
           this.updateCurrentScene();
+          this.handlePeakStatus(val.isShow);
+          this.handlePeakScale(val.scale);
+          this.handlePeakURL(val.icon);
         }
       },
       deep: true,
     },
-    "sky.isShow": {
+    earth: {
       handler: function (val) {
-        this.handlePeakStatus(val);
+        if (this.currentScene.type === "pano" && val) {
+          this.currentScene.customMask.earth = val;
+          this.updateCurrentScene();
+          this.handleNadirStatus(val.isShow);
+          this.handleNadirScale(val.scale);
+          this.handleNadirURL(val.icon);
+        }
       },
-      immediate: true,
+      deep: true,
     },
-    "sky.scale": {
+    isApplyToAll: {
       handler: function (val) {
-        this.handlePeakScale(val);
+        if (val) {
+          this.$confirm({
+            content: "是否应用到全部全景图?",
+            ok: () => {},
+            no: () => {
+              this.isApplyToAll = false;
+            },
+          });
+        }
       },
       immediate: true,
     },
-    "sky.icon": {
-      handler: function (val) {
-        this.handlePeakURL(val);
+    "currentScene.customMask": {
+      handler: function (newVal) {
+        if (newVal) {
+          const { sky, earth } = newVal;
+          this.sky = sky;
+          this.earth = earth;
+        }
       },
+      deep: true,
       immediate: true,
     },
   },
-  mounted() {
-    const { customMask } = this.currentScene;
-    if (customMask) {
-      this.sky = this.currentScene.customMask.sky;
-      this.earth = this.currentScene.customMask.earth;
-    }
-  },
+  mounted() {},
   methods: {
+    onClickGo4dkk() {
+      window.open("/#/scene");
+    },
     onClickCancelSkyLogo() {
       this.handlePeakURL("/static/template/skin/masking.png");
     },
@@ -150,7 +241,7 @@ export default {
       const status_b = !!status;
       const kr = this.$getKrpano();
       if (kr) {
-        console.log("handlePeakStatus", status);
+        // console.log("handlePeakStatus", status);
         kr.set("hotspot[peaklogo].visible", status_b);
       }
     },
@@ -166,6 +257,25 @@ export default {
         kr.set("hotspot[peaklogo].scale", scale);
       }
     },
+    handleNadirStatus(status) {
+      const status_b = !!status;
+      const kr = this.$getKrpano();
+      if (kr) {
+        kr.set("hotspot[nadirlogo].visible", status_b);
+      }
+    },
+    handleNadirURL(url) {
+      const kr = this.$getKrpano();
+      if (kr && url) {
+        kr.set("hotspot[nadirlogo].url", url);
+      }
+    },
+    handleNadirScale(scale) {
+      const kr = this.$getKrpano();
+      if (kr) {
+        kr.set("hotspot[nadirlogo].scale", scale);
+      }
+    },
     updateCurrentScene() {
       this.$store.dispatch("scene/syncCurrentSceneToStore");
     },
@@ -228,5 +338,28 @@ export default {
     width: 120px;
     height: 120px;
   }
+  .goto-4dkk-tip {
+    > .img-wrap {
+      position: relative;
+      width: 100%;
+      > .img {
+        width: 100%;
+      }
+      > .tip-text {
+        position: absolute;
+        left: 50%;
+        bottom: 32px;
+        transform: translateX(-50%);
+        font-size: 14px;
+        color: #fff;
+        opacity: 0.6;
+        white-space: pre;
+      }
+    }
+    > button {
+      margin-top: 16px;
+      width: 100%;
+    }
+  }
 }
 </style>

+ 10 - 6
packages/qjkankan-editor/src/views/screen/Setting.vue

@@ -85,9 +85,11 @@ export default {
   watch: {
     "currentScene.initVisual": {
       handler(val) {
-        const { vlookatmin, vlookatmax } = val;
-        if (vlookatmin && vlookatmax) {
-          this.vlookat = [vlookatmin, vlookatmax];
+        if (val) {
+          const { vlookatmin, vlookatmax } = val;
+          if (vlookatmin && vlookatmax) {
+            this.vlookat = [vlookatmin, vlookatmax];
+          }
         }
       },
       deep: true,
@@ -110,9 +112,11 @@ export default {
       if (val) {
         const min = Math.min(...val);
         const max = Math.max(...val);
-        this.currentScene.initVisual.vlookatmin = min;
-        this.currentScene.initVisual.vlookatmax = max;
-        this.handleKrAction(min, max);
+        if (this.currentScene.initVisual) {
+          this.currentScene.initVisual.vlookatmin = min;
+          this.currentScene.initVisual.vlookatmax = max;
+          this.handleKrAction(min, max);
+        }
       }
     },
     handleKrAction(min, max) {