Forráskód Böngészése

feat: 增加1.6.0 遮罩 sky功能

gemercheung 1 éve
szülő
commit
0e2c616b14

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 367 - 366
packages/qjkankan-editor/public/static/template/skin/vtourskin.xml


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

@@ -1,6 +1,5 @@
 import { i18n } from "@/lang";
 
-
 export default {
   namespaced: true,
   state() {
@@ -8,20 +7,24 @@ export default {
       // 场景列表
       list: [],
       //当前场景
-      currentScene: {},
+      currentScene: {
+        customMask: {
+          sky: { isShow: false, icon: "", scale: 1, fodderId: "" },
+          earth: { isShow: false, icon: "", scale: 1, fodderId: "" },
+        },
+      },
       //访问密码
       password: "",
       //场景数据
       metadata: {},
       //当前一级分组
-      currentCatalogRoot:{},
+      currentCatalogRoot: {},
       //当前二级分组
-      currentSecondary:{},
+      currentSecondary: {},
       //二级分组
-      secondaryList:{},
+      secondaryList: {},
       //当前场景分组
-      currentScenesList:{},
-
+      currentScenesList: {},
     };
   },
   getters: {
@@ -43,8 +46,8 @@ export default {
     },
 
     // 设置当前场景
-    setCurrentScene(state, payload) {
-      state.currentScene = payload;
+    setCurrentScene(state, payload, rootState) {
+      state.currentScene = Object.assign({}, state.currentScene, payload);
     },
     // 设置当前二级分组
     setCurrentSecondary(state, payload) {
@@ -53,7 +56,10 @@ export default {
         return state.currentSecondary.id == item.category;
       });
 
-      this.commit('scene/setCurrentScenesList', arr.sort((a, b) => a.weight - b.weight))
+      this.commit(
+        "scene/setCurrentScenesList",
+        arr.sort((a, b) => a.weight - b.weight)
+      );
     },
 
     // 设置当前场景列表
@@ -69,29 +75,40 @@ export default {
         payload.children.forEach((item) => {
           state.metadata.catalogs.forEach((sub) => {
             if (item == sub.id) {
-              if (state.list.some(iii=>iii.category == sub.id)) {
+              if (state.list.some((iii) => iii.category == sub.id)) {
                 temp.push(sub);
               }
             }
           });
         });
-        
-      this.commit('scene/setSecondaryList', temp)
+
+      this.commit("scene/setSecondaryList", temp);
     },
 
     // 设置当前二级分组列表
-    setSecondaryList(state, payload){
-      state.secondaryList = payload
-      if (payload.length>0) {
-        this.commit('scene/setCurrentSecondary', payload[0])
+    setSecondaryList(state, payload) {
+      state.secondaryList = payload;
+      if (payload.length > 0) {
+        this.commit("scene/setCurrentSecondary", payload[0]);
       } else {
-        this.commit('scene/setCurrentSecondary', {})
+        this.commit("scene/setCurrentSecondary", {});
       }
     },
     setMetaData(state, payload) {
       state.metadata = payload;
-      if (location.href.includes('show.html')) {
-        document.title = payload.name || i18n.t('common.notit')
+      if (location.href.includes("show.html")) {
+        document.title = payload.name || i18n.t("common.notit");
+      }
+    },
+  },
+  actions: {
+    syncCurrentSceneToStore({ commit, state, rootState }) {
+      const currentScene = state.currentScene;
+      const updateSceneIndex = Array.from(rootState.info.scenes).findIndex(
+        (item) => item.id === currentScene.id
+      );
+      if (updateSceneIndex > -1) {
+        rootState.info.scenes[updateSceneIndex] = currentScene;
       }
     },
   },

+ 1 - 14
packages/qjkankan-editor/src/core/utils.js

@@ -227,24 +227,11 @@ export default class Utils {
    */
 
   toggleHotspot(krpano, toggle) {
+    // console.error("toggleHotspot");
     try {
       krpano.call(`set_hotspot_visible(${toggle})`);
     } catch (e) {
       e;
     }
   }
-
-  /**
-   * 显示隐藏热点
-   */
 }
-
-// toggleHotspot(krpano,someData,toggle){
-//   if (!someData) {
-//     return
-//   }
-//   let mysd = JSON.parse(someData)
-//   mysd.hotspots.forEach(item => {
-//     krpano.set(`hotspot[${item.name}].visible`,toggle);
-//   });
-// }

+ 1 - 0
packages/qjkankan-editor/src/framework/EditorHead.vue

@@ -159,6 +159,7 @@ export default {
         );
       }
       const scenes = this.info.scenes;
+      // debugger
       if (scenes && scenes.length > 0) {
         scenes.forEach((scene, index) => {
           if (

+ 2 - 1
packages/qjkankan-editor/src/framework/core/index.vue

@@ -1,4 +1,5 @@
 <template>
+  <!-- 没引用 -->
   <div class="pano-body">
     <div class="none-center" v-show="!activeItem">请先上传或添加场景素材</div>
 
@@ -146,7 +147,7 @@ export default {
   },
   mounted() {
     window.__krfn = __krfn;
-
+    debugger;
     this.$bus.on("currentPcode", (data) => {
       this.activeItem = data;
     });

+ 0 - 456
packages/qjkankan-editor/src/framework/play/pano/components/list copy.vue

@@ -1,456 +0,0 @@
-<template>
-  <div class="bar-list" v-if="show" :class="{ disable: isEditing }">
-    <div
-      class="top-con"
-      v-show="currentScenesList.length > 0"
-      :style="`width:${
-        Math.max(scenesListW, secondaryW) > 1150
-          ? '100%'
-          : Math.max(scenesListW, secondaryW) + 120 + 'px'
-      }`"
-    >
-      <div
-        class="swiper-container"
-        :style="`width:${scenesListW > 1150 ? '100%' : scenesListW + 'px'}`"
-        id="swScenes"
-        ref="sw"
-        v-swiper:mySwiper="swiperOptions"
-        v-if="currentScenesList.length > 0"
-      >
-        <ul class="swiper-wrapper">
-          <li
-            v-tooltip="
-              item.type === '4dkk' ? $i18n.t('navigation.scene_edit_tips') : ''
-            "
-            @click="tabCurrentScene(item)"
-            class="swiper-slide"
-            :class="{
-              active: currentScene.id == item.id,
-              loopspan:
-                item.sceneTitle.length > spanlength &&
-                currentScene.id == item.id,
-            }"
-            :style="{ backgroundImage: `url(${item.icon})` }"
-            v-for="(item, i) in currentScenesList"
-            :key="item.id"
-          >
-            <i
-              class="iconfont icon-edit_type_3d"
-              :class="{ iconedit_type_panorama: item.type !== '4dkk' }"
-            ></i>
-            <div>
-              <span v-if="currentScene.id == item.id">{{
-                item.sceneTitle
-              }}</span>
-              <span v-else>{{
-                item.sceneTitle.length > spanlength
-                  ? item.sceneTitle.slice(0, spanlength)
-                  : item.sceneTitle
-              }}</span>
-            </div>
-          </li>
-        </ul>
-      </div>
-
-      <div
-        class="swiper-container"
-        :style="`width:${Math.min(secondaryW, innerW)}px`"
-        id="swSecondary"
-        ref="sw1"
-        v-swiper:mySwipera="swiperOptions"
-        v-if="
-          !(
-            secondaryList.length === 1 &&
-            (secondaryList[0].name === '默认二级分组' ||
-              secondaryList[0].name === $i18n.t('navigation.default_group_two'))
-          )
-        "
-      >
-        <ul class="swiper-wrapper">
-          <li
-            class="swiper-slide"
-            @click="tabSecondary(item)"
-            :class="{
-              active: currentSecondary.id == item.id,
-              loopspan:
-                fixTitle(item.name).length > spanlength &&
-                currentSecondary.id == item.id,
-            }"
-            v-for="(item, i) in secondaryList"
-            :key="i"
-          >
-            <span v-if="currentSecondary.id == item.id">{{
-              fixTitle(item.name)
-            }}</span>
-            <span v-else>{{
-              fixTitle(item.name).length > spanlength
-                ? fixTitle(item.name).slice(0, spanlength)
-                : fixTitle(item.name)
-            }}</span>
-          </li>
-        </ul>
-      </div>
-    </div>
-
-    <div
-      class="swiper-container"
-      :style="`width:${catalogRootW > innerW ? '100%' : catalogRootW + 'px'}`"
-      id="swcatalogRoot"
-      ref="sw2"
-      v-swiper:mySwiperb="swiperOptions"
-      v-if="metadata.catalogRoot.length > 0 && metadata.catalogs.length > 1"
-    >
-      <ul class="swiper-wrapper" v-if="metadata.catalogRoot.length > 1">
-        <li
-          class="swiper-slide"
-          :class="{
-            active: currentCatalogRoot.id == item.id,
-            loopspan:
-              fixTitle(item.name).length > spanlength &&
-              currentCatalogRoot.id == item.id,
-          }"
-          @click="tabRoot(item)"
-          v-for="(item, i) in metadata.catalogRoot"
-          :key="i"
-        >
-          <span v-if="currentCatalogRoot.id == item.id">{{
-            fixTitle(item.name)
-          }}</span>
-          <span v-else>{{
-            fixTitle(item.name).length > spanlength
-              ? fixTitle(item.name).slice(0, spanlength)
-              : fixTitle(item.name)
-          }}</span>
-        </li>
-      </ul>
-    </div>
-  </div>
-</template>
-
-<script>
-import { mapGetters } from "vuex";
-
-import { directive } from "vue-awesome-swiper";
-// import style (<= Swiper 5.x)
-import "swiper/css/swiper.css";
-
-export default {
-  data() {
-    return {
-      spanlength: 6,
-      show: false,
-      innerW: 1150,
-      swidth: {
-        swcatalogRoot: 104,
-        swSecondary: 84,
-        swScenes: 72,
-      },
-    };
-  },
-  directives: {
-    swiper: directive,
-  },
-
-  watch: {
-    currentSecondary() {
-      this.loadList();
-    },
-    currentScenesList() {
-      this.loadList();
-    },
-    metadata: {
-      deep: true,
-      handler: function (newVal) {
-        if (newVal.scenes) {
-          this.$store.commit("scene/setScenes", newVal.scenes);
-          if (!this.show) {
-            this.show = true;
-            this.loadList();
-          } else {
-            // 更新列表
-            this.tabRoot(this.currentCatalogRoot);
-          }
-        }
-      },
-    },
-  },
-  computed: {
-    ...mapGetters({
-      metadata: "scene/metadata",
-      scenes: "scene/list",
-      currentScene: "scene/currentScene",
-      currentCatalogRoot: "scene/currentCatalogRoot",
-      currentSecondary: "scene/currentSecondary",
-      secondaryList: "scene/secondaryList",
-      isShowScenesList: "scene/isShowScenesList",
-      currentScenesList: "scene/currentScenesList",
-      isEditing: "isEditing",
-    }),
-
-    scenesListW() {
-      return this.currentScenesList.length * (this.swidth["swScenes"] + 10);
-    },
-    secondaryW() {
-      return this.secondaryList.length * (this.swidth["swSecondary"] + 10);
-    },
-    catalogRootW() {
-      return (
-        this.metadata.catalogRoot.length * (this.swidth["swcatalogRoot"] + 10)
-      );
-    },
-    swiperOptions() {
-      return {
-        slidesPerView: "auto",
-        centeredSlides: true,
-        centerInsufficientSlides: true,
-        centeredSlidesBounds: true,
-        freeMode: {
-          enabled: true,
-          sticky: false,
-        },
-      };
-    },
-  },
-  methods: {
-    fixTitle(name) {
-      if (name == "默认二级分组") {
-        name = this.$i18n.t("navigation.default_group_two");
-      } else if (name == "一级分组") {
-        name = this.$i18n.t("navigation.group_one");
-      } else {
-        name = name;
-      }
-      return name;
-    },
-    loadList() {
-      this.$nextTick(() => {
-        // let t = setTimeout(() => {
-        //   clearTimeout(t);
-        //   ["#swcatalogRoot", "#swSecondary", "#swScenes"].forEach((item) => {
-        //     new Swiper(item, {
-        //       slidesPerView: "auto",
-        //       spaceBetween: 10,
-        //       centeredSlides: true,
-        //       centerInsufficientSlides: true,
-        //       centeredSlidesBounds: true,
-        //       freeMode: true,
-        //     });
-        //   });
-        // }, 100);
-      });
-    },
-
-    tabCurrentScene(data) {
-      this.$store.commit("scene/setCurrentScene", data);
-    },
-
-    tabSecondary(data) {
-      this.$store.commit("scene/setCurrentSecondary", data);
-    },
-
-    tabRoot(data) {
-      this.$store.commit("scene/setCurrentCatalogRoot", data);
-    },
-  },
-
-  mounted() {
-    // console.log(this.metadata,'metadata');
-    // this.loadList();
-  },
-};
-</script>
-
-<style lang="less" scoped>
-@width: 1150px;
-
-.bar-list {
-  position: absolute;
-  bottom: 28px;
-  left: 50%;
-  transform: translateX(-50%);
-  text-align: center;
-  max-width: @width;
-  overflow: hidden;
-  transition: 0.3s all ease;
-  .swiper-container {
-    width: 100%;
-    position: relative;
-
-    > ul {
-      margin: 0 auto;
-      > li {
-        margin: 0 5px;
-        white-space: nowrap;
-
-        > span,
-        > div > span {
-          cursor: pointer;
-          display: inline-block;
-          color: rgba(255, 255, 255, 0.6);
-        }
-
-        &.loopspan {
-          > span,
-          > div > span {
-            animation: 5s wordsLoop linear infinite normal;
-          }
-        }
-
-        &.active {
-          > span,
-          > div > span {
-            color: rgba(255, 255, 255, 1);
-          }
-        }
-      }
-    }
-  }
-
-  .top-con {
-    margin: 0 auto 10px;
-    padding: 10px 0;
-    background: linear-gradient(
-      268deg,
-      rgba(0, 0, 0, 0) 0%,
-      rgba(0, 0, 0, 0.4) 25%,
-      rgba(0, 0, 0, 0.4) 75%,
-      rgba(0, 0, 0, 0) 100%
-    );
-  }
-
-  #swcatalogRoot {
-    > ul {
-      > li {
-        width: 104px;
-        background: rgba(0, 0, 0, 0.5);
-        border-radius: 4px;
-        padding: 4px 10px;
-        border: 1px solid rgba(255, 255, 255, 0.5);
-        box-sizing: border-box;
-        overflow: hidden;
-
-        > span {
-          width: 100%;
-          word-break: keep-all;
-        }
-
-        &.active {
-          border: 1px solid rgba(255, 255, 255, 1);
-        }
-      }
-    }
-  }
-
-  #swSecondary {
-    margin: 20px auto 10px;
-
-    > ul {
-      > li {
-        width: 84px;
-        box-sizing: border-box;
-        overflow: hidden;
-        padding-bottom: 6px;
-
-        > span {
-          width: 100%;
-          word-break: keep-all;
-        }
-
-        &.active {
-          position: relative;
-
-          &::before {
-            content: "";
-            display: inline-block;
-            position: absolute;
-            bottom: 0;
-            width: 20px;
-            height: 2px;
-            z-index: 9999;
-            left: 50%;
-            transform: translateX(-50%);
-            background: @color;
-          }
-        }
-      }
-    }
-  }
-
-  #swScenes {
-    > ul {
-      > li {
-        cursor: pointer;
-        width: 72px;
-        height: 72px;
-        border-radius: 6px;
-        border: 1px solid #ffffff;
-        background-size: cover;
-        position: relative;
-        overflow: hidden;
-
-        .iconfont {
-          position: absolute;
-          left: 4px;
-          top: 4px;
-          z-index: 99;
-
-          &::after {
-            background: rgba(0, 0, 0, 0.3);
-            content: "";
-            width: 14px;
-            height: 14px;
-            display: inline-block;
-            position: absolute;
-            top: 50%;
-            left: 50%;
-            transform: translate(-50%, -50%);
-            z-index: -1;
-            filter: blur(4px);
-          }
-        }
-
-        > div {
-          position: absolute;
-          bottom: 0;
-          left: 0;
-          height: 20px;
-          background: rgba(0, 0, 0, 0.5);
-          width: 100%;
-          overflow: hidden;
-
-          > span {
-            width: 100%;
-            line-height: 20px;
-            word-break: keep-all;
-          }
-        }
-
-        &.active {
-          border: 1px solid @color;
-
-          > div {
-            > span {
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-.barshow {
-  max-height: 520px;
-}
-
-@keyframes wordsLoop {
-  0% {
-    transform: translateX(100%);
-    -webkit-transform: translateX(100%);
-  }
-
-  100% {
-    transform: translateX(-100%);
-    -webkit-transform: translateX(-100%);
-  }
-}
-</style>

+ 46 - 8
packages/qjkankan-editor/src/framework/play/pano/index.vue

@@ -87,6 +87,7 @@ export default {
   watch: {
     "$route.name": function (newVal) {
       __krfn.utils.toggleHotspot(this.$getKrpano(), newVal == "hotspot");
+      this.handleRouterCoverForCap(newVal == "screen");
     },
     currentScene(newVal) {
       if (newVal) {
@@ -130,12 +131,10 @@ export default {
         };
         window.vrViewFn = () => {
           try {
-            let tmp = newVal.initVisual;
-            this.$getKrpano().set("view.vlookat", tmp ? tmp.vlookat : "");
-            this.$getKrpano().set("view.hlookat", tmp ? tmp.hlookat : "");
-            this.$getKrpano().set("view.limitview", "lookat");
-            this.$getKrpano().set("view.vlookatmin", tmp ? String(tmp.vlookatmin) : "-90");
-            this.$getKrpano().set("view.vlookatmax", tmp ? String(tmp.vlookatmax) : "90");
+            let visual = newVal.initVisual;
+            const { sky, earth } = newVal.customMask;
+            this.handleVisual(visual);
+            this.handleSkyCover(sky);
           } catch (error) {
             console.error(error);
           }
@@ -149,7 +148,6 @@ export default {
           removepano("#pano");
           $waiting.show();
 
-          console.log("embedpano", settings);
           embedpano({
             // http://oss-xiaoan.oss-cn-shenzhen.aliyuncs.com/720yun_fd_manage/fd720_Va0LrkXW3/vtour/tour.xml
             // xml: "%HTMLPATH%/static/template/tour.xml",
@@ -213,12 +211,52 @@ export default {
       __krfn.utils.addhotspot(this.$getKrpano(), param, true);
       this.$store.commit("tags/setIsConfirmingPosi", param.name);
     },
+
+    handleVisual(visual) {
+      this.$getKrpano().set("view.vlookat", visual ? visual.vlookat : "");
+      this.$getKrpano().set("view.hlookat", visual ? visual.hlookat : "");
+      this.$getKrpano().set("view.limitview", "lookat");
+      this.$getKrpano().set(
+        "view.vlookatmin",
+        visual ? String(visual.vlookatmin) : "-90"
+      );
+      this.$getKrpano().set(
+        "view.vlookatmax",
+        visual ? String(visual.vlookatmax) : "90"
+      );
+    },
+    /**
+     * 1.6 处理遮罩层
+     * @param {*} sky
+     */
+    handleSkyCover(sky) {
+      if (sky) {
+        if (sky.isShow) {
+          this.$getKrpano().set("hotspot[peaklogo].visible", true);
+          sky.icon && this.$getKrpano().set("hotspot[peaklogo].url", sky.icon);
+          sky.scale &&
+            this.$getKrpano().set("hotspot[peaklogo].scale", sky.scale);
+        } else {
+          this.$getKrpano().set("hotspot[peaklogo].visible", false);
+        }
+      }
+    },
+    handleRouterCoverForCap(isRoute) {
+      if (isRoute) {
+        this.$getKrpano().set("hotspot[peaklogo].visible", false);
+        this.$getKrpano().set("hotspot[nadirlogo].visible", false);
+      } else {
+        const { sky, earth } = this.currentScene.customMask;
+        sky.isShow && this.$getKrpano().set("hotspot[peaklogo].visible", true);
+        earth.isShow &&
+          this.$getKrpano().set("hotspot[nadirlogo].visible", true);
+      }
+    },
   },
   mounted() {
     window.__krfn = __krfn;
 
     this.$bus.on("addhotspot", (data) => {
-      // debugger
       this.addhotspot(data);
     });
 

+ 9 - 2
packages/qjkankan-editor/src/views/cover/index.vue

@@ -1,11 +1,18 @@
 <template>
   <!-- 编辑器-初始 -->
-  <div class="cover-screen"></div>
+  <div class="cover-screen">
+    <div class="panel">
+      <setting />
+    </div>
+  </div>
 </template>
 <script>
+import setting from "./setting";
 export default {
   name: "cover-setting",
-  components: {},
+  components: {
+    setting,
+  },
 };
 </script>
 

+ 232 - 0
packages/qjkankan-editor/src/views/cover/setting.vue

@@ -0,0 +1,232 @@
+<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>
+
+    <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="up-col">
+      <span> 缩放比例 </span>
+
+      <slider
+        v-model="sky.scale"
+        show-stops
+        :marks="scaleMarks"
+        :step="0.1"
+        :min="0.5"
+        :max="2"
+      />
+    </div>
+    <div class="dialog" style="z-index: 2000" v-if="isShowSelectionWindow">
+      <MaterialSelector
+        :title="$i18n.t(`gather.select_material`)"
+        @cancel="isShowSelectionWindow = false"
+        @submit="handleSubmitFromMaterialSelector"
+        :selectableType="['image']"
+      />
+    </div>
+  </div>
+</template>
+<script>
+import { mapGetters } from "vuex";
+import Switcher from "@/components/shared/Switcher";
+import { Slider } from "element-ui";
+import SelectedImage from "@/components/selectedImageInEditor.vue";
+import MaterialSelector from "@/components/materialSelector.vue";
+export default {
+  name: "cover-setting-panel",
+  components: {
+    Switcher,
+    Slider,
+    SelectedImage,
+    MaterialSelector,
+  },
+  computed: {
+    ...mapGetters({
+      currentScene: "scene/currentScene",
+    }),
+  },
+  data() {
+    return {
+      isShowSelectionWindow: false,
+      isSelect: "",
+      scaleMarks: {
+        0.52: "0.5倍",
+        1: "1倍",
+        1.99: "2倍",
+      },
+      sky: {
+        isShow: false,
+        icon: "",
+        scale: 1,
+        fodderId: "",
+      },
+      earth: {
+        isShow: false,
+        icon: "",
+        scale: 1,
+        fodderId: "",
+      },
+    };
+  },
+  watch: {
+    sky: {
+      handler: function (val) {
+        if (this.currentScene.type === "pano" && val) {
+          this.currentScene.customMask.sky = val;
+          this.updateCurrentScene();
+        }
+      },
+      deep: true,
+    },
+    "sky.isShow": {
+      handler: function (val) {
+        this.handlePeakStatus(val);
+      },
+      immediate: true,
+    },
+    "sky.scale": {
+      handler: function (val) {
+        this.handlePeakScale(val);
+      },
+      immediate: true,
+    },
+    "sky.icon": {
+      handler: function (val) {
+        this.handlePeakURL(val);
+      },
+      immediate: true,
+    },
+  },
+  mounted() {
+    const { customMask } = this.currentScene;
+    if (customMask) {
+      this.sky = this.currentScene.customMask.sky;
+      this.earth = this.currentScene.customMask.earth;
+    }
+  },
+  methods: {
+    onClickCancelSkyLogo() {
+      this.handlePeakURL("/static/template/skin/masking.png");
+    },
+    onSelectPic(type) {
+      this.isSelect = type;
+      this.isShowSelectionWindow = true;
+    },
+    handleSubmitFromMaterialSelector(selected) {
+      this[this.isSelect].icon = selected[0].icon;
+      this[this.isSelect].fodderId = selected[0].id;
+      this.isShowSelectionWindow = false;
+    },
+    handlePeakStatus(status) {
+      const status_b = !!status;
+      const kr = this.$getKrpano();
+      if (kr) {
+        console.log("handlePeakStatus", status);
+        kr.set("hotspot[peaklogo].visible", status_b);
+      }
+    },
+    handlePeakURL(url) {
+      const kr = this.$getKrpano();
+      if (kr && url) {
+        kr.set("hotspot[peaklogo].url", url);
+      }
+    },
+    handlePeakScale(scale) {
+      const kr = this.$getKrpano();
+      if (kr) {
+        kr.set("hotspot[peaklogo].scale", scale);
+      }
+    },
+    updateCurrentScene() {
+      this.$store.dispatch("scene/syncCurrentSceneToStore");
+    },
+  },
+};
+</script>
+<style>
+.cover-panel .el-slider__marks-text {
+  white-space: nowrap;
+}
+</style>
+
+<style lang="less" scoped>
+.cover-panel {
+  padding: 20px;
+  height: 100%;
+  > .title {
+    font-size: 18px;
+    color: #fff;
+    margin-bottom: 16px;
+    > i {
+      font-size: 12px;
+      position: relative;
+      top: -2px;
+    }
+  }
+  .swi-col,
+  .up-col {
+    display: inline-flex;
+    width: 100%;
+    justify-content: space-between;
+    align-items: center;
+    flex-direction: row;
+    margin: 10px 0;
+  }
+  .up-col {
+    flex-direction: column;
+    justify-content: flex-start;
+    align-items: flex-start;
+    flex-wrap: nowrap;
+    > * {
+      flex: 1;
+      width: 100%;
+    }
+  }
+  .update-col {
+    justify-content: flex-start;
+    align-items: flex-start;
+  }
+  .action {
+    .ui-button {
+      margin-bottom: 10px;
+    }
+  }
+  .el-slider {
+    padding: 0 8px;
+    color: #fff;
+  }
+  .img-wrapper {
+    width: 120px;
+    height: 120px;
+  }
+}
+</style>

+ 13 - 1
packages/qjkankan-editor/src/views/screen/Setting.vue

@@ -22,7 +22,14 @@
       />
       <div class="item">
         <div class="">垂直视角限制</div>
-        <slider v-model="vlookat" range show-stops :min="-90" :max="90">
+        <slider
+          v-model="vlookat"
+          range
+          show-stops
+          :marks="marks"
+          :min="-90"
+          :max="90"
+        >
         </slider>
       </div>
 
@@ -66,6 +73,10 @@ export default {
   },
   data() {
     return {
+      marks: {
+        "-90": "-90°",
+        90: "90°",
+      },
       initImg: "",
       vlookat: null,
       applyToAll: false,
@@ -156,6 +167,7 @@ export default {
   .item {
     .el-slider {
       padding: 0 5px;
+      margin-bottom: 10px;
     }
   }
   .col {