chenlei 1 年之前
父節點
當前提交
dc493920bf
共有 65 個文件被更改,包括 135206 次插入134646 次删除
  1. 24 24
      .gitignore
  2. 3 0
      package.json
  3. 二進制
      public/favicon/favicon-lfjng.ico
  4. 二進制
      public/images/Volume btn_off.png
  5. 二進制
      public/images/Volume btn_on.png
  6. 二進制
      public/images/auto-suspend.png
  7. 二進制
      public/images/auto.png
  8. 二進制
      public/images/close1.png
  9. 二進制
      public/images/dollhouse.png
  10. 二進制
      public/images/floor.png
  11. 二進制
      public/images/hotlist.png
  12. 二進制
      public/images/hotspot-bg-mobile-min.jpg
  13. 二進制
      public/images/hotspot-bg.png
  14. 二進制
      public/images/icon-back-1@2x-min.png
  15. 二進制
      public/images/icon-back@2x-min.png
  16. 二進制
      public/images/icon-close@2x-min.png
  17. 二進制
      public/images/icon-fangda@2x-min.png
  18. 二進制
      public/images/icon-fushi-1@2x-min.png
  19. 二進制
      public/images/icon-home-1@2x-min.png
  20. 二進制
      public/images/icon-home@2x-min.png
  21. 二進制
      public/images/icon-list-1@2x-min.png
  22. 二進制
      public/images/icon-mini-1@2x-min.png
  23. 二進制
      public/images/icon-quanjing-1@2x-min.png
  24. 二進制
      public/images/icon-shang@2x.png
  25. 二進制
      public/images/icon-suoxiao@2x-min.png
  26. 二進制
      public/images/inside.png
  27. 二進制
      public/images/line@2x.png
  28. 二進制
      public/images/pause.png
  29. 二進制
      public/images/play.png
  30. 1844 1844
      public/js/Hot.js
  31. 55723 55723
      public/js/main_2020_edit.js
  32. 66080 66080
      public/js/main_2020_show.js
  33. 二進制
      src/assets/images/icon-image-1@2x.png
  34. 二進制
      src/assets/images/icon-image@2x.png
  35. 二進制
      src/assets/images/icon-left-min.png
  36. 二進制
      src/assets/images/icon-model-1@2x.png
  37. 二進制
      src/assets/images/icon-model@2x.png
  38. 二進制
      src/assets/images/icon-next@2x-min.png
  39. 二進制
      src/assets/images/icon-previous@2x-min.png
  40. 二進制
      src/assets/images/icon-right-min.png
  41. 二進制
      src/assets/images/icon-video-1@2x.png
  42. 二進制
      src/assets/images/icon-video@2x.png
  43. 20 17
      src/configure.ts
  44. 5 0
      src/router/index.ts
  45. 二進制
      src/views/cover/enter-icon-min.png
  46. 37 0
      src/views/cover/index.scss
  47. 16 0
      src/views/cover/index.tsx
  48. 二進制
      src/views/cover/mobile-min.png
  49. 二進制
      src/views/cover/pc-min.png
  50. 123 123
      src/views/home/components/gui-loading/index.scss
  51. 263 242
      src/views/home/components/guide/index.scss
  52. 1 1
      src/views/home/components/guide/index.tsx
  53. 174 171
      src/views/home/components/hot-spot-list/index.scss
  54. 10 9
      src/views/home/components/hot-spot-list/index.tsx
  55. 85 82
      src/views/home/components/menu/index.scss
  56. 19 13
      src/views/home/components/menu/index.tsx
  57. 43 35
      src/views/home/components/popup/index.scss
  58. 210 190
      src/views/home/components/title/index.scss
  59. 6 3
      src/views/home/components/title/index.tsx
  60. 2 32
      src/views/home/index.scss
  61. 14 13
      src/views/home/index.tsx
  62. 238 0
      src/views/hotspot/index.scss
  63. 216 0
      src/views/hotspot/index.vue
  64. 3 2
      vue.config.js
  65. 10047 10042
      yarn.lock

+ 24 - 24
.gitignore

@@ -1,24 +1,24 @@
-.DS_Store
-.temp
-node_modules
-/build
-
-
-# local env files
-.env.local
-.env.*.local
-
-# Log files
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-
-# Editor directories and files
-.idea
-.vscode
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
+.DS_Store
+.temp
+node_modules
+/build
+/dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 3 - 0
package.json

@@ -6,6 +6,8 @@
     "serve": "cross-env TITLE=大理洱海科普馆 vue-cli-service serve",
     "build:test": "cross-env TITLE=大理洱海科普馆 vue-cli-service build",
     "push:test": "cross-env node ./scripts/publish.js",
+    "serve:lfjng": "cross-env SCENE=lfjng HOT_DOMAIN=http://localhost/#/hotspot TITLE=雷锋纪念馆-新时代廉洁文化专题展 vue-cli-service serve",
+    "build:lfjng:test": "cross-env SCENE=lfjng HOT_DOMAIN=https://houseoss.4dkankan.com/project/leifeng-jng/lfjng.html#/hotspot TITLE=雷锋纪念馆-新时代廉洁文化专题展 vue-cli-service build",
     "lint": "vue-cli-service lint",
     "prepare": "husky install"
   },
@@ -16,6 +18,7 @@
     "lodash": "^4.17.21",
     "pinia": "^2.0.24",
     "query-string": "^8.1.0",
+    "swiper": "^11.1.4",
     "vue": "^3.2.13",
     "vue-class-component": "^8.0.0-0",
     "vue-router": "^4.0.3"

二進制
public/favicon/favicon-lfjng.ico


二進制
public/images/Volume btn_off.png


二進制
public/images/Volume btn_on.png


二進制
public/images/auto-suspend.png


二進制
public/images/auto.png


二進制
public/images/close1.png


二進制
public/images/dollhouse.png


二進制
public/images/floor.png


二進制
public/images/hotlist.png


二進制
public/images/hotspot-bg-mobile-min.jpg


二進制
public/images/hotspot-bg.png


二進制
public/images/icon-back-1@2x-min.png


二進制
public/images/icon-back@2x-min.png


二進制
public/images/icon-close@2x-min.png


二進制
public/images/icon-fangda@2x-min.png


二進制
public/images/icon-fushi-1@2x-min.png


二進制
public/images/icon-home-1@2x-min.png


二進制
public/images/icon-home@2x-min.png


二進制
public/images/icon-list-1@2x-min.png


二進制
public/images/icon-mini-1@2x-min.png


二進制
public/images/icon-quanjing-1@2x-min.png


二進制
public/images/icon-shang@2x.png


二進制
public/images/icon-suoxiao@2x-min.png


二進制
public/images/inside.png


二進制
public/images/line@2x.png


二進制
public/images/pause.png


二進制
public/images/play.png


文件差異過大導致無法顯示
+ 1844 - 1844
public/js/Hot.js


文件差異過大導致無法顯示
+ 55723 - 55723
public/js/main_2020_edit.js


文件差異過大導致無法顯示
+ 66080 - 66080
public/js/main_2020_show.js


二進制
src/assets/images/icon-image-1@2x.png


二進制
src/assets/images/icon-image@2x.png


二進制
src/assets/images/icon-left-min.png


二進制
src/assets/images/icon-model-1@2x.png


二進制
src/assets/images/icon-model@2x.png


二進制
src/assets/images/icon-next@2x-min.png


二進制
src/assets/images/icon-previous@2x-min.png


二進制
src/assets/images/icon-right-min.png


二進制
src/assets/images/icon-video-1@2x.png


二進制
src/assets/images/icon-video@2x.png


+ 20 - 17
src/configure.ts

@@ -1,17 +1,20 @@
-import queryString from 'query-string';
-
-const urlParams = queryString.parse(location.search.slice(1));
-
-window.number = urlParams.m as string;
-
-if (performance) {
-  window.navigationStart = performance.timing.navigationStart;
-} else {
-  window.navigationStart = Date.now() + 300;
-}
-
-window.getHotIframePath = (src: string) => {
-  return process.env.NODE_ENV === 'development' && process.env.HOT_DOMAIN
-    ? src.replace('https://www.4dmodel.com/SuperTwo/hot_online1', process.env.HOT_DOMAIN)
-    : src;
-};
+import queryString from 'query-string';
+
+const urlParams = queryString.parse(location.search.slice(1));
+
+window.number = urlParams.m as string;
+
+if (performance) {
+  window.navigationStart = performance.timing.navigationStart;
+} else {
+  window.navigationStart = Date.now() + 300;
+}
+
+window.getHotIframePath = (src: string) => {
+  return process.env.HOT_DOMAIN
+    ? src.replace(
+        'https://www.4dmodel.com/SuperTwo/hot_online1/index.html#/',
+        process.env.HOT_DOMAIN
+      )
+    : src;
+};

+ 5 - 0
src/router/index.ts

@@ -6,6 +6,11 @@ const routes: Array<RouteRecordRaw> = [
     name: 'home',
     component: () => import('@/views/home'),
   },
+  {
+    path: '/hotspot',
+    name: 'hotspot',
+    component: () => import('@/views/hotspot/index.vue'),
+  },
 ];
 
 const router = createRouter({

二進制
src/views/cover/enter-icon-min.png


+ 37 - 0
src/views/cover/index.scss

@@ -0,0 +1,37 @@
+.cover {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: var(--z-index-popper);
+  background: url('./pc-min.png') no-repeat center / cover;
+
+  &__btn {
+    position: absolute;
+    left: 50%;
+    bottom: 122px;
+    width: 280px;
+    height: 78px;
+    line-height: 78px;
+    text-align: center;
+    font-weight: bold;
+    color: white;
+    font-size: 24px;
+    background: url('./enter-icon-min.png') no-repeat center / contain;
+    transform: translateX(-50%);
+    cursor: pointer;
+  }
+}
+
+@media only screen and (max-width: 600px) {
+  .cover {
+    &__btn {
+      bottom: 130px;
+      width: 173px;
+      height: 50px;
+      font-size: 16px;
+      line-height: 50px;
+    }
+  }
+}

+ 16 - 0
src/views/cover/index.tsx

@@ -0,0 +1,16 @@
+import { defineComponent } from 'vue';
+import './index.scss';
+
+export default defineComponent({
+  name: 'cover',
+  emits: ['close'],
+  render() {
+    return (
+      <div class="cover">
+        <div class="cover__btn" onClick={() => this.$emit('close')}>
+          探索场景
+        </div>
+      </div>
+    );
+  },
+});

二進制
src/views/cover/mobile-min.png


二進制
src/views/cover/pc-min.png


+ 123 - 123
src/views/home/components/gui-loading/index.scss

@@ -1,123 +1,123 @@
-#gui-loading {
-  z-index: var(--z-index-top);
-}
-
-.message-inner {
-  display: table-cell;
-  height: 100%;
-  text-align: center;
-  vertical-align: middle;
-}
-
-#loaderCoBrand,
-.model-title {
-  position: absolute;
-  width: 100%;
-  text-align: center;
-  font-weight: 100;
-}
-
-.model-title {
-  top: 19%;
-  display: block;
-  padding: 0 4px;
-  font-size: 38px;
-  letter-spacing: 0.75px;
-  color: rgba(255, 255, 255, 1);
-  margin: 0;
-  hyphens: auto;
-  line-height: 45px;
-}
-
-.progressbar {
-  position: relative;
-  display: block;
-  margin: 40px auto;
-  padding: 0px 20px;
-  width: 24%;
-  height: 10px;
-  background: #fff;
-  border-radius: 5px;
-
-  .label {
-    font-family: 'Aldrich', sans-serif;
-    position: absolute;
-    margin-left: -20px;
-    display: block;
-    width: 40px;
-    height: 22px;
-    line-height: 20px;
-    left: 0px;
-    font-size: 16px;
-    text-align: center;
-    -webkit-border-radius: 6px;
-    border-radius: 6px;
-    border: 1px solid rgba(0, 0, 0, 0.2);
-    box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.3);
-    top: -30px;
-    color: #fff;
-  }
-  .bar {
-    position: absolute;
-    display: block;
-    width: 0px;
-    height: 10px;
-    top: 0px;
-    left: 0px;
-    background: #00b4ed;
-    border-radius: 5px;
-    overflow: hidden;
-
-    span {
-      position: absolute;
-      display: block;
-      width: 100%;
-      height: 64px;
-      border-radius: 16px;
-      background: #00b4ed;
-      opacity: 0.2;
-    }
-  }
-}
-
-.specialPower {
-  display: none;
-}
-
-@media only screen and (max-width: 1000px) {
-  .progressbar {
-    width: 60%;
-  }
-}
-
-@media only screen and (max-width: 700px) {
-  .progressbar {
-    width: 65%;
-  }
-}
-
-@media only screen and (max-width: 555px) {
-  .model-title {
-    font-size: 22px;
-    line-height: 26px;
-  }
-}
-
-@media only screen and (max-height: 600px) {
-  .model-title {
-    top: 10%;
-    bottom: auto;
-  }
-}
-
-@media only screen and (max-height: 370px) {
-  .model-title {
-    top: 10px;
-    bottom: auto;
-    font-size: 14px;
-    line-height: 20px;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-  }
-}
+#gui-loading {
+  z-index: var(--z-index-top);
+}
+
+.message-inner {
+  display: table-cell;
+  height: 100%;
+  text-align: center;
+  vertical-align: middle;
+}
+
+#loaderCoBrand,
+.model-title {
+  position: absolute;
+  width: 100%;
+  text-align: center;
+  font-weight: 100;
+}
+
+.model-title {
+  top: 19%;
+  display: block;
+  padding: 0 4px;
+  font-size: 38px;
+  letter-spacing: 0.75px;
+  color: rgba(255, 255, 255, 1);
+  margin: 0;
+  hyphens: auto;
+  line-height: 45px;
+}
+
+.progressbar {
+  position: relative;
+  display: block;
+  margin: 40px auto;
+  padding: 0px 20px;
+  width: 24%;
+  height: 10px;
+  background: #fff;
+  border-radius: 5px;
+
+  .label {
+    font-family: 'Aldrich', sans-serif;
+    position: absolute;
+    margin-left: -20px;
+    display: block;
+    width: 40px;
+    height: 22px;
+    line-height: 20px;
+    left: 0px;
+    font-size: 16px;
+    text-align: center;
+    -webkit-border-radius: 6px;
+    border-radius: 6px;
+    border: 1px solid rgba(0, 0, 0, 0.2);
+    box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.3);
+    top: -30px;
+    color: #fff;
+  }
+  .bar {
+    position: absolute;
+    display: block;
+    width: 0px;
+    height: 10px;
+    top: 0px;
+    left: 0px;
+    background: #ddaf35;
+    border-radius: 5px;
+    overflow: hidden;
+
+    span {
+      position: absolute;
+      display: block;
+      width: 100%;
+      height: 64px;
+      border-radius: 16px;
+      background: #ddaf35;
+      opacity: 0.2;
+    }
+  }
+}
+
+.specialPower {
+  display: none;
+}
+
+@media only screen and (max-width: 1000px) {
+  .progressbar {
+    width: 60%;
+  }
+}
+
+@media only screen and (max-width: 700px) {
+  .progressbar {
+    width: 65%;
+  }
+}
+
+@media only screen and (max-width: 555px) {
+  .model-title {
+    font-size: 22px;
+    line-height: 26px;
+  }
+}
+
+@media only screen and (max-height: 600px) {
+  .model-title {
+    top: 10%;
+    bottom: auto;
+  }
+}
+
+@media only screen and (max-height: 370px) {
+  .model-title {
+    top: 10px;
+    bottom: auto;
+    font-size: 14px;
+    line-height: 20px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+}

+ 263 - 242
src/views/home/components/guide/index.scss

@@ -1,242 +1,263 @@
-#drawer-container {
-  position: absolute;
-  left: 0;
-  bottom: 0px;
-  width: 100%;
-  height: 200px;
-  overflow: hidden;
-  pointer-events: none;
-  transition-property: bottom, opacity;
-  transition-duration: 0.5s;
-  z-index: var(--z-index-normal);
-
-  #drawer.playing {
-    bottom: 20px;
-  }
-}
-
-#drawer {
-  position: absolute;
-  left: 0;
-  bottom: 0;
-  width: 100%;
-  height: 0;
-  color: #fff;
-  pointer-events: all;
-  transition-duration: 0.5s;
-  transition-property: height, bottom;
-
-  &.open {
-    height: 130px;
-
-    &.noScroll {
-      height: 107px;
-    }
-  }
-}
-
-#drawer-container.drawerOpen #drawer.open {
-  height: 136px;
-}
-
-#drawer.open.fadeOut {
-  pointer-events: none;
-}
-
-#drawer-container.drawerOpen #drawer.open.noScroll,
-#drawer.open.noScroll.playing {
-  height: 113px;
-}
-
-#thumb-container {
-  .thumbImg {
-    cursor: pointer;
-
-    img {
-      height: 97px;
-    }
-  }
-}
-
-.fullWidth .frame-container {
-  width: 100%;
-}
-.frame-container {
-  float: left;
-  width: calc(100% - 58px);
-  height: 100%;
-}
-
-.frame {
-  width: calc(100% - 20px);
-  height: 97px;
-  margin: 9px 10px;
-  float: left;
-}
-
-.frame.noScroll {
-  margin: 17px 10px;
-}
-
-.frame .slidee {
-  display: flex;
-  height: 100%;
-  list-style: none;
-}
-
-.frame .slidee li {
-  width: 136px;
-  margin: 0 12px 0 0;
-  position: relative;
-}
-
-.frame .slidee li .overlay {
-  position: absolute;
-  left: 2px;
-  right: 2px;
-  bottom: 2px;
-  height: 20px;
-  padding: 6px;
-  color: #fff;
-  background-color: rgba(0, 0, 0, 0.7);
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  font-weight: 100;
-  text-align: center;
-  line-height: 4px;
-  z-index: 100;
-}
-
-.frame .slidee li .mark360View,
-.frame .slidee li .markInsideView {
-  position: absolute;
-  top: 2px;
-  left: 2px;
-  width: 50px;
-  max-height: 25px;
-  color: #fff;
-  background-color: rgba(0, 0, 0, 1);
-  z-index: 100;
-  transform: translate3d(0, 0, 0);
-}
-
-.frame .slidee li img {
-  width: inherit;
-  border: 2px solid transparent;
-  transition: all 0.5s;
-}
-
-.frame .slidee li.thumbImg.hasHover > img:hover {
-  opacity: 1;
-  border-color: #fff;
-}
-
-.playing .frame .slidee li.thumbImg.hasHover > img:hover {
-  opacity: 0.6;
-  border-color: transparent;
-}
-
-.frame .slidee li.thumbImg.hasHover.recent > img:hover,
-.frame .slidee li.thumbImg.recent > img {
-  opacity: 0.6;
-  border-color: #a0a0a0;
-}
-
-.frame .slidee li.thumbImg.hasHover.upcoming > img:hover,
-.frame .slidee li.thumbImg.upcoming > img {
-  opacity: 1;
-  border-color: #bfaf1e;
-}
-
-.frame .slidee li.thumbImg.active > img,
-.frame .slidee li.thumbImg.hasHover.active > img:hover {
-  opacity: 1;
-  border-color: #00b4ed;
-}
-
-.scrollbar {
-  width: calc(100% - 10px);
-  margin: 0 5px;
-  height: 8px;
-  float: left;
-  border-radius: 5px;
-  background: rgba(0, 0, 0, 0.75);
-}
-
-.scrollbar .handle {
-  width: 100px;
-  height: 100%;
-  background: rgba(255, 255, 255, 0.75);
-  border-radius: 5px;
-}
-
-#progressBar,
-#status {
-  display: table-cell;
-  height: 0;
-  vertical-align: middle;
-}
-
-#playHead {
-  display: table;
-  position: absolute;
-  bottom: -20px;
-  left: 0;
-  height: 20px;
-  width: 100%;
-  transition-property: bottom;
-  transition-duration: 0.5s;
-  background-color: #000;
-
-  &.playing {
-    bottom: 0;
-  }
-}
-
-#status {
-  width: 65px;
-  color: #fff;
-  font-family: OpenSans, 'Helvetica Neue', Arial, sans-serif;
-  font-weight: 700;
-  font-size: 11px;
-  padding-left: 10px;
-}
-
-#progressBar {
-  padding: 0 10px;
-  pointer-events: all;
-
-  .step {
-    height: 6px;
-    float: left;
-
-    &::before {
-      content: '';
-      display: block;
-      width: 100%;
-      height: 100%;
-      background-color: #575757;
-    }
-    &.active::before {
-      background-color: #00b4ed;
-    }
-  }
-}
-
-@media only screen and (max-width: 487px), (max-height: 487px) {
-  #thumb-container .thumbImg img,
-  .frame {
-    height: 77px;
-  }
-  .frame .slidee li {
-    width: 103px;
-  }
-  #drawer-container.drawerOpen #drawer.open.noScroll {
-    height: 94px;
-  }
-  #drawer.open.noScroll,
-  #drawer.open.noScroll.playing {
-    height: 88px;
-  }
-}
+#drawer-container {
+  position: absolute;
+  left: 0;
+  bottom: 0px;
+  width: 100%;
+  height: 200px;
+  overflow: hidden;
+  pointer-events: none;
+  transition-property: bottom, opacity;
+  transition-duration: 0.5s;
+  z-index: var(--z-index-normal);
+
+  #drawer.playing {
+    bottom: 20px;
+  }
+}
+
+#drawer {
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  width: 100%;
+  height: 0;
+  color: #fff;
+  pointer-events: all;
+  transition-duration: 0.5s;
+  transition-property: height, bottom;
+
+  &.open {
+    height: 130px;
+
+    &.noScroll {
+      height: 170px;
+    }
+  }
+}
+
+#drawer-container.drawerOpen #drawer.open {
+  height: 210px;
+}
+
+#drawer.open.fadeOut {
+  pointer-events: none;
+}
+
+#drawer-container.drawerOpen #drawer.open.noScroll,
+#drawer.open.noScroll.playing {
+  height: 185px;
+}
+
+#thumb-container {
+  .thumbImg {
+    cursor: pointer;
+
+    img {
+      height: 110px;
+    }
+  }
+}
+
+.fullWidth .frame-container {
+  width: 100%;
+}
+.frame-container {
+  float: left;
+  width: calc(100% - 58px);
+  height: 100%;
+  border-top-left-radius: 30px;
+  border-top-right-radius: 30px;
+  background: linear-gradient(#d67729, #c41800);
+}
+
+.frame {
+  padding: 13px 32px;
+  height: 170px;
+  box-sizing: border-box;
+}
+
+.frame.noScroll {
+  margin: 17px 10px;
+}
+
+.frame .slidee {
+  display: flex;
+  height: 100%;
+  list-style: none;
+}
+
+.frame .slidee li {
+  width: 174px;
+  margin: 0 31px 0 0;
+  position: relative;
+
+  &.active div {
+    color: #ddaf35;
+  }
+}
+
+.frame .slidee li .overlay {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 6px;
+  height: 20px;
+  padding: 6px;
+  color: #fff;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  font-weight: 100;
+  text-align: center;
+  line-height: 4px;
+  z-index: 100;
+}
+
+.frame .slidee li .mark360View,
+.frame .slidee li .markInsideView {
+  position: absolute;
+  top: 2px;
+  left: 2px;
+  width: 50px;
+  max-height: 25px;
+  color: #fff;
+  background-color: rgba(0, 0, 0, 1);
+  z-index: 100;
+  transform: translate3d(0, 0, 0);
+}
+
+.frame .slidee li img {
+  width: inherit;
+  overflow: hidden;
+  border-radius: 6px;
+  object-fit: cover;
+  border: 2px solid transparent;
+  transition: all 0.5s;
+}
+
+.frame .slidee li.thumbImg.hasHover > img:hover {
+  opacity: 1;
+  border-color: #fff;
+}
+
+.playing .frame .slidee li.thumbImg.hasHover > img:hover {
+  opacity: 0.6;
+  border-color: transparent;
+}
+
+.frame .slidee li.thumbImg.hasHover.recent > img:hover,
+.frame .slidee li.thumbImg.recent > img {
+  opacity: 0.6;
+  border-color: #a0a0a0;
+}
+
+.frame .slidee li.thumbImg.hasHover.upcoming > img:hover,
+.frame .slidee li.thumbImg.upcoming > img {
+  opacity: 1;
+  border-color: #bfaf1e;
+}
+
+.frame .slidee li.thumbImg.active > img,
+.frame .slidee li.thumbImg.hasHover.active > img:hover {
+  opacity: 1;
+  border-color: #ddaf35;
+}
+
+.scrollbar {
+  width: calc(100% - 10px);
+  margin: 0 5px;
+  height: 8px;
+  float: left;
+  border-radius: 5px;
+  background: rgba(0, 0, 0, 0.75);
+}
+
+.scrollbar .handle {
+  width: 100px;
+  height: 100%;
+  background: rgba(255, 255, 255, 0.75);
+  border-radius: 5px;
+}
+
+#progressBar,
+#status {
+  display: table-cell;
+  height: 0;
+  vertical-align: middle;
+}
+
+#playHead {
+  display: table;
+  position: absolute;
+  bottom: -20px;
+  left: 0;
+  height: 20px;
+  width: 100%;
+  transition-property: bottom;
+  transition-duration: 0.5s;
+  background-color: #000;
+
+  &.playing {
+    bottom: 0;
+  }
+}
+
+#status {
+  width: 65px;
+  color: #fff;
+  font-family: OpenSans, 'Helvetica Neue', Arial, sans-serif;
+  font-weight: 700;
+  font-size: 11px;
+  padding-left: 10px;
+}
+
+#progressBar {
+  padding: 0 10px;
+  pointer-events: all;
+
+  .step {
+    height: 6px;
+    float: left;
+
+    &::before {
+      content: '';
+      display: block;
+      width: 100%;
+      height: 100%;
+      background-color: #575757;
+    }
+    &.active::before {
+      background-color: #ddaf35;
+    }
+  }
+}
+
+@media only screen and (max-width: 487px), (max-height: 487px) {
+  .frame-container {
+    border-radius: 0;
+  }
+  #drawer.open.noScroll {
+    height: 110px;
+  }
+  .frame {
+    padding: 9px 7px;
+    height: inherit;
+
+    .slidee li {
+      width: 100px;
+      margin-right: 7px;
+
+      .overlay {
+        font-size: 10px;
+      }
+    }
+  }
+  #thumb-container .thumbImg img {
+    height: 60px;
+  }
+
+  #drawer-container.drawerOpen #drawer.open.noScroll,
+  #drawer.open.noScroll.playing {
+    height: 110px;
+  }
+}

+ 1 - 1
src/views/home/components/guide/index.tsx

@@ -7,7 +7,7 @@ export default defineComponent({
     return (
       <div id="drawer-container">
         <div id="drawer" class="fullWidth">
-          <div class="frame-container darkGlass">
+          <div class="frame-container">
             <div id="scrollFrame" class="frame">
               <ul id="thumb-container" class="slidee"></ul>
             </div>

+ 174 - 171
src/views/home/components/hot-spot-list/index.scss

@@ -1,171 +1,174 @@
-#hotListWrap {
-  display: flex;
-  flex-direction: column;
-  position: absolute;
-  top: 0;
-  right: -400px;
-  width: 356px;
-  height: 100%;
-  transition: right 0.4s, width 0.5s;
-  z-index: var(--el-index-popper);
-}
-
-.hotListActive {
-  right: 0 !important;
-}
-
-#hotListTitle {
-  position: relative;
-  width: 100%;
-  height: 15%;
-  background: #222425;
-  opacity: 0.8;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  text-align: center;
-}
-
-#hotListContent {
-  width: 100%;
-  background: rgba(34, 36, 37, 0.7);
-  /* opacity: 0.65; */
-  flex-grow: 1;
-  height: 100%;
-  overflow-y: scroll;
-  overflow-x: hidden;
-}
-
-#hotListBottom {
-  position: relative;
-  height: 20%;
-  background: rgba(34, 36, 37, 0.7);
-}
-
-#hotListClose {
-  position: absolute;
-  width: 26px;
-  right: 64px;
-  bottom: 64px;
-}
-
-#hotListContent ul {
-  padding: 40px 30px;
-  font-size: 18px;
-  letter-spacing: 3px;
-}
-
-#hotListContent ul li {
-  height: 68px;
-  line-height: 68px;
-  text-align: right;
-  color: #979cab;
-  padding: 0 25px;
-  transition: color 0.3s, background 0.6s;
-  border-radius: 10px;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-}
-
-#hotListContent ul li:hover {
-  color: white;
-}
-
-#hotListContent ul li.active {
-  color: black;
-  background: #f3f5f9;
-}
-
-#hotListText {
-  font-size: 22px;
-  letter-spacing: 4px;
-  color: white;
-}
-
-#hotListIcon {
-  width: 34px;
-  margin-left: 48px;
-}
-
-#hotListContent::-webkit-scrollbar {
-  width: 6px;
-}
-
-#hotListContent::-webkit-scrollbar-thumb {
-  border-radius: 10px;
-  background-color: #979cab;
-}
-
-#hotListContent::-webkit-scrollbar-track {
-  border-radius: 10px;
-}
-
-@media only screen and (max-width: 910px) {
-  #hotListWrap {
-    top: -320px;
-    right: 0;
-    width: 100%;
-    height: 250px;
-    transition: top 0.4s, width 0.5s;
-    background: rgba(34, 36, 37, 0.9);
-  }
-  .hotListActive {
-    top: 0 !important;
-  }
-
-  #hotListTitle {
-    height: 40%;
-    position: relative;
-    background: none;
-    opacity: 1;
-  }
-  #hotListContent {
-    /* background: rgba(34, 36, 37,0.9); */
-    background: none;
-  }
-  #hotListText {
-    font-size: 20px;
-    letter-spacing: 3px;
-    font-weight: 100;
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    transform: translate(-50%, -50%);
-  }
-  #hotListIcon {
-    width: 24px;
-    margin-left: 26px;
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    transform: translate(165%, -50%);
-  }
-  #hotListContent ul li {
-    text-align: center;
-    height: 40px;
-    line-height: 40px;
-  }
-  #hotListContent ul {
-    padding: 0 30px;
-    font-size: 16px;
-  }
-  #hotListBottom {
-    display: none;
-    height: 15%;
-    /* background: rgba(34, 36, 37,0.9); */
-    background: none;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-  #hotListClose {
-    display: none;
-    position: initial;
-    width: 18px;
-  }
-  #hotListContent ul li.active {
-    color: white;
-    background: none;
-  }
-}
+#hotListWrap {
+  display: none;
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba($color: #5e1a13, $alpha: 0.8);
+  z-index: 1001;
+}
+
+.hotListWrapContainer {
+  display: flex;
+  flex-direction: column;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  padding: 64px;
+  width: 941px;
+  height: 640px;
+  border-radius: 20px;
+  overflow: hidden;
+  transform: translate(-50%, -50%);
+  box-sizing: border-box;
+  background: url('/public/images/hotspot-bg.png') no-repeat center / contain;
+}
+
+.hotListActive {
+  display: block !important;
+}
+
+#hotListTitle {
+  margin-bottom: 38px;
+  color: #c41800;
+  font-size: 24px;
+  line-height: 28px;
+  font-weight: bold;
+}
+
+#hotListContent {
+  padding-right: 10px;
+  width: 100%;
+  flex-grow: 1;
+  height: 100%;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+
+#hotListBottom {
+  position: relative;
+  height: 20%;
+}
+
+#hotListClose {
+  position: absolute;
+  width: 36px;
+  height: 36px;
+  top: 64px;
+  right: 60px;
+  cursor: pointer;
+}
+
+#hotListContent ul {
+  font-size: 16px;
+}
+
+#hotListContent ul li {
+  height: 50px;
+  line-height: 50px;
+  color: white;
+  transition: color 0.3s, background 0.6s;
+  overflow: hidden;
+  white-space: nowrap;
+  border-top: 1px solid rgba($color: white, $alpha: 0.6);
+  text-overflow: ellipsis;
+}
+
+#hotListContent ul li:hover {
+  color: black;
+}
+
+#hotListContent ul li.active {
+  color: black;
+}
+
+#hotListIcon {
+  width: 34px;
+  margin-left: 48px;
+}
+
+#hotListContent::-webkit-scrollbar {
+  width: 6px;
+}
+
+#hotListContent::-webkit-scrollbar-thumb {
+  border-radius: 10px;
+  background-color: #ddaf35;
+}
+
+#hotListContent::-webkit-scrollbar-track {
+  border-radius: 10px;
+}
+
+@media only screen and (max-width: 910px) {
+  #hotListWrap {
+    top: -320px;
+    right: 0;
+    width: 100%;
+    height: 100%;
+    transition: top 0.4s, width 0.5s;
+    background: rgba(34, 36, 37, 0.9);
+  }
+  .hotListWrapContainer {
+    padding: 30px;
+    width: 100%;
+    height: 100%;
+    border-radius: 0;
+    background: url('/public/images/hotspot-bg-mobile-min.jpg') no-repeat left bottom / cover;
+  }
+  .hotListActive {
+    top: 0 !important;
+  }
+
+  #hotListTitle {
+    position: relative;
+    margin-bottom: 15px;
+    background: none;
+    opacity: 1;
+  }
+  #hotListContent {
+    /* background: rgba(34, 36, 37,0.9); */
+    background: none;
+  }
+  #hotListText {
+    font-size: 19px;
+    line-height: 22px;
+    font-weight: bold;
+  }
+  #hotListIcon {
+    width: 24px;
+    margin-left: 26px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(165%, -50%);
+  }
+  #hotListContent ul li {
+    height: 40px;
+    line-height: 40px;
+    border: 0;
+  }
+  #hotListContent ul {
+    font-size: 16px;
+  }
+  #hotListBottom {
+    display: none;
+    height: 15%;
+    /* background: rgba(34, 36, 37,0.9); */
+    background: none;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+  #hotListClose {
+    top: 20px;
+    right: 12px;
+    width: 33px;
+    height: 33px;
+  }
+  #hotListContent ul li.active {
+    color: white;
+    background: none;
+  }
+}

+ 10 - 9
src/views/home/components/hot-spot-list/index.tsx

@@ -6,16 +6,17 @@ export default defineComponent({
   render() {
     return (
       <div id="hotListWrap">
-        <div id="hotListTitle">
-          <div>
-            <span id="hotListText">热点列表</span>
+        <div class="hotListWrapContainer">
+          <div id="hotListTitle">
+            <div>
+              <span id="hotListText">热点列表</span>
+            </div>
           </div>
-        </div>
-        <div id="hotListContent">
-          <ul></ul>
-        </div>
-        <div id="hotListBottom">
-          <img id="hotListClose" src="/images/close1.png" alt="" />
+          <div id="hotListContent">
+            <ul></ul>
+          </div>
+          <div id="hotListBottom"></div>
+          <img id="hotListClose" src="./images/close1.png" alt="" />
         </div>
       </div>
     );

+ 85 - 82
src/views/home/components/menu/index.scss

@@ -24,7 +24,7 @@
     bottom: 140px;
 
     &.noScroll {
-      bottom: 117px;
+      bottom: 190px;
 
       &.playing {
         bottom: 135px;
@@ -35,73 +35,92 @@
     }
   }
   &.left {
-    background: rgba(0, 0, 0, 0.2);
-    border-radius: 10px;
-    left: 10px;
-    bottom: 10px;
+    left: 36px;
+    bottom: 38px;
   }
   &.right {
-    right: 0;
-    bottom: 10px;
-    text-shadow: 0 0 1px rgba(0, 0, 0, 0.6);
-
-    .rightViewContainer > div:hover {
-      background: rgba(0, 0, 0, 0.25);
-    }
-    .ui-icon {
-      float: left;
-      padding: 0;
-      margin-right: 10px;
-      background: rgba(0, 0, 0, 0.2);
-      border-radius: 10px;
-    }
+    right: 30px;
+    bottom: 38px;
+
+    // .rightViewContainer > div:hover {
+    //   background: rgba(0, 0, 0, 0.25);
+    // }
+    // .ui-icon {
+    //   float: left;
+    //   padding: 0;
+    //   margin-right: 10px;
+    //   background: rgba(0, 0, 0, 0.2);
+    //   border-radius: 10px;
+    // }
   }
 }
 
-.viewContainer {
-  float: left;
-  position: relative;
+.rightViewContainer {
+  display: flex;
+  align-items: center;
+  gap: 14px;
+}
 
-  > div {
-    float: left;
-  }
+.viewContainer,
+#gui-modes-map {
+  position: relative;
+  display: flex;
+  gap: 14px;
 }
 
 #play,
 #pause {
-  position: relative;
-  width: 94px;
-  height: 48px;
-  display: flex;
-  justify-content: center;
-  align-items: center;
   cursor: pointer;
+}
 
-  &:hover {
-    background: rgba(0, 0, 0, 0.25);
-  }
+.w52 {
+  width: 52px;
+  height: 52px;
 }
 
 #gui-modes-map > div {
-  float: left;
-  width: 94px;
-  height: 48px;
-  display: flex;
-  justify-content: center;
-  align-items: center;
+  position: relative;
+  width: 52px;
+  height: 52px;
   cursor: pointer;
 
-  &:hover,
-  &.active,
-  &.opened {
-    background: rgba(0, 0, 0, 0.25);
-  }
+  // &:hover,
+  // &.active,
+  // &.opened {
+  //   background: rgba(0, 0, 0, 0.25);
+  // }
   img {
-    width: 24px;
-    height: 24px;
+    width: 100%;
+    height: 100%;
   }
 }
 
+#hotList.active::before,
+#gui-modes-inside.active::before,
+#gui-modes-dollhouse.active::before,
+#gui-modes-floorplan.active::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 1;
+}
+
+#hotList.active::before {
+  background: url('/public/images/icon-list-1@2x-min.png') no-repeat center / contain;
+}
+#gui-modes-inside.active::before {
+  background: url('/public/images/icon-quanjing-1@2x-min.png') no-repeat center / contain;
+}
+#gui-modes-dollhouse.active::before {
+  background: url('/public/images/icon-mini-1@2x-min.png') no-repeat center / contain;
+}
+#gui-modes-floorplan.active::before {
+  background: url('/public/images/icon-fushi-1@2x-min.png') no-repeat center / contain;
+}
+
 #pullTab {
   display: block;
   position: relative;
@@ -110,15 +129,6 @@
   text-align: center;
 }
 
-#volume > a,
-#gui-fullscreen > a {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  width: 48px;
-  height: 48px;
-}
-
 .terms2 {
   display: none;
 }
@@ -133,38 +143,31 @@
 }
 
 @media only screen and (max-width: 600px) {
-  .pinBottom.right,
-  .pinBottom.left {
-    bottom: 5px;
-  }
-  .pinBottom.left {
-    left: 5px;
-  }
-  .pinBottom.right .ui-icon {
-    margin-right: 5px;
-  }
-  #play,
-  #pause {
-    width: 64px;
-  }
-  #gui-modes-map > div {
-    width: 64px;
-  }
   .viewContainer,
   #gui-modes-map {
     display: flex;
     flex-direction: column;
+    gap: 5px;
   }
-}
-
-@media only screen and (max-width: 487px), (max-height: 487px) {
-  .pinBottom-container.drawerOpen.duringTour {
-    bottom: 6px;
+  .w52,
+  #gui-modes-map > div {
+    width: 37px;
+    height: 37px;
+  }
+  .pinBottom.left {
+    left: 11px;
+  }
+  .pinBottom.open.noScroll {
+    bottom: 130px;
   }
-  #gui .pinBottom.open.noScroll {
-    bottom: 93px;
+  .pinBottom.right {
+    position: fixed;
+    top: 120px;
+    right: 8px;
+    bottom: unset;
   }
-  .pinBottom.open.noScroll.playing {
-    bottom: 108px;
+  .rightViewContainer {
+    flex-direction: column;
+    gap: 5px;
   }
 }

+ 19 - 13
src/views/home/components/menu/index.tsx

@@ -3,6 +3,7 @@ import './index.scss';
 
 export default defineComponent({
   name: 'HomeMenu',
+  emits: ['showCover'],
   render() {
     return (
       <div class="pinBottom-container">
@@ -10,17 +11,17 @@ export default defineComponent({
           <div class="viewContainer">
             <div id="previous" class="previous desktop-only ui-icon" style="display: none;">
               <a>
-                <img src="images/play.png" width="24" height="24" data-original-title="播放" />
+                <img class="w52" src="./images/play.png" data-original-title="播放" />
               </a>
             </div>
             <div id="play" class="ui-icon" data-original-title="播放">
               <a>
-                <img src="images/play.png" width="24" height="24" />
+                <img class="w52" src="./images/play.png" />
               </a>
             </div>
             <div id="pause" class="ui-icon" style="display: none;">
               <a>
-                <img title="暂停" src="images/pause.png" width="24" height="24" />
+                <img class="w52" title="暂停" src="./images/pause.png" />
               </a>
             </div>
             <div id="next" class="next desktop-only ui-icon wide" style="display: none;">
@@ -30,22 +31,22 @@ export default defineComponent({
             </div>
             <div id="gui-modes-map" class="ui-icon double active">
               <div data-original-title="导览" id="pullTab" title="">
-                <img class="icon icon-inside" src="images/auto.png" title="导览" />
+                <img class="icon icon-inside" src="./images/auto.png" title="导览" />
               </div>
               <div data-original-title="热点列表" id="hotList" title="" style="display: none">
-                <img class="icon icon-inside" src="images/hotlist.png" title="热点列表" />
+                <img class="icon icon-inside" src="./images/hotlist.png" title="热点列表" />
               </div>
               <div data-original-title="全景漫游" id="gui-modes-inside" title="" class="">
-                <img class="icon icon-inside" src="images/inside.png" title="全景漫游" />
+                <img class="icon icon-inside" src="./images/inside.png" title="全景漫游" />
               </div>
               <div data-original-title="迷你模型" id="gui-modes-dollhouse" title="" class="">
-                <img class="icon icon-inside" src="images/dollhouse.png" title="迷你模型" />
+                <img class="icon icon-inside" src="./images/dollhouse.png" title="迷你模型" />
               </div>
               <div data-original-title="俯视图" id="gui-modes-floorplan" title="">
-                <img class="icon icon-inside" src="images/floor.png" title="俯视图" />
+                <img class="icon icon-inside" src="./images/floor.png" title="俯视图" />
               </div>
               <div data-original-title="VR" id="vr" title="" style="display: none;">
-                <img class="icon icon-inside" src="images/VR.png" title="VR" />
+                <img class="icon icon-inside" src="./images/VR.png" title="VR" />
               </div>
               <div
                 data-original-title="消除外壳"
@@ -53,16 +54,21 @@ export default defineComponent({
                 title=""
                 style="display: none; float: left;"
               >
-                <img class="icon icon-inside" src="images/face.jpg" />
+                <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" onClick={() => this.$emit('showCover')}>
+              <a>
+                <img class="w52" src="./images/icon-home@2x-min.png" />
+              </a>
+            </div>
             <div id="volume" class="ui-icon wide">
               <a>
-                <img src="images/Volume btn_on.png" width="24" height="24" />
+                <img class="w52" src="./images/Volume btn_on.png" />
               </a>
             </div>
             <div id="vr" class="ui-icon wide hidden" style="display: none;">
@@ -82,7 +88,7 @@ export default defineComponent({
               title="{[{ VIEW_FULLSCREEN }]}"
             >
               <a>
-                <i class="icon icon-fullscreen"></i>
+                <img class="w52" src="./images/icon-fangda@2x-min.png" draggable={false} />
               </a>
             </div>
             <div
@@ -93,7 +99,7 @@ export default defineComponent({
               style="display: none;"
             >
               <a>
-                <i class="icon icon-fullscreen-exit"></i>
+                <img class="w52" src="./images/icon-suoxiao@2x-min.png" draggable={false} />
               </a>
             </div>
             <div class="pull-right terms terms2">

+ 43 - 35
src/views/home/components/popup/index.scss

@@ -1,35 +1,43 @@
-#popup {
-  display: none;
-  position: relative;
-  padding: 0;
-  width: 100%;
-  height: 100%;
-  text-align: center;
-  background: rgba(0, 0, 0, 0.6);
-  z-index: var(--z-index-popper);
-
-  &.wait {
-    opacity: 0.1;
-  }
-}
-#id1 {
-  width: 100%;
-  height: 100%;
-}
-.popup-content {
-  position: relative;
-  width: 100%;
-  height: 100%;
-  overflow: hidden;
-}
-#closepop {
-  position: absolute;
-  top: 30px;
-  right: 30px;
-  width: 60px;
-  height: 60px;
-  cursor: pointer;
-  text-indent: -999em;
-  background-size: 100% 100%;
-  background: url('/public/images/close1.png') no-repeat;
-}
+#popup {
+  display: none;
+  position: relative;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  background: rgba(0, 0, 0, 0.6);
+  z-index: var(--z-index-popper);
+
+  &.wait {
+    opacity: 0.1;
+  }
+}
+#id1 {
+  width: 100%;
+  height: 100%;
+}
+.popup-content {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+}
+#closepop {
+  position: absolute;
+  top: 40px;
+  right: 48px;
+  width: 50px;
+  height: 50px;
+  cursor: pointer;
+  text-indent: -999em;
+  background: url('/public/images/icon-close@2x-min.png') no-repeat center / contain;
+}
+
+@media only screen and (max-width: 600px) {
+  #closepop {
+    top: 20px;
+    right: 12px;
+    width: 33px;
+    height: 33px;
+  }
+}

+ 210 - 190
src/views/home/components/title/index.scss

@@ -1,190 +1,210 @@
-.pinTop {
-  position: fixed;
-  top: 16px;
-  left: 50%;
-  display: flex;
-  align-items: center;
-  flex-direction: column;
-  transition: all 0.5s;
-  line-height: 1;
-  transform: translateX(-50%);
-  z-index: var(--z-index-normal);
-}
-
-#model-title {
-  position: relative;
-  padding: 0 10px;
-  min-width: 180px;
-  height: 38px;
-  font-weight: 100;
-  transition: all 0.3s;
-  pointer-events: all;
-  border-radius: 10px;
-  word-wrap: break-word;
-  background: rgba(0, 0, 0, 0.2);
-
-  &:hover,
-  &.expand {
-    background: rgba(0, 0, 0, 0.5);
-  }
-}
-
-.title-row {
-  display: flex;
-  align-items: center;
-  justify-content: space-around;
-  white-space: nowrap;
-}
-
-#title-toggle {
-  display: none;
-}
-
-#title-container-wrapper {
-  width: 100%;
-  overflow: hidden;
-}
-
-.title-container {
-  position: relative;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  right: 0;
-  margin-left: 1px;
-  height: 38px;
-  width: 100%;
-  white-space: nowrap;
-  transition: all 0.4s ease-in-out;
-
-  &.expand {
-    #more-hint {
-      display: none;
-    }
-  }
-  &.meta-toggle {
-    cursor: pointer;
-  }
-  #more-hint,
-  &.expand #less-hint {
-    display: flex;
-    align-items: center;
-    padding-left: 12px;
-    height: 100%;
-    font-weight: 400;
-    font-size: 10px;
-  }
-  #less-hint {
-    display: none;
-  }
-  .icon-dpad-down {
-    position: relative;
-    display: block;
-    width: 0;
-    height: 0;
-    border-width: 8px 6px 0;
-    border-style: solid;
-    border-color: #fff transparent transparent;
-    margin: 40px 0;
-    transition: all 0.2s;
-  }
-  .icon-dpad-up {
-    display: block;
-    width: 0;
-    height: 0;
-    border-width: 0px 6px 8px;
-    border-style: solid;
-    border-color: transparent transparent #fff;
-    margin: 40px 0;
-    transition: all 0.2s;
-    position: relative;
-  }
-}
-
-#title-logo {
-  margin-right: 6px;
-
-  i {
-    display: block;
-    width: 18px;
-    height: 18px;
-    background: url('/public/images/4dage-logo.png') left top no-repeat;
-    background-size: 100%;
-  }
-}
-
-#gui-name {
-  display: flex;
-  align-items: center;
-  overflow: hidden;
-  height: 100%;
-  line-height: 18px;
-  font-size: 18px;
-}
-
-#meta-info-wrapper {
-  position: relative;
-  top: 14px;
-  width: 360px;
-  overflow: hidden;
-
-  &.expand {
-    pointer-events: auto;
-  }
-}
-
-#meta-info {
-  position: relative;
-  bottom: 100%;
-  width: 100%;
-  padding: 10px;
-  white-space: normal;
-  font-size: 14px;
-  font-weight: 400;
-  line-height: 19px;
-  color: #fff;
-  border-radius: 10px;
-  transition: all 0.4s ease-in-out;
-
-  * {
-    user-select: text;
-  }
-  &.expand {
-    bottom: 0;
-  }
-  #meta-description {
-    margin-bottom: 10px;
-    word-wrap: break-word;
-    text-align: justify;
-  }
-  .contact-info {
-    margin-bottom: 12px;
-  }
-  .address {
-    width: 100%;
-    white-space: nowrap;
-    overflow: hidden;
-  }
-  .menu-toggles {
-    font-size: 14px;
-    padding-top: 10px;
-  }
-}
-
-@media only screen and (max-width: 370px) {
-  #gui-name {
-    font-size: 16px;
-  }
-  #meta-info-wrapper {
-    width: 100vw;
-  }
-  #meta-info {
-    font-size: 12px;
-  }
-}
-
-@media only screen and (max-width: 330px) {
-  #gui-name {
-    font-size: 14px;
-  }
-}
+.pinTop {
+  position: fixed;
+  top: 34px;
+  left: 36px;
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  transition: all 0.5s;
+  line-height: 1;
+  z-index: var(--z-index-normal);
+}
+
+#model-title {
+  position: relative;
+  min-width: 180px;
+  width: 100%;
+  height: 46px;
+  font-weight: 400;
+  transition: all 0.3s;
+  pointer-events: all;
+  border-radius: 5px;
+  word-wrap: break-word;
+  background: rgba($color: #5e1a13, $alpha: 0.6);
+
+  // &:hover,
+  // &.expand {
+  //   background: rgba(0, 0, 0, 0.5);
+  // }
+}
+
+.title-row {
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+  white-space: nowrap;
+}
+
+#title-toggle {
+  display: none;
+}
+
+#title-container-wrapper {
+  width: 100%;
+  overflow: hidden;
+}
+
+.title-container {
+  position: relative;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  right: 0;
+  padding-right: 2px;
+  margin-left: 1px;
+  height: 46px;
+  width: 100%;
+  white-space: nowrap;
+  transition: all 0.4s ease-in-out;
+
+  &__line {
+    flex-shrink: 0;
+    width: 1px;
+    height: 36px;
+  }
+  &.expand {
+    #more-hint {
+      display: none;
+    }
+  }
+  &.meta-toggle {
+    cursor: pointer;
+  }
+  #more-hint {
+    position: relative;
+    left: 2px;
+    transform: rotate(180deg);
+  }
+  #more-hint,
+  &.expand #less-hint {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 45px;
+    height: 100%;
+    font-weight: 400;
+    font-size: 10px;
+
+    img {
+      width: 18px;
+      height: 10px;
+    }
+  }
+  #less-hint {
+    display: none;
+  }
+  .icon-dpad-down {
+    position: relative;
+    display: block;
+    width: 0;
+    height: 0;
+    border-width: 8px 6px 0;
+    border-style: solid;
+    border-color: #fff transparent transparent;
+    margin: 40px 0;
+    transition: all 0.2s;
+  }
+  .icon-dpad-up {
+    display: block;
+    width: 0;
+    height: 0;
+    border-width: 0px 6px 8px;
+    border-style: solid;
+    border-color: transparent transparent #fff;
+    margin: 40px 0;
+    transition: all 0.2s;
+    position: relative;
+  }
+}
+
+#title-logo {
+  display: none;
+  margin-right: 6px;
+
+  i {
+    display: block;
+    width: 18px;
+    height: 18px;
+    background: url('/public/images/4dage-logo.png') left top no-repeat;
+    background-size: 100%;
+  }
+}
+
+#gui-name {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  padding: 0 14px;
+  overflow: hidden;
+  height: 100%;
+  line-height: 19px;
+  font-size: 16px;
+}
+
+#meta-info-wrapper {
+  position: relative;
+  top: 14px;
+  width: 360px;
+  overflow: hidden;
+
+  &.expand {
+    pointer-events: auto;
+  }
+}
+
+#meta-info {
+  position: relative;
+  bottom: 100%;
+  width: 100%;
+  padding: 10px;
+  white-space: normal;
+  font-size: 14px;
+  font-weight: 400;
+  line-height: 19px;
+  color: #fff;
+  border-radius: 10px;
+  background: rgba($color: #5e1a13, $alpha: 0.6);
+  transition: all 0.4s ease-in-out;
+
+  * {
+    user-select: text;
+  }
+  &.expand {
+    bottom: 0;
+  }
+  #meta-description {
+    margin-bottom: 10px;
+    word-wrap: break-word;
+    text-align: justify;
+  }
+  .contact-info {
+    margin-bottom: 12px;
+  }
+  .address {
+    width: 100%;
+    white-space: nowrap;
+    overflow: hidden;
+  }
+  .menu-toggles {
+    font-size: 14px;
+    padding-top: 10px;
+  }
+}
+
+@media only screen and (max-width: 370px) {
+  #gui-name {
+    font-size: 16px;
+  }
+  #meta-info-wrapper {
+    width: 100vw;
+  }
+  #meta-info {
+    font-size: 12px;
+  }
+}
+
+@media only screen and (max-width: 330px) {
+  #gui-name {
+    font-size: 14px;
+  }
+}

+ 6 - 3
src/views/home/components/title/index.tsx

@@ -23,18 +23,21 @@ export default defineComponent({
                   <i></i>
                 </div>
                 <div id="gui-name" class="titleText"></div>
+
+                <img class="title-container__line" draggable={false} src="./images/line@2x.png" />
+
                 <a id="more-hint">
-                  <i class="icon icon-dpad-down"></i>
+                  <img src="./images/icon-shang@2x.png" draggable={false} />
                 </a>
                 <a id="less-hint">
-                  <i class="icon icon-dpad-up"></i>
+                  <img src="./images/icon-shang@2x.png" draggable={false} />
                 </a>
               </div>
             </div>
           </div>
         </div>
         <div id="meta-info-wrapper">
-          <div id="meta-info" class="darkGlass">
+          <div id="meta-info">
             <div id="meta-description"></div>
             <div class="contact-info">
               <i class="icon icon-user pull-left"></i>

+ 2 - 32
src/views/home/index.scss

@@ -1,30 +1,6 @@
 .home {
   width: 100%;
   height: 100%;
-
-  &_logo {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    position: absolute;
-    left: 50%;
-    bottom: 20px;
-    width: 300px;
-    text-align: center;
-    font-size: 14px;
-    transform: translateX(-50%);
-    color: rgba(255, 255, 255, 0.8);
-
-    img {
-      width: 50%;
-    }
-    span {
-      font-size: 16px;
-      padding: 5px 0;
-      color: rgba(255, 255, 255, 0.8);
-      border-bottom: 1px solid rgba(255, 255, 255, 0.8);
-    }
-  }
 }
 
 #player {
@@ -80,13 +56,7 @@
 }
 
 @media only screen and (max-width: 600px) {
-  .home {
-    &_logo {
-      width: 200px;
-
-      span {
-        font-size: 14px;
-      }
-    }
+  #model-title {
+    display: none;
   }
 }

+ 14 - 13
src/views/home/index.tsx

@@ -1,5 +1,6 @@
 import { defineComponent, ref } from 'vue';
 import JsScript from '@/components/js-script';
+import Cover from '../cover';
 import Title from './components/title';
 import WebVr from './components/web-vr';
 import Other from './components/other';
@@ -25,8 +26,10 @@ export default defineComponent({
   setup() {
     const manageJsLoaded = ref(false);
     const hotJsLoaded = ref(false);
+    const coverVisible = ref(true);
 
     return {
+      coverVisible,
       manageJsLoaded,
       hotJsLoaded,
     };
@@ -34,6 +37,9 @@ export default defineComponent({
   render() {
     return (
       <div class="home">
+        {/* 封面 */}
+        {this.coverVisible && <Cover onClose={() => (this.coverVisible = false)} />}
+
         {/* 进度条加载 */}
         <GuiLoading />
 
@@ -59,15 +65,10 @@ export default defineComponent({
             <HotSpotList />
 
             {/* 底部菜单 */}
-            <Menu />
+            <Menu onShowCover={() => (this.coverVisible = true)} />
 
             {/* 导览 */}
             <Guide />
-
-            <div class="home_logo">
-              <img src="images/btm_logo.png" />
-              <span>提供技术支持</span>
-            </div>
           </div>
 
           <WebVr />
@@ -76,18 +77,18 @@ export default defineComponent({
         </div>
 
         {/* TODO: 没有控制权,耦合严重;放在此处为了防止元素未渲染导致报错 */}
-        <JsScript src="/js/manage.js" onLoad={() => (this.manageJsLoaded = true)} />
+        <JsScript src="./js/manage.js" onLoad={() => (this.manageJsLoaded = true)} />
         {this.manageJsLoaded && (
           <>
-            <JsScript src="/js/Hot.js" onLoad={() => (this.hotJsLoaded = true)} />
+            <JsScript src="./js/Hot.js" onLoad={() => (this.hotJsLoaded = true)} />
             {this.hotJsLoaded && (
               <>
-                <JsScript src="/js/main_2020_show.js" />
+                <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" />
+                <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" />
               </>
             )}
           </>

+ 238 - 0
src/views/hotspot/index.scss

@@ -0,0 +1,238 @@
+.hotspot-page {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(255, 252, 247, 0.8);
+  z-index: var(--z-index-popper);
+
+  &-info {
+    position: absolute;
+    top: 42px;
+    left: 40px;
+
+    h3 {
+      margin-bottom: 14px;
+      max-width: 50%;
+      color: #c41800;
+      font-size: 24px;
+      line-height: 28px;
+    }
+    p {
+      width: 214px;
+      height: 213px;
+      color: #333333;
+      font-size: 14px;
+      overflow-y: auto;
+
+      &::-webkit-scrollbar {
+        width: 6px;
+      }
+      &::-webkit-scrollbar-thumb {
+        border-radius: 10px;
+        background-color: #c41800;
+      }
+      &::-webkit-scrollbar-track {
+        border-radius: 10px;
+      }
+    }
+  }
+
+  &-main {
+    position: absolute;
+    top: 45%;
+    left: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 1100px;
+    transform: translate(-50%, -50%);
+  }
+  &-swiper {
+    &__left,
+    &__right {
+      position: absolute;
+      top: 50%;
+      width: 50px;
+      height: 50px;
+      cursor: pointer;
+      transform: translateY(-50%);
+      z-index: 1;
+    }
+    &__left {
+      left: -50px;
+      background: url('@/assets/images/icon-previous@2x-min.png') no-repeat center / contain;
+    }
+    &__right {
+      right: -50px;
+      background: url('@/assets/images/icon-next@2x-min.png') no-repeat center / contain;
+    }
+  }
+  &-model {
+    width: 100%;
+    height: 600px;
+
+    iframe {
+      width: 100%;
+      height: 100%;
+    }
+  }
+  &-video {
+    width: 900px;
+    height: 561px;
+    object-fit: cover;
+  }
+  &-img {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: inherit;
+
+    &-swiper {
+      height: 567px;
+    }
+    img {
+      width: 100%;
+      height: 100%;
+      object-fit: contain;
+    }
+  }
+
+  &-nav {
+    position: absolute;
+    left: 50%;
+    bottom: 104px;
+    display: flex;
+    align-items: center;
+    gap: 30px;
+    transform: translateX(-50%);
+
+    &__item {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      gap: 9px;
+      width: 120px;
+      height: 36px;
+      border-radius: 18px;
+      color: #666666;
+      background: #d0cec6;
+      border: 1px solid #666666;
+      box-sizing: border-box;
+      cursor: pointer;
+
+      &.active {
+        color: #ddaf35;
+        border-width: 0;
+        background: linear-gradient(#d67729, #c41800);
+      }
+      .model-icon {
+        width: 19px;
+        height: 22px;
+      }
+      .video-icon {
+        width: 21px;
+        height: 18px;
+      }
+      .img-icon {
+        width: 21px;
+        height: 18px;
+      }
+    }
+  }
+}
+
+@media only screen and (max-width: 600px) {
+  .hotspot-page-info {
+    top: unset;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    display: flex;
+    flex-direction: column;
+    padding: 20px 25px;
+    height: 167px;
+    box-sizing: border-box;
+    border-top-left-radius: 17px;
+    border-top-right-radius: 17px;
+    background: linear-gradient(181deg, #d67729 0%, #c41800 100%);
+
+    h3 {
+      margin-bottom: 7px;
+      max-width: 100%;
+      width: 100%;
+      color: white;
+      font-size: 18px;
+      font-weight: bold;
+      display: -webkit-box;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      -webkit-line-clamp: 1;
+      -webkit-box-orient: vertical;
+      word-break: break-all;
+      word-wrap: break-word;
+    }
+    p {
+      flex: 1;
+      padding-right: 2px;
+      width: 100%;
+      height: 0;
+      color: white;
+
+      &::-webkit-scrollbar {
+        width: 2px;
+      }
+      &::-webkit-scrollbar-thumb {
+        background-color: #ddaf35;
+      }
+    }
+  }
+  .hotspot-page-nav {
+    bottom: 194px;
+    gap: 13px;
+
+    &__item {
+      width: 70px;
+      height: 20px;
+      font-size: 10px;
+      gap: 4px;
+
+      .video-icon,
+      .img-icon {
+        width: 12px;
+        height: 10px;
+      }
+      .model-icon {
+        width: 10px;
+        height: 11px;
+      }
+    }
+  }
+  .hotspot-page-swiper__left,
+  .hotspot-page-swiper__right {
+    width: 19px;
+    height: 38px;
+  }
+  .hotspot-page-swiper__left {
+    left: 0;
+    background-image: url('@/assets/images/icon-left-min.png');
+  }
+  .hotspot-page-swiper__right {
+    right: 0;
+    background-image: url('@/assets/images/icon-right-min.png');
+  }
+  .hotspot-page-main {
+    top: 37%;
+    width: 100%;
+  }
+
+  .hotspot-page-video {
+    width: 300px;
+    height: 168px;
+  }
+  .hotspot-page-img-swiper,
+  .hotspot-page-model {
+    height: 50vh;
+  }
+}

+ 216 - 0
src/views/hotspot/index.vue

@@ -0,0 +1,216 @@
+<template>
+  <div class="hotspot-page">
+    <div class="hotspot-page-info">
+      <h3>{{ myTitle }}</h3>
+      <p>{{ myTxt }}</p>
+    </div>
+
+    <div class="hotspot-page-main">
+      <!-- 模型页面 -->
+      <Swiper
+        v-if="myType === 'model'"
+        class="hotspot-page-swiper hotspot-page-model"
+        @swiper="initSwiper"
+        @slideChange="handleChange"
+      >
+        <SwiperSlide v-for="(item, index) in curList" :key="item.url">
+          <iframe v-if="index === myInd" :src="item" frameborder="0" />
+        </SwiperSlide>
+      </Swiper>
+
+      <!-- 视频页面 -->
+      <Swiper
+        v-if="myType === 'video'"
+        class="hotspot-page-swiper hotspot-page-video"
+        @swiper="initSwiper"
+        @slideChange="handleChange"
+      >
+        <SwiperSlide v-for="(item, index) in curList" :key="item.url">
+          <video
+            v-if="index === myInd"
+            id="videoID"
+            class="hotspot-page-video"
+            controls
+            :src="item.url"
+            autoplay
+          />
+        </SwiperSlide>
+      </Swiper>
+
+      <!-- 图片页面 -->
+      <Swiper
+        v-if="myType === 'img'"
+        class="hotspot-page-swiper hotspot-page-img-swiper"
+        @swiper="initSwiper"
+        @slideChange="handleChange"
+      >
+        <SwiperSlide v-for="item in curList" :key="item">
+          <div class="hotspot-page-img">
+            <img :src="item" alt="" />
+          </div>
+        </SwiperSlide>
+      </Swiper>
+
+      <template v-if="curList.length > 1">
+        <div class="hotspot-page-swiper__left" @click="handlePre" />
+        <div class="hotspot-page-swiper__right" @click="handleNext" />
+      </template>
+    </div>
+
+    <!-- 底部的tab -->
+    <div v-if="flooTab.length > 1" class="hotspot-page-nav">
+      <div
+        v-for="item in flooTab"
+        :key="item.id"
+        :class="[
+          'hotspot-page-nav__item',
+          {
+            active: myType === item.type,
+          },
+        ]"
+        @click="handleTab(item)"
+      >
+        <img :class="`${item.type}-icon`" :src="myType === item.type ? item.acIcon : item.icon" />
+        {{ item.name }}
+        {{ item.type === 'img' ? `${myInd + 1}/${data.img.length}` : '' }}
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  import { Swiper, SwiperSlide } from 'swiper/vue';
+  import 'swiper/css';
+  import ModelIcon from '@/assets/images/icon-model@2x.png';
+  import AcModelIcon from '@/assets/images/icon-model-1@2x.png';
+  import ImageIcon from '@/assets/images/icon-image@2x.png';
+  import AcImageIcon from '@/assets/images/icon-image-1@2x.png';
+  import VideoIcon from '@/assets/images/icon-video@2x.png';
+  import AcVideoIcon from '@/assets/images/icon-video-1@2x.png';
+
+  export default {
+    name: 'hotspot',
+    components: {
+      Swiper,
+      SwiperSlide,
+    },
+    data() {
+      return {
+        m: this.$route.query.m,
+        id: this.$route.query.id,
+        // 音频地址
+        audio: '',
+        // 如果只有单独的音频
+        isOneAduio: false,
+        // 音频状态
+        audioSta: false,
+
+        data: {
+          // 模型数组
+          model: [],
+          // 视频数组
+          video: [],
+          // 图片数组
+          img: [],
+        },
+        // 当前 type
+        myType: '',
+
+        // 当前索引
+        myInd: 0,
+
+        // 底部的tab
+        flooTab: [],
+
+        // 标题
+        myTitle: '',
+        // 内容
+        myTxt: '',
+        // 视频内容
+        videoTxt: [],
+        imgTxt: [],
+
+        // 只有标题和文字(没有视频,没有模型,没有图片)
+        oneTxt: false,
+      };
+    },
+    computed: {
+      curList() {
+        return this.data[this.myType] || [];
+      },
+    },
+    mounted() {
+      this.getData();
+    },
+    methods: {
+      async getData() {
+        // https://www.4dmodel.com/
+        let url = `https://super.4dage.com/data/${this.id}/hot/js/data.js?time=${Math.random()}`;
+        let result = await fetch(url).then((response) => response.json());
+        const resData = result[this.m];
+        console.log('----', resData);
+        if (resData) {
+          this.audio = resData.backgroundMusic;
+          // 只有单独的音频上传
+          if (resData.backgroundMusic && !resData.model && !resData.video && !resData.images) {
+            this.isOneAduio = true;
+          }
+          // 底部的tab
+          const arr = [];
+          const obj = {};
+          if (resData.model) {
+            obj.model = resData.model;
+            arr.push({ id: 1, type: 'model', name: '模型', icon: ModelIcon, acIcon: AcModelIcon });
+          }
+          if (resData.video) {
+            obj.video = resData.video;
+            arr.push({ id: 2, type: 'video', name: '视频', icon: VideoIcon, acIcon: AcVideoIcon });
+          }
+          if (resData.images) {
+            obj.img = resData.images;
+            arr.push({ id: 3, type: 'img', name: '图片', icon: ImageIcon, acIcon: AcImageIcon });
+          }
+          this.flooTab = arr;
+          this.data = obj;
+
+          // 当前type的值 应该为
+          if (resData.model) this.myType = 'model';
+          else if (resData.video) this.myType = 'video';
+          else if (resData.images) this.myType = 'img';
+
+          this.myTitle = resData.title || '';
+          this.myTxt = resData.content || '';
+          this.videoTxt = resData.videosDesc || [];
+          this.imgTxt = resData.imagesDesc || [];
+
+          // 只有 标题和 文字介绍(没有视频,没有模型,没有图片)
+          if (!obj.model && !obj.video && !obj.img && !resData.backgroundMusic) {
+            this.oneTxt = true;
+          }
+        }
+      },
+
+      handleTab(item) {
+        this.myInd = 0;
+        this.myType = item.type;
+      },
+
+      initSwiper(swiper) {
+        this.swiper = swiper;
+      },
+      handleChange({ activeIndex }) {
+        this.myInd = activeIndex;
+      },
+      handlePre() {
+        this.swiper?.slidePrev();
+      },
+      handleNext() {
+        this.swiper?.slideNext();
+      },
+    },
+  };
+</script>
+
+<style lang="scss">
+  @import './index.scss';
+</style>

+ 3 - 2
vue.config.js

@@ -19,12 +19,13 @@ if (SCENE != null) {
 const ENV = getEnv();
 
 module.exports = defineConfig({
+  publicPath: './',
   transpileDependencies: true,
   lintOnSave: false,
   indexPath: `${SCENE || 'index'}.html`,
-  outputDir: IS_PRODUCTION && !!SCENE ? `build/${SCENE}` : 'build',
+  // outputDir: IS_PRODUCTION && !!SCENE ? `build/${SCENE}` : 'build',
   // 根据场景隔离
-  assetsDir: path.posix.join(config.assetsDir, SCENE || ''),
+  // assetsDir: path.posix.join(config.assetsDir, SCENE || ''),
 
   productionSourceMap: process.env.SOURCE_MAP === 'true' || false,
 

文件差異過大導致無法顯示
+ 10047 - 10042
yarn.lock