123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790 |
- <template>
- <div
- class="app-view"
- :class="{
- higher: !isShowNavBar,
- }"
- >
- <div
- v-show="$route.meta.isShowUnityModel"
- id="unity-container"
- >
- <canvas
- id="unity-canvas"
- width="960"
- height="600"
- tabindex="-1"
- />
- </div>
- <router-view />
- <nav
- v-show="!$route.meta.hideNavBar"
- :style="{
- bottom: isShowNavBar ? '0' : `-${navBarHeight}`,
- }"
- >
- <button
- class="tab-item"
- :class="{
- active: $route.meta.belongNavGroup === 0
- }"
- @click="$router.push({name: 'GeneralView'})"
- >
- 概述总览
- <img
- class="decorator"
- src="@/assets/images/nav-item-active-decorator.png"
- alt=""
- draggable="false"
- >
- </button>
- <button
- class="tab-item"
- :class="{
- active: $route.meta.belongNavGroup === 1
- }"
- @click="$router.push({name: 'HistoryView'})"
- >
- 历史回顾
- <img
- class="decorator"
- src="@/assets/images/nav-item-active-decorator.png"
- alt=""
- draggable="false"
- >
- </button>
- <button
- class="tab-item"
- :class="{
- active: $route.meta.belongNavGroup === 2
- }"
- @click="$router.push({name: 'TreasureView'})"
- >
- 国之重器
- <img
- class="decorator"
- src="@/assets/images/nav-item-active-decorator.png"
- alt=""
- draggable="false"
- >
- </button>
- <button
- class="tab-item"
- :class="{
- active: $route.meta.belongNavGroup === 3
- }"
- @click="$router.push({name: 'MetaverseView'})"
- >
- 工业元宇宙
- <img
- class="decorator"
- src="@/assets/images/nav-item-active-decorator.png"
- alt=""
- draggable="false"
- >
- </button>
- </nav>
- <Teleport to="body">
- <audio
- ref="bgAudio"
- loop
- :src="`${$env.VUE_APP_API_ORIGIN}${bgMusicUrl}`"
- />
- </Teleport>
- <button
- v-show="!$route.meta.hideNavBar && bgMusicUrl"
- class="music-switch"
- :style="{
- backgroundImage: bgMusicStatus ? `url(${require(`@/assets/images/icon_music_2_on.png`)})` : `url(${require(`@/assets/images/icon_music_2_off.png`)})`,
- }"
- @click="onClickBgMusicBtn"
- />
- <Teleport
- to="body"
- >
- <div
- v-show="isShowInfoTooltip"
- ref="infoTooltip"
- class="info-tooltip"
- >
- <p v-show="contactMethod">
- <span class="key">联系方式:</span><span class="value">{{ contactMethod }}</span>
- </p>
- <p v-show="email">
- <span class="key">电子邮箱:</span><span class="value">{{ email }}</span>
- </p>
- <div
- ref="tooltipArrow"
- class="arrow"
- />
- </div>
- </Teleport>
- <button
- v-show="!$route.meta.hideNavBar && (contactMethod || email)"
- ref="infoButton"
- class="info"
- :style="{
- backgroundImage: `url(${require(`@/assets/images/icon_info.png`)})`,
- }"
- @click="onClickInfoButton"
- />
- <button
- v-show="!$route.meta.hideNavBar"
- class="show-hide"
- :style="{
- backgroundImage: isShowNavBar ? `url(${require(`@/assets/images/arrow-down.png`)})` : `url(${require(`@/assets/images/arrow-up.png`)})`,
- }"
- @click="isShowNavBar = !isShowNavBar"
- />
- <Teleport to="body">
- <transition name="fade-out">
- <HomeFadeIn
- v-if="isShowFadeInMask"
- class="fade-in-mask"
- :progress="progress"
- />
- </transition>
- </Teleport>
- <Teleport to="body">
- <div class="screen-rotate-tip">
- <div class="inner-wrapper">
- <img
- class=""
- src="@/assets/images/tip-screen-rotate.png"
- alt=""
- draggable="false"
- >
- <span>请横屏浏览</span>
- </div>
- </div>
- </Teleport>
- </div>
- </template>
- <script>
- import HomeFadeIn from "@/components/HomeFadeIn.vue"
- import {
- computed,
- getCurrentInstance,
- nextTick,
- onMounted,
- reactive,
- ref,
- watch,
- } from 'vue'
- import { useStore } from "vuex"
- import { computePosition, offset, shift, arrow } from '@floating-ui/dom'
- import { onClickOutside } from '@vueuse/core'
- export default {
- components: {
- HomeFadeIn,
- },
- setup () {
- const internalInstance = getCurrentInstance()
- const store = useStore()
- const isShowFadeInMask = ref(true)
- const progress = ref(0)
- onMounted(async () => {
- window.G4AllList = await api.getMetaverseList()
- })
- onMounted(() => {
- /**
- * 加载unity
- */
- window.addEventListener("load", function () {
- if ("serviceWorker" in navigator) {
- navigator.serviceWorker.register("ServiceWorker.js")
- }
- })
- var canvas = document.querySelector("#unity-canvas")
- var buildUrl = "unity/Build"
- var loaderUrl = buildUrl + "/SHIndustryMuseum_2.13.loader.js"
- var config = {
- dataUrl: buildUrl + "/SHIndustryMuseum_2.13.data.unityweb",
- frameworkUrl: buildUrl + "/SHIndustryMuseum_2.13.framework.js.unityweb",
- codeUrl: buildUrl + "/SHIndustryMuseum_2.13.wasm.unityweb",
- streamingAssetsUrl: "StreamingAssets",
- companyName: "DefaultCompany",
- productName: "SHIndustryMuseum",
- productVersion: "0.1",
- }
- // By default Unity keeps WebGL canvas render target size matched with
- // the DOM size of the canvas element (scaled by window.devicePixelRatio)
- // Set this to false if you want to decouple this synchronization from
- // happening inside the engine, and you would instead like to size up
- // the canvas DOM size and WebGL render target sizes yourself.
- // config.matchWebGLToCanvasSize = false;
- if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
- // Mobile device style: fill the whole browser client area with the game canvas:
- var meta = document.createElement('meta')
- meta.name = 'viewport'
- meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes'
- document.getElementsByTagName('head')[0].appendChild(meta)
- }
- var script = document.createElement("script")
- script.src = loaderUrl
- script.onload = () => {
- createUnityInstance(canvas, config, (paramProgress) => {
- progress.value = Math.round(paramProgress * 100)
- if (paramProgress > 0.95) {
- setTimeout(() => {
- isShowFadeInMask.value = false
- }, 1000)
- }
- }).then((unityInstance) => {
- window.gUnityInst = unityInstance
- utils.loadUnitySceneGeneral()
- }).catch((message) => {
- console.error('shabi', message)
- })
- }
- window.onClickEnterprise = function (id) {
- if (window.handleClickEnterprise) {
- window.handleClickEnterprise(id)
- }
- }
- window.onClickPlanet = function (id) {
- if (window.handleClickPlanet) {
- window.handleClickPlanet(id)
- }
- }
- window.onMovedPlanet = function (id) {
- if (window.handleMovedPlanet) {
- window.handleMovedPlanet(id)
- }
- }
- document.body.appendChild(script)
- /**
- * end of unity
- */
- })
- const isShowNavBar = ref(true)
- const activeNavItemIdx = ref(0)
- const navBarHeight = internalInstance.appContext.config.globalProperties.$isMobile ? `${90 / 1080 * window.innerHeight}px` : '90px'
- /**
- * 背景音乐按钮相关
- */
- function onClickBgMusicBtn() {
- store.commit('switchBgMusic')
- }
- const bgMusicStatus = computed(() => {
- return store.state.bgMusicStatus
- })
- const bgAudio = ref(null)
- const bgMusicUrl = computed(() => {
- return store.state.bgMusicUrl
- })
- watch(bgMusicStatus, (v) => {
- if (v) {
- bgAudio.value.play()
- } else {
- bgAudio.value.pause()
- }
- })
- watch(bgMusicUrl, (v) => {
- if (v && bgMusicStatus.value) {
- console.log('sdkfjlsfllsflsfljsdfl')
- nextTick(() => {
- bgAudio.value.play()
- })
- }
- })
- document.addEventListener('click', function onFirstClick() {
- if (bgMusicUrl.value) {
- bgAudio.value.play()
- store.commit('switchBgMusic')
- document.removeEventListener('click', onFirstClick)
- }
- })
- /**
- * 信息展示弹框tooltip相关
- */
- const infoButton = ref(null)
- const infoTooltip = ref(null)
- const tooltipArrow = ref(null)
- const isShowInfoTooltip = ref(false)
- const contactMethod = ref('')
- const email = ref('')
- onMounted(() => {
- api.getSiteInfo().then((res) => {
- contactMethod.value = res.phone
- email.value = res.email
- store.commit('initBgMusicUrl', res.filePath)
- })
- })
- function onClickInfoButton() {
- isShowInfoTooltip.value = true
- nextTick(() => {
- computePosition(infoButton.value, infoTooltip.value, {
- placement: 'top',
- middleware: [
- offset(10),
- shift({
- padding: 10,
- }),
- arrow({
- element: tooltipArrow.value,
- padding: 3,
- }),
- ],
- }).then(({ x, y, placement, middlewareData }) => {
- Object.assign(infoTooltip.value.style, {
- left: `${x}px`,
- top: `${y}px`,
- })
- const { x: arrowX, y: arrowY } = middlewareData.arrow
- const arrowPlacement = {
- top: 'bottom',
- right: 'left',
- bottom: 'top',
- left: 'right',
- }[placement.split('-')[0]]
- const dialogPlacement2arrowRotate = {
- top: '-135deg',
- right: '-45deg',
- bottom: '45deg',
- left: '135deg',
- }
- Object.assign(tooltipArrow.value.style, {
- top: 'initial',
- bottom: 'initial',
- left: 'initial',
- right: 'initial',
- })
- Object.assign(tooltipArrow.value.style, {
- left: arrowX != null ? `${arrowX}px` : '',
- [arrowPlacement]: '0',
- transform: ` translateY(50%) rotate(${dialogPlacement2arrowRotate[placement]})`,
- })
- })
- })
- }
- onClickOutside(infoTooltip, (event) => {
- if (isShowInfoTooltip.value) {
- isShowInfoTooltip.value = false
- }
- })
- return {
- activeNavItemIdx,
- bgAudio,
- bgMusicUrl,
- bgMusicStatus,
- contactMethod,
- email,
- infoButton,
- infoTooltip,
- isShowFadeInMask,
- isShowInfoTooltip,
- isShowNavBar,
- navBarHeight,
- onClickBgMusicBtn,
- onClickInfoButton,
- progress,
- tooltipArrow,
- }
- },
- }
- </script>
- <style lang="less">
- html, body {
- // overscroll-behavior: none;
- // overflow: hidden;
- height: 100%;
- }
- #app {
- height: 100%;
- width: 100%;
- background-image: url(@/assets/images/main-bg.jpg);
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- }
- // * {
- // user-select: none;
- // -webkit-touch-callout: none;
- // }
- // // 360浏览器不支持not()
- // input, textarea {
- // user-select: initial;
- // }
- // 字体
- @font-face {
- font-family: 'Source Han Sans CN-Light';
- src: url('@/assets/style/SOURCEHANSANSCN-LIGHT.OTF');
- }
- @font-face {
- font-family: 'Source Han Sans CN-Regular';
- src: url('@/assets/style/SOURCEHANSANSCN-REGULAR.OTF');
- }
- @font-face {
- font-family: 'Source Han Sans CN';
- src: url('@/assets/style/SOURCEHANSANSCN-REGULAR.OTF');
- }
- @font-face {
- font-family: 'Source Han Sans CN-Bold';
- src: url('@/assets/style/SOURCEHANSANSCN-BOLD.OTF');
- }
- // i {
- // font-style: italic;
- // }
- // 滚动条
- // ::-webkit-scrollbar { background: #dddecc; width: 0.3rem; height: 0.3rem; } /*宽度是对垂直滚动条而言,高度是对水平滚动条而言*/
- // ::-webkit-scrollbar-thumb { background: #828a5b; border-radius: 0.15rem; }
- // ::-webkit-scrollbar-corner { background: #dddecc; }
- // vue组件过渡效果
- .fade-out-leave-active {
- transition: opacity 1s;
- }
- .fade-out-leave-to {
- opacity: 0;
- }
- // 不断渐变显隐 animation
- .animation-show-hide {
- animation: show-hide 1.8s infinite;
- }
- @keyframes show-hide {
- 0% {
- opacity: 0;
- }
- 50% {
- opacity: 1;
- }
- 100% {
- opacity: 0;
- }
- }
- // // vue-viewer
- // .viewer-container {
- // background-color: rgba(0, 0, 0, 80%) !important;
- // }
- // 或者
- // .viewer-backdrop {
- // background-color: rgba(0, 0, 0, 90%) !important;
- // }
- .info-tooltip {
- position: absolute;
- padding: 8px;
- z-index: 50;
- background: rgba(32,52,75,0.3);
- box-shadow: inset 1px 0px 1px 0px rgba(255,236,188,0.5);
- backdrop-filter: blur(10px);
- padding: 8px;
- font-size: 11px;
- font-family: Source Han Sans CN-Regular, Source Han Sans CN;
- font-weight: 400;
- color: #FFFFFF;
- line-height: 1.5;
- white-space: pre;
- opacity: 0.8;
- >p{
- >.key{
- }
- >.value{
- }
- }
- >.arrow {
- position: absolute;
- background-color: inherit;
- width: 10px;
- height: 10px;
- border: 1px solid transparent;
- border-left: inherit;
- border-top: inherit;
- }
- }
- .screen-rotate-tip {
- position: fixed;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.8);
- display: none;
- z-index: 100;
- @media (max-aspect-ratio: 1/1) {
- display: initial;
- }
- >.inner-wrapper {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- width: 126px;
- height: 126px;
- >img {
- width: 100%;
- height: 100%;
- }
- >span {
- position: absolute;
- left: 50%;
- bottom: -8px;
- transform: translate(-50%, 100%);
- font-size: 16px;
- font-family: Source Han Sans-Regular, Source Han Sans;
- font-weight: 400;
- color: #FFFFFF;
- white-space: pre;
- }
- }
- }
- </style>
- <style scoped lang="less">
- .app-view {
- width: 100%;
- height: calc(100% - v-bind('navBarHeight'));
- position: relative;
- &.higher {
- height: 100%;
- }
- >#unity-container {
- position: absolute;
- width: 100%;
- height: 100%;
- >#unity-canvas {
- height: 100%;
- width: 100%;
- background: #231F20;
- }
- }
- >nav {
- position: fixed;
- left: 0;
- width: 100%;
- height: v-bind('navBarHeight');
- border-radius: 5px 5px 0 0;
- border-top: rgba(210, 189, 132, 0.7);
- box-shadow: inset 0px 2px 2px 0px rgba(210,189,132,0.45), 0px -9px 24px 0px rgba(183,162,109,0.25);
- display: flex;
- justify-content: center;
- align-items: center;
- transition: all 0.5s;
- // backdrop-filter: blur(10px);
- background-image: url(@/assets/images/bg-bottom-bar.jpg);
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- // background-color: #0c0d12;
- >button.tab-item {
- font-size: 30px;
- font-family: Source Han Sans CN-Regular, Source Han Sans CN;
- font-weight: 400;
- color: #FFFFFF;
- margin-left: 200px;
- opacity: 0.5;
- position: relative;
- user-select: none;
- >img.decorator {
- display: none;
- }
- &:first-of-type {
- margin-left: initial;
- }
- &.active {
- opacity: initial;
- font-weight: bold;
- >img.decorator {
- display: initial;
- position: absolute;
- left: 50%;
- bottom: -15px;
- transform: translateX(-50%);
- width: 150%;
- }
- }
- }
- @media only screen and (max-width: 1400px) {
- >button.tab-item {
- margin-left: 100px;
- }
- }
- }
- >button.music-switch {
- position: fixed;
- right: calc(82px + (36px + 30px) * 2);
- bottom: 28px;
- width: 36px;
- height: 36px;
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- }
- @media only screen and (max-width: 1670px) {
- >button.music-switch {
- right: calc(10px + (36px + 10px) * 2);
- }
- }
- >button.info {
- position: fixed;
- right: calc(82px + (36px + 30px) * 1);
- bottom: 28px;
- width: 36px;
- height: 36px;
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- }
- @media only screen and (max-width: 1670px) {
- >button.info {
- right: calc(10px + (36px + 10px) * 1);
- }
- }
- >button.show-hide {
- position: fixed;
- right: 82px;
- bottom: 28px;
- width: 36px;
- height: 36px;
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- }
- @media only screen and (max-width: 1670px) {
- >button.show-hide {
- right: 10px;
- }
- }
- }
- .mobile {
- .app-view {
- width: 100%;
- height: calc(100% - v-bind('navBarHeight'));
- position: relative;
- &.higher {
- height: 100%;
- }
- >.fade-in-mask {
- z-index: 2005;
- }
- >#unity-container {
- position: absolute;
- width: 100%;
- height: 100%;
- >#unity-canvas {
- height: 100%;
- width: 100%;
- background: #231F20;
- }
- }
- >nav {
- position: fixed;
- left: 0;
- width: 100%;
- height: v-bind('navBarHeight');
- border-radius: 5px 5px 0 0;
- border-top: rgba(210, 189, 132, 0.7);
- box-shadow: inset 0px 2px 2px 0px rgba(210,189,132,0.45), 0px -9px 24px 0px rgba(183,162,109,0.25);
- display: flex;
- justify-content: center;
- align-items: center;
- transition: all 0.5s;
- // backdrop-filter: blur(10px);
- background-image: url(@/assets/images/bg-bottom-bar.jpg);
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- // background-color: #0c0d12;
- >button.tab-item {
- font-size: calc(30 / 1080 * 83vh);
- font-family: Source Han Sans CN-Regular, Source Han Sans CN;
- font-weight: 400;
- color: #FFFFFF;
- margin-left: calc(200 / 1080 * 83vh);
- opacity: 0.5;
- position: relative;
- user-select: none;
- >img.decorator {
- display: none;
- }
- &:first-of-type {
- margin-left: initial;
- }
- &.active {
- opacity: initial;
- font-weight: bold;
- >img.decorator {
- display: none;
- // display: initial;
- // position: absolute;
- // left: 50%;
- // bottom: -calc(15 / 1080 * 83vh);
- // transform: translateX(-50%);
- // width: 150%;
- }
- }
- }
- }
- >button.music-switch {
- position: fixed;
- right: calc((82 + (36 + 80) * 2) / 1080 * 83vh);
- bottom: calc(28 / 1080 * 83vh);
- width: calc(36 / 1080 * 83vh);
- height: calc(36 / 1080 * 83vh);
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- }
- >button.info {
- position: fixed;
- right: calc((82 + (36 + 80) * 1) / 1080 * 83vh);
- bottom: calc(28 / 1080 * 83vh);
- width: calc(36 / 1080 * 83vh);
- height: calc(36 / 1080 * 83vh);
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- }
- >button.show-hide {
- position: fixed;
- right: calc(82 / 1080 * 83vh);
- bottom: calc(28 / 1080 * 83vh);
- width: calc(36 / 1080 * 83vh);
- height: calc(36 / 1080 * 83vh);
- background-size: cover;
- background-repeat: no-repeat;
- background-position: center center;
- }
- }
- }
- </style>
|