chenlei 8 ماه پیش
والد
کامیت
4ed51d6804

+ 4 - 0
package.json

@@ -16,6 +16,10 @@
     "build:syjy:test": "cross-env VITE_APP_SCENE=syjy VITE_APP_TITLE=中国民族博物馆-三亚家园线上展厅 VITE_APP_HOT_DOMAIN=.\/hotspot.html run-p type-check \"build-only {@}\" --",
     "push:syjy": "cross-env VITE_APP_SCENE=syjy node ./scripts/publish.js",
 
+    "serve:ylct": "cross-env VITE_APP_SCENE=ylct VITE_APP_TITLE=家国天下-勇立潮头 VITE_APP_HOT_DOMAIN=.\/hotspot.html vite",
+    "build:ylct:test": "cross-env VITE_APP_SCENE=ylct VITE_APP_TITLE=家国天下-勇立潮头 VITE_APP_HOT_DOMAIN=.\/hotspot.html run-p type-check \"build-only {@}\" --",
+    "push:ylct": "cross-env VITE_APP_SCENE=ylct node ./scripts/publish.js",
+
     "preview": "vite preview",
     "build-only": "vite build",
     "type-check": "vue-tsc --build --force"

BIN
public/images/ylct/12-min.png


BIN
src/index/assets/images/ylct/1-min.png


BIN
src/index/assets/images/ylct/10-min.png


BIN
src/index/assets/images/ylct/11-min.png


BIN
src/index/assets/images/ylct/13-min.png


BIN
src/index/assets/images/ylct/14-min.png


BIN
src/index/assets/images/ylct/2-min.png


BIN
src/index/assets/images/ylct/3-min.png


BIN
src/index/assets/images/ylct/4-min.png


BIN
src/index/assets/images/ylct/5-min.png


BIN
src/index/assets/images/ylct/6-min.png


BIN
src/index/assets/images/ylct/7-min.png


BIN
src/index/assets/images/ylct/8-min.png


BIN
src/index/assets/images/ylct/9-min.png


BIN
src/index/assets/images/ylct/bg-min.png


BIN
src/index/assets/images/ylct/button-min.png


BIN
src/index/assets/images/ylct/close-min.png


BIN
src/index/assets/images/ylct/hot_bg-min.png


BIN
src/index/assets/images/ylct/hotlist_bg-min.png


+ 188 - 0
src/index/views/home/components/menu/index.ylct.scss

@@ -0,0 +1,188 @@
+.pinBottom-container {
+  position: absolute;
+  bottom: 25px;
+  width: 100%;
+  transition: all 0.5s;
+  z-index: var(--z-index-top);
+
+  .pinBottom.playing {
+    bottom: 20px;
+  }
+}
+
+.pinBottom.open.noScroll.playing {
+  bottom: 175px;
+}
+
+.pinBottom {
+  position: absolute;
+  bottom: 0;
+  line-height: 1;
+  transition: all 0.5s;
+
+  &.left {
+    left: 0;
+  }
+  &.right {
+    right: 30px;
+  }
+  &.open {
+    bottom: 135px;
+
+    &.playing {
+      bottom: 155px;
+    }
+  }
+}
+
+.viewContainer,
+.rightViewContainer,
+#gui-modes-map {
+  display: flex;
+  align-items: center;
+  gap: 15px;
+  height: 100%;
+}
+
+.viewContainer {
+  padding-left: 30px;
+}
+
+#play,
+#pause {
+  cursor: pointer;
+
+  img {
+    width: 50px;
+    height: 50px;
+  }
+}
+
+#pullTab,
+.good-btn,
+#hotList,
+.home-btn,
+#gui-modes-dollhouse,
+#gui-modes-floorplan,
+#volume,
+#sharing {
+  display: block;
+  width: 50px;
+  height: 50px;
+  cursor: pointer;
+}
+
+.home-btn {
+  background: url('@/assets/images/syjy/icon-home-min.png') no-repeat center / contain;
+}
+
+#pullTab {
+  background: url('@/assets/images/syjy/icon-daolan-min.png') no-repeat center / contain;
+
+  &.opened {
+    background-image: url('@/assets/images/syjy/icon-daolan-1-min.png');
+  }
+}
+
+#hotList {
+  background: url('@/assets/images/syjy/icon-redian-min.png') no-repeat center / contain;
+
+  &.active {
+    background-image: url('@/assets/images/syjy/icon-redian-1-min.png');
+  }
+}
+
+#gui-modes-dollhouse {
+  background: url('@/assets/images/syjy/icon-dingbu-min.png') no-repeat center / contain;
+
+  &.active {
+    background-image: url('@/assets/images/syjy/icon-dingbu-1-min.png');
+  }
+}
+
+#gui-modes-floorplan {
+  background: url('@/assets/images/syjy/icon-mini-min.png') no-repeat center / contain;
+
+  &.active {
+    background-image: url('@/assets/images/syjy/icon-mini-1-min.png');
+  }
+}
+
+#volume {
+  background: url('@/assets/images/syjy/icon-shengyin-min.png') no-repeat center / contain;
+
+  &.active {
+    background-image: url('@/assets/images/syjy/icon-shengyin-1-min.png');
+  }
+}
+
+#sharing {
+  background: url('@/assets/images/syjy/icon-share-min.png') no-repeat center / contain;
+}
+
+.terms2 {
+  display: none;
+}
+
+@media only screen and (max-width: 600px) {
+  .pinBottom {
+    &-container {
+      bottom: 37px;
+    }
+    &.open {
+      bottom: 80px;
+
+      &.noScroll.playing {
+        bottom: 100px;
+      }
+    }
+    &.open.right {
+      bottom: 152px;
+
+      &.noScroll.playing {
+        bottom: 172px;
+      }
+    }
+    &.left {
+      .viewContainer {
+        flex-direction: column;
+        padding-left: 10px;
+        gap: 7px;
+        width: 47px;
+      }
+    }
+    &.right {
+      position: fixed;
+      right: 8px;
+      top: 120px;
+      bottom: unset;
+
+      &.playing {
+        bottom: 50px;
+      }
+      .rightViewContainer {
+        flex-direction: column;
+        gap: 7px;
+
+        #sharing,
+        #volume,
+        .home-btn,
+        .good-btn {
+          width: 37px;
+          height: 37px;
+        }
+      }
+    }
+  }
+  #play img,
+  #pause img,
+  #gui-modes-map > div,
+  .hotList {
+    width: 37px;
+    height: 37px;
+  }
+  #gui-modes-map {
+    flex-direction: column;
+    gap: 7px;
+  }
+}

+ 146 - 0
src/index/views/home/components/menu/index.ylct.vue

@@ -0,0 +1,146 @@
+<template>
+  <div class="pinBottom-container">
+    <div class="pinBottom left">
+      <div class="viewContainer">
+        <div id="previous" class="previous desktop-only ui-icon" style="display: none">
+          <a>
+            <img :src="PauseIcon" width="24" height="24" data-original-title="播放" />
+          </a>
+        </div>
+        <div id="play" class="ui-icon" data-original-title="播放">
+          <a>
+            <img :src="PauseIcon" width="24" height="24" title="播放" />
+          </a>
+        </div>
+        <div id="pause" class="ui-icon" style="display: none">
+          <a>
+            <img title="暂停" :src="PlayIcon" width="24" height="24" />
+          </a>
+        </div>
+        <div id="next" class="next desktop-only ui-icon wide" style="display: none">
+          <a>
+            <i title="" class="icon icon-dpad-right" data-original-title="下一个"></i>
+          </a>
+        </div>
+        <div id="gui-modes-map" class="ui-icon double active">
+          <div data-original-title="导览" id="pullTab" title="导览" />
+
+          <div id="hotList" title="热点列表" data-original-title="热点列表" style="display: none" />
+          <div
+            data-original-title="迷你模型"
+            id="gui-modes-dollhouse"
+            title="迷你模型"
+            class=""
+          ></div>
+          <div data-original-title="俯视图" id="gui-modes-floorplan" title="俯视图"></div>
+          <div data-original-title="VR" id="vr" title="" style="display: none"></div>
+          <div
+            data-original-title="消除外壳"
+            id="gui-remove-face"
+            title=""
+            style="display: none; float: left"
+          >
+            <img class="icon icon-inside" src="/images/face.jpg" />
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="pinBottom right hideTarget">
+      <div class="rightViewContainer clearfix">
+        <div class="ui-icon wide home-btn" title="首页" @click="goToHome"></div>
+        <div id="sharing" class="ui-icon wide" title="分享" @click="shareVisible = true"></div>
+        <div id="volume" class="ui-icon wide" style="display: none"></div>
+        <div id="vr" class="ui-icon wide hidden" style="display: none">
+          <a>
+            <i title="{[{ VIEW_IN_VR }]}" class="icon icon-webvr"></i>
+          </a>
+        </div>
+        <div
+          id="gui-fullscreen"
+          class="ui-icon wide"
+          data-placement="top"
+          title="{[{ VIEW_FULLSCREEN }]}"
+          style="display: none"
+        >
+          <a>
+            <i class="icon icon-fullscreen"></i>
+          </a>
+        </div>
+        <div
+          id="gui-fullscreen-exit"
+          class="ui-icon wide"
+          data-placement="top"
+          title="{[{ EXIT_FULLSCREEN }]}"
+          style="display: none"
+        >
+          <a>
+            <i class="icon icon-fullscreen-exit"></i>
+          </a>
+        </div>
+        <div class="pull-right terms terms2"></div>
+      </div>
+    </div>
+  </div>
+
+  <share-popup v-model:visible="shareVisible" />
+</template>
+
+<script setup lang="ts">
+  import { onMounted, onUnmounted, ref } from 'vue';
+  import PauseIcon from '@/assets/images/syjy/icon-manyou-1-min.png';
+  import PlayIcon from '@/assets/images/syjy/icon-manyou-min.png';
+  import { homeApi } from '@/api';
+  import SharePopup from '../share-popup/index.vue';
+
+  let helperVisible = false;
+  const starSum = ref(0);
+  const shareVisible = ref(false);
+
+  const closeHelper = () => {
+    window.$('#interaction-modal').removeClass('fadeIn');
+    helperVisible = false;
+  };
+
+  const handleKeydown = () => {
+    helperVisible && closeHelper();
+  };
+  const handleClick = (e: MouseEvent | TouchEvent) => {
+    const clickedElement = e.target;
+    // @ts-ignore
+    const modalElement = clickedElement?.closest('#interaction-modal');
+    // @ts-ignore
+    const btnElement = clickedElement?.closest('.helper-btn');
+    if (!modalElement && !btnElement && helperVisible) {
+      closeHelper();
+    }
+  };
+
+  const getDetail = async () => {
+    const { data } = await homeApi.getSceneDetail(window.number);
+
+    if (!data) return;
+    starSum.value = data.starSum;
+  };
+
+  const goToHome = () => {
+    location.href = 'https://houseoss.4dkankan.com/project/syjy/mobile/index.html';
+  };
+
+  onMounted(() => {
+    getDetail();
+
+    window.addEventListener('keydown', handleKeydown);
+    window.addEventListener('click', handleClick);
+    window.addEventListener('touchmove', handleClick);
+  });
+
+  onUnmounted(() => {
+    window.removeEventListener('keydown', handleKeydown);
+    window.removeEventListener('click', handleClick);
+    window.removeEventListener('touchmove', handleClick);
+  });
+</script>
+
+<style lang="scss" scoped>
+  @use './index.syjy.scss';
+</style>

+ 114 - 0
src/index/views/home/index.ylct.scss

@@ -0,0 +1,114 @@
+.home {
+  width: 100%;
+  height: 100%;
+
+  &-cover {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: url('@/assets/images/ylct/bg-min.png') no-repeat center / cover;
+    z-index: 9999;
+
+    img {
+      position: absolute;
+      left: 50%;
+      bottom: 70px;
+      cursor: pointer;
+      transform: translateX(-50%);
+    }
+  }
+}
+
+#player {
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  width: 100%;
+  height: 100%;
+
+  canvas {
+    position: relative;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+  }
+}
+
+#hot {
+  position: absolute;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+  pointer-events: none;
+
+  > div[pos='right'] {
+    transform: translate(20px, -50%);
+  }
+  > div[pos='top'] {
+    transform: translate(-50%, calc(-100% - 20px));
+  }
+  > div[pos='middle'] {
+    transform: translate(-50%, -50%);
+  }
+  > div[pos='bottom'] {
+    transform: translate(-50%, 20px);
+  }
+  > div[pos='left'] {
+    transform: translate(calc(-100% - 20px), -50%);
+  }
+  > div {
+    position: absolute;
+    color: #fff;
+    user-select: none;
+    border-radius: 5px;
+    background-color: rgba(34, 34, 34, 0.3);
+    padding: 10px;
+    max-width: 400px;
+    letter-spacing: 1px;
+    line-height: 20px;
+    z-index: var(--z-index-top);
+  }
+}
+
+div.cad {
+  top: 44px;
+  right: 30px;
+  width: 150px;
+  height: 150px;
+  border: 1px solid #c39c6b;
+  background: rgba(111, 15, 13, 0.6);
+
+  path {
+    stroke-width: 1;
+    stroke: #c39c6b;
+    fill: RGBA(157, 34, 45, 0.7);
+  }
+  circle {
+    fill: #9d222d;
+  }
+}
+
+.pinTop {
+  display: none;
+}
+
+@media only screen and (max-width: 600px) {
+  .home {
+    &__back {
+      top: 12px;
+      left: 12px;
+      width: 35px;
+      height: 35px;
+      z-index: 1001;
+    }
+  }
+  div.cad {
+    top: 20px;
+    right: 8px;
+    width: 90px;
+    height: 90px;
+  }
+}

+ 124 - 0
src/index/views/home/index.ylct.tsx

@@ -0,0 +1,124 @@
+import { defineComponent, ref } from 'vue';
+import JsScript from '@/components/js-script';
+import Title from './components/title';
+import WebVr from './components/web-vr';
+import Other from './components/other';
+import Guide from './components/guide';
+import Vrcon from './components/vrcon';
+import Menu from './components/menu';
+import GuiLoading from './components/gui-loading';
+import Popup from './components/popup';
+import HotSpotList from './components/hot-spot-list';
+import BtnIcon from '@/assets/images/ylct/button-min.png';
+import useBaseStore from '@/store/module/base';
+import './index.ylct.scss';
+
+// @ts-ignore
+window.hoticon = {
+  default: './images/ylct/12-min.png',
+  higt: './images/ylct/12-min.png',
+};
+
+export default defineComponent({
+  name: 'home',
+  components: {
+    Title,
+    WebVr,
+    Other,
+    Vrcon,
+    GuiLoading,
+    JsScript,
+    Popup,
+  },
+  setup() {
+    const baseStore = useBaseStore();
+    const manageJsLoaded = ref(false);
+    const hotJsLoaded = ref(false);
+    const showCover = ref(true);
+
+    return {
+      manageJsLoaded,
+      hotJsLoaded,
+      baseStore,
+      showCover,
+    };
+  },
+  render() {
+    return (
+      <div class="home">
+        {this.showCover && (
+          <div class="home-cover">
+            <img src={BtnIcon} onClick={() => (this.showCover = false)} />
+          </div>
+        )}
+
+        {/* 进度条加载 */}
+        <GuiLoading />
+
+        {/* 加载初始页面 */}
+        <div id="gui-thumb" />
+
+        {/* 热点弹出框 */}
+        <Popup />
+
+        {/* 热点列表 */}
+        <HotSpotList />
+
+        {/* 场景canvs主容器 */}
+        <div id="player" />
+
+        {/* 底部菜单 */}
+        <div id="gui-parent">
+          {/* 热点气泡 */}
+          <div id="hot" />
+
+          <div id="gui" style="display: none;">
+            {/* 标题 */}
+            {/* @ts-ignore */}
+            <Title isInit={this.manageJsLoaded} />
+
+            {/* 底部菜单 */}
+            <Menu />
+
+            {/* 导览 */}
+            <Guide />
+          </div>
+
+          <WebVr />
+          <Vrcon />
+          <Other />
+        </div>
+
+        {/* TODO: 没有控制权,耦合严重;放在此处为了防止元素未渲染导致报错 */}
+        <JsScript
+          src="./js/manage.js"
+          onLoad={() => {
+            this.manageJsLoaded = true;
+            this.baseStore.handleJSLoaded('manageJsLoaded');
+          }}
+        />
+        {this.manageJsLoaded && (
+          <div>
+            <JsScript
+              src="./js/Hot.js"
+              onLoad={() => {
+                this.hotJsLoaded = true;
+                this.baseStore.handleJSLoaded('hotJsLoaded');
+              }}
+            />
+            {this.hotJsLoaded && (
+              <div>
+                <JsScript src="./js/main_2020_show.js" />
+                {/* 延迟加载 */}
+                <JsScript src="./js/lib/player-0.0.12.min.js" />
+                <JsScript src="./js/lib/Tween.js" />
+                <JsScript src="./js/SpecialScene.js" />
+                <JsScript src="./js/loadCAD.js" />
+              </div>
+            )}
+          </div>
+        )}
+      </div>
+    );
+  },
+});