App.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. <template>
  2. <div
  3. class="app-view"
  4. :class="{
  5. higher: !isShowNavBar,
  6. }"
  7. >
  8. <div
  9. v-show="$route.meta.isShowUnityModel"
  10. id="unity-container"
  11. >
  12. <canvas
  13. id="unity-canvas"
  14. width="960"
  15. height="600"
  16. tabindex="-1"
  17. />
  18. </div>
  19. <router-view />
  20. <nav
  21. v-show="!$route.meta.hideNavBar"
  22. :style="{
  23. bottom: isShowNavBar ? '0' : `-${navBarHeight}`,
  24. }"
  25. >
  26. <button
  27. class="tab-item"
  28. :class="{
  29. active: $route.meta.belongNavGroup === 0
  30. }"
  31. @click="$router.push({name: 'GeneralView'})"
  32. >
  33. 概述总览
  34. <img
  35. class="decorator"
  36. src="@/assets/images/nav-item-active-decorator.png"
  37. alt=""
  38. draggable="false"
  39. >
  40. </button>
  41. <button
  42. class="tab-item"
  43. :class="{
  44. active: $route.meta.belongNavGroup === 1
  45. }"
  46. @click="$router.push({name: 'HistoryView'})"
  47. >
  48. 历史回顾
  49. <img
  50. class="decorator"
  51. src="@/assets/images/nav-item-active-decorator.png"
  52. alt=""
  53. draggable="false"
  54. >
  55. </button>
  56. <button
  57. class="tab-item"
  58. :class="{
  59. active: $route.meta.belongNavGroup === 2
  60. }"
  61. @click="$router.push({name: 'TreasureView'})"
  62. >
  63. 国之重器
  64. <img
  65. class="decorator"
  66. src="@/assets/images/nav-item-active-decorator.png"
  67. alt=""
  68. draggable="false"
  69. >
  70. </button>
  71. <button
  72. class="tab-item"
  73. :class="{
  74. active: $route.meta.belongNavGroup === 3
  75. }"
  76. @click="$router.push({name: 'MetaverseView'})"
  77. >
  78. 工业元宇宙
  79. <img
  80. class="decorator"
  81. src="@/assets/images/nav-item-active-decorator.png"
  82. alt=""
  83. draggable="false"
  84. >
  85. </button>
  86. </nav>
  87. <Teleport to="body">
  88. <audio
  89. ref="bgAudio"
  90. loop
  91. :src="`${$env.VUE_APP_API_ORIGIN}${bgMusicUrl}`"
  92. />
  93. </Teleport>
  94. <button
  95. v-show="!$route.meta.hideNavBar && bgMusicUrl"
  96. class="music-switch"
  97. :style="{
  98. backgroundImage: bgMusicStatus ? `url(${require(`@/assets/images/icon_music_2_on.png`)})` : `url(${require(`@/assets/images/icon_music_2_off.png`)})`,
  99. }"
  100. @click="onClickBgMusicBtn"
  101. />
  102. <Teleport
  103. to="body"
  104. >
  105. <div
  106. v-show="isShowInfoTooltip"
  107. ref="infoTooltip"
  108. class="info-tooltip"
  109. >
  110. <p v-show="contactMethod">
  111. <span class="key">联系方式:</span><span class="value">{{ contactMethod }}</span>
  112. </p>
  113. <p v-show="email">
  114. <span class="key">电子邮箱:</span><span class="value">{{ email }}</span>
  115. </p>
  116. <div
  117. ref="tooltipArrow"
  118. class="arrow"
  119. />
  120. </div>
  121. </Teleport>
  122. <button
  123. v-show="!$route.meta.hideNavBar && (contactMethod || email)"
  124. ref="infoButton"
  125. class="info"
  126. :style="{
  127. backgroundImage: `url(${require(`@/assets/images/icon_info.png`)})`,
  128. }"
  129. @click="onClickInfoButton"
  130. />
  131. <button
  132. v-show="!$route.meta.hideNavBar"
  133. class="show-hide"
  134. :style="{
  135. backgroundImage: isShowNavBar ? `url(${require(`@/assets/images/arrow-down.png`)})` : `url(${require(`@/assets/images/arrow-up.png`)})`,
  136. }"
  137. @click="isShowNavBar = !isShowNavBar"
  138. />
  139. <Teleport to="body">
  140. <transition name="fade-out">
  141. <HomeFadeIn
  142. v-if="isShowFadeInMask"
  143. class="fade-in-mask"
  144. :progress="progress"
  145. />
  146. </transition>
  147. </Teleport>
  148. <Teleport to="body">
  149. <div class="screen-rotate-tip">
  150. <div class="inner-wrapper">
  151. <img
  152. class=""
  153. src="@/assets/images/tip-screen-rotate.png"
  154. alt=""
  155. draggable="false"
  156. >
  157. <span>请横屏浏览</span>
  158. </div>
  159. </div>
  160. </Teleport>
  161. </div>
  162. </template>
  163. <script>
  164. import HomeFadeIn from "@/components/HomeFadeIn.vue"
  165. import {
  166. computed,
  167. getCurrentInstance,
  168. nextTick,
  169. onMounted,
  170. reactive,
  171. ref,
  172. watch,
  173. } from 'vue'
  174. import { useStore } from "vuex"
  175. import { computePosition, offset, shift, arrow } from '@floating-ui/dom'
  176. import { onClickOutside } from '@vueuse/core'
  177. export default {
  178. components: {
  179. HomeFadeIn,
  180. },
  181. setup () {
  182. const internalInstance = getCurrentInstance()
  183. const store = useStore()
  184. const isShowFadeInMask = ref(true)
  185. const progress = ref(0)
  186. onMounted(async () => {
  187. window.G4AllList = await api.getMetaverseList()
  188. })
  189. onMounted(() => {
  190. /**
  191. * 加载unity
  192. */
  193. window.addEventListener("load", function () {
  194. if ("serviceWorker" in navigator) {
  195. navigator.serviceWorker.register("ServiceWorker.js")
  196. }
  197. })
  198. var canvas = document.querySelector("#unity-canvas")
  199. var buildUrl = "unity/Build"
  200. var loaderUrl = buildUrl + "/SHIndustryMuseum_2.13.loader.js"
  201. var config = {
  202. dataUrl: buildUrl + "/SHIndustryMuseum_2.13.data.unityweb",
  203. frameworkUrl: buildUrl + "/SHIndustryMuseum_2.13.framework.js.unityweb",
  204. codeUrl: buildUrl + "/SHIndustryMuseum_2.13.wasm.unityweb",
  205. streamingAssetsUrl: "StreamingAssets",
  206. companyName: "DefaultCompany",
  207. productName: "SHIndustryMuseum",
  208. productVersion: "0.1",
  209. }
  210. // By default Unity keeps WebGL canvas render target size matched with
  211. // the DOM size of the canvas element (scaled by window.devicePixelRatio)
  212. // Set this to false if you want to decouple this synchronization from
  213. // happening inside the engine, and you would instead like to size up
  214. // the canvas DOM size and WebGL render target sizes yourself.
  215. // config.matchWebGLToCanvasSize = false;
  216. if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
  217. // Mobile device style: fill the whole browser client area with the game canvas:
  218. var meta = document.createElement('meta')
  219. meta.name = 'viewport'
  220. meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes'
  221. document.getElementsByTagName('head')[0].appendChild(meta)
  222. }
  223. var script = document.createElement("script")
  224. script.src = loaderUrl
  225. script.onload = () => {
  226. createUnityInstance(canvas, config, (paramProgress) => {
  227. progress.value = Math.round(paramProgress * 100)
  228. if (paramProgress > 0.95) {
  229. setTimeout(() => {
  230. isShowFadeInMask.value = false
  231. }, 1000)
  232. }
  233. }).then((unityInstance) => {
  234. window.gUnityInst = unityInstance
  235. utils.loadUnitySceneGeneral()
  236. }).catch((message) => {
  237. console.error('shabi', message)
  238. })
  239. }
  240. window.onClickEnterprise = function (id) {
  241. if (window.handleClickEnterprise) {
  242. window.handleClickEnterprise(id)
  243. }
  244. }
  245. window.onClickPlanet = function (id) {
  246. if (window.handleClickPlanet) {
  247. window.handleClickPlanet(id)
  248. }
  249. }
  250. window.onMovedPlanet = function (id) {
  251. if (window.handleMovedPlanet) {
  252. window.handleMovedPlanet(id)
  253. }
  254. }
  255. document.body.appendChild(script)
  256. /**
  257. * end of unity
  258. */
  259. })
  260. const isShowNavBar = ref(true)
  261. const activeNavItemIdx = ref(0)
  262. const navBarHeight = internalInstance.appContext.config.globalProperties.$isMobile ? `${90 / 1080 * window.innerHeight}px` : '90px'
  263. /**
  264. * 背景音乐按钮相关
  265. */
  266. function onClickBgMusicBtn() {
  267. store.commit('switchBgMusic')
  268. }
  269. const bgMusicStatus = computed(() => {
  270. return store.state.bgMusicStatus
  271. })
  272. const bgAudio = ref(null)
  273. const bgMusicUrl = computed(() => {
  274. return store.state.bgMusicUrl
  275. })
  276. watch(bgMusicStatus, (v) => {
  277. if (v) {
  278. bgAudio.value.play()
  279. } else {
  280. bgAudio.value.pause()
  281. }
  282. })
  283. watch(bgMusicUrl, (v) => {
  284. if (v && bgMusicStatus.value) {
  285. console.log('sdkfjlsfllsflsfljsdfl')
  286. nextTick(() => {
  287. bgAudio.value.play()
  288. })
  289. }
  290. })
  291. document.addEventListener('click', function onFirstClick() {
  292. if (bgMusicUrl.value) {
  293. bgAudio.value.play()
  294. store.commit('switchBgMusic')
  295. document.removeEventListener('click', onFirstClick)
  296. }
  297. })
  298. /**
  299. * 信息展示弹框tooltip相关
  300. */
  301. const infoButton = ref(null)
  302. const infoTooltip = ref(null)
  303. const tooltipArrow = ref(null)
  304. const isShowInfoTooltip = ref(false)
  305. const contactMethod = ref('')
  306. const email = ref('')
  307. onMounted(() => {
  308. api.getSiteInfo().then((res) => {
  309. contactMethod.value = res.phone
  310. email.value = res.email
  311. store.commit('initBgMusicUrl', res.filePath)
  312. })
  313. })
  314. function onClickInfoButton() {
  315. isShowInfoTooltip.value = true
  316. nextTick(() => {
  317. computePosition(infoButton.value, infoTooltip.value, {
  318. placement: 'top',
  319. middleware: [
  320. offset(10),
  321. shift({
  322. padding: 10,
  323. }),
  324. arrow({
  325. element: tooltipArrow.value,
  326. padding: 3,
  327. }),
  328. ],
  329. }).then(({ x, y, placement, middlewareData }) => {
  330. Object.assign(infoTooltip.value.style, {
  331. left: `${x}px`,
  332. top: `${y}px`,
  333. })
  334. const { x: arrowX, y: arrowY } = middlewareData.arrow
  335. const arrowPlacement = {
  336. top: 'bottom',
  337. right: 'left',
  338. bottom: 'top',
  339. left: 'right',
  340. }[placement.split('-')[0]]
  341. const dialogPlacement2arrowRotate = {
  342. top: '-135deg',
  343. right: '-45deg',
  344. bottom: '45deg',
  345. left: '135deg',
  346. }
  347. Object.assign(tooltipArrow.value.style, {
  348. top: 'initial',
  349. bottom: 'initial',
  350. left: 'initial',
  351. right: 'initial',
  352. })
  353. Object.assign(tooltipArrow.value.style, {
  354. left: arrowX != null ? `${arrowX}px` : '',
  355. [arrowPlacement]: '0',
  356. transform: ` translateY(50%) rotate(${dialogPlacement2arrowRotate[placement]})`,
  357. })
  358. })
  359. })
  360. }
  361. onClickOutside(infoTooltip, (event) => {
  362. if (isShowInfoTooltip.value) {
  363. isShowInfoTooltip.value = false
  364. }
  365. })
  366. return {
  367. activeNavItemIdx,
  368. bgAudio,
  369. bgMusicUrl,
  370. bgMusicStatus,
  371. contactMethod,
  372. email,
  373. infoButton,
  374. infoTooltip,
  375. isShowFadeInMask,
  376. isShowInfoTooltip,
  377. isShowNavBar,
  378. navBarHeight,
  379. onClickBgMusicBtn,
  380. onClickInfoButton,
  381. progress,
  382. tooltipArrow,
  383. }
  384. },
  385. }
  386. </script>
  387. <style lang="less">
  388. html, body {
  389. // overscroll-behavior: none;
  390. // overflow: hidden;
  391. height: 100%;
  392. }
  393. #app {
  394. height: 100%;
  395. width: 100%;
  396. background-image: url(@/assets/images/main-bg.jpg);
  397. background-size: cover;
  398. background-repeat: no-repeat;
  399. background-position: center center;
  400. }
  401. // * {
  402. // user-select: none;
  403. // -webkit-touch-callout: none;
  404. // }
  405. // // 360浏览器不支持not()
  406. // input, textarea {
  407. // user-select: initial;
  408. // }
  409. // 字体
  410. @font-face {
  411. font-family: 'Source Han Sans CN-Light';
  412. src: url('@/assets/style/SOURCEHANSANSCN-LIGHT.OTF');
  413. }
  414. @font-face {
  415. font-family: 'Source Han Sans CN-Regular';
  416. src: url('@/assets/style/SOURCEHANSANSCN-REGULAR.OTF');
  417. }
  418. @font-face {
  419. font-family: 'Source Han Sans CN';
  420. src: url('@/assets/style/SOURCEHANSANSCN-REGULAR.OTF');
  421. }
  422. @font-face {
  423. font-family: 'Source Han Sans CN-Bold';
  424. src: url('@/assets/style/SOURCEHANSANSCN-BOLD.OTF');
  425. }
  426. // i {
  427. // font-style: italic;
  428. // }
  429. // 滚动条
  430. // ::-webkit-scrollbar { background: #dddecc; width: 0.3rem; height: 0.3rem; } /*宽度是对垂直滚动条而言,高度是对水平滚动条而言*/
  431. // ::-webkit-scrollbar-thumb { background: #828a5b; border-radius: 0.15rem; }
  432. // ::-webkit-scrollbar-corner { background: #dddecc; }
  433. // vue组件过渡效果
  434. .fade-out-leave-active {
  435. transition: opacity 1s;
  436. }
  437. .fade-out-leave-to {
  438. opacity: 0;
  439. }
  440. // 不断渐变显隐 animation
  441. .animation-show-hide {
  442. animation: show-hide 1.8s infinite;
  443. }
  444. @keyframes show-hide {
  445. 0% {
  446. opacity: 0;
  447. }
  448. 50% {
  449. opacity: 1;
  450. }
  451. 100% {
  452. opacity: 0;
  453. }
  454. }
  455. // // vue-viewer
  456. // .viewer-container {
  457. // background-color: rgba(0, 0, 0, 80%) !important;
  458. // }
  459. // 或者
  460. // .viewer-backdrop {
  461. // background-color: rgba(0, 0, 0, 90%) !important;
  462. // }
  463. .info-tooltip {
  464. position: absolute;
  465. padding: 8px;
  466. z-index: 50;
  467. background: rgba(32,52,75,0.3);
  468. box-shadow: inset 1px 0px 1px 0px rgba(255,236,188,0.5);
  469. backdrop-filter: blur(10px);
  470. padding: 8px;
  471. font-size: 11px;
  472. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  473. font-weight: 400;
  474. color: #FFFFFF;
  475. line-height: 1.5;
  476. white-space: pre;
  477. opacity: 0.8;
  478. >p{
  479. >.key{
  480. }
  481. >.value{
  482. }
  483. }
  484. >.arrow {
  485. position: absolute;
  486. background-color: inherit;
  487. width: 10px;
  488. height: 10px;
  489. border: 1px solid transparent;
  490. border-left: inherit;
  491. border-top: inherit;
  492. }
  493. }
  494. .screen-rotate-tip {
  495. position: fixed;
  496. left: 0;
  497. top: 0;
  498. width: 100%;
  499. height: 100%;
  500. background: rgba(0, 0, 0, 0.8);
  501. display: none;
  502. z-index: 100;
  503. @media (max-aspect-ratio: 1/1) {
  504. display: initial;
  505. }
  506. >.inner-wrapper {
  507. position: absolute;
  508. left: 50%;
  509. top: 50%;
  510. transform: translate(-50%, -50%);
  511. width: 126px;
  512. height: 126px;
  513. >img {
  514. width: 100%;
  515. height: 100%;
  516. }
  517. >span {
  518. position: absolute;
  519. left: 50%;
  520. bottom: -8px;
  521. transform: translate(-50%, 100%);
  522. font-size: 16px;
  523. font-family: Source Han Sans-Regular, Source Han Sans;
  524. font-weight: 400;
  525. color: #FFFFFF;
  526. white-space: pre;
  527. }
  528. }
  529. }
  530. </style>
  531. <style scoped lang="less">
  532. .app-view {
  533. width: 100%;
  534. height: calc(100% - v-bind('navBarHeight'));
  535. position: relative;
  536. &.higher {
  537. height: 100%;
  538. }
  539. >#unity-container {
  540. position: absolute;
  541. width: 100%;
  542. height: 100%;
  543. >#unity-canvas {
  544. height: 100%;
  545. width: 100%;
  546. background: #231F20;
  547. }
  548. }
  549. >nav {
  550. position: fixed;
  551. left: 0;
  552. width: 100%;
  553. height: v-bind('navBarHeight');
  554. border-radius: 5px 5px 0 0;
  555. border-top: rgba(210, 189, 132, 0.7);
  556. box-shadow: inset 0px 2px 2px 0px rgba(210,189,132,0.45), 0px -9px 24px 0px rgba(183,162,109,0.25);
  557. display: flex;
  558. justify-content: center;
  559. align-items: center;
  560. transition: all 0.5s;
  561. // backdrop-filter: blur(10px);
  562. background-image: url(@/assets/images/bg-bottom-bar.jpg);
  563. background-size: cover;
  564. background-repeat: no-repeat;
  565. background-position: center center;
  566. // background-color: #0c0d12;
  567. >button.tab-item {
  568. font-size: 30px;
  569. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  570. font-weight: 400;
  571. color: #FFFFFF;
  572. margin-left: 200px;
  573. opacity: 0.5;
  574. position: relative;
  575. user-select: none;
  576. >img.decorator {
  577. display: none;
  578. }
  579. &:first-of-type {
  580. margin-left: initial;
  581. }
  582. &.active {
  583. opacity: initial;
  584. font-weight: bold;
  585. >img.decorator {
  586. display: initial;
  587. position: absolute;
  588. left: 50%;
  589. bottom: -15px;
  590. transform: translateX(-50%);
  591. width: 150%;
  592. }
  593. }
  594. }
  595. @media only screen and (max-width: 1400px) {
  596. >button.tab-item {
  597. margin-left: 100px;
  598. }
  599. }
  600. }
  601. >button.music-switch {
  602. position: fixed;
  603. right: calc(82px + (36px + 30px) * 2);
  604. bottom: 28px;
  605. width: 36px;
  606. height: 36px;
  607. background-size: cover;
  608. background-repeat: no-repeat;
  609. background-position: center center;
  610. }
  611. @media only screen and (max-width: 1670px) {
  612. >button.music-switch {
  613. right: calc(10px + (36px + 10px) * 2);
  614. }
  615. }
  616. >button.info {
  617. position: fixed;
  618. right: calc(82px + (36px + 30px) * 1);
  619. bottom: 28px;
  620. width: 36px;
  621. height: 36px;
  622. background-size: cover;
  623. background-repeat: no-repeat;
  624. background-position: center center;
  625. }
  626. @media only screen and (max-width: 1670px) {
  627. >button.info {
  628. right: calc(10px + (36px + 10px) * 1);
  629. }
  630. }
  631. >button.show-hide {
  632. position: fixed;
  633. right: 82px;
  634. bottom: 28px;
  635. width: 36px;
  636. height: 36px;
  637. background-size: cover;
  638. background-repeat: no-repeat;
  639. background-position: center center;
  640. }
  641. @media only screen and (max-width: 1670px) {
  642. >button.show-hide {
  643. right: 10px;
  644. }
  645. }
  646. }
  647. .mobile {
  648. .app-view {
  649. width: 100%;
  650. height: calc(100% - v-bind('navBarHeight'));
  651. position: relative;
  652. &.higher {
  653. height: 100%;
  654. }
  655. >.fade-in-mask {
  656. z-index: 2005;
  657. }
  658. >#unity-container {
  659. position: absolute;
  660. width: 100%;
  661. height: 100%;
  662. >#unity-canvas {
  663. height: 100%;
  664. width: 100%;
  665. background: #231F20;
  666. }
  667. }
  668. >nav {
  669. position: fixed;
  670. left: 0;
  671. width: 100%;
  672. height: v-bind('navBarHeight');
  673. border-radius: 5px 5px 0 0;
  674. border-top: rgba(210, 189, 132, 0.7);
  675. box-shadow: inset 0px 2px 2px 0px rgba(210,189,132,0.45), 0px -9px 24px 0px rgba(183,162,109,0.25);
  676. display: flex;
  677. justify-content: center;
  678. align-items: center;
  679. transition: all 0.5s;
  680. // backdrop-filter: blur(10px);
  681. background-image: url(@/assets/images/bg-bottom-bar.jpg);
  682. background-size: cover;
  683. background-repeat: no-repeat;
  684. background-position: center center;
  685. // background-color: #0c0d12;
  686. >button.tab-item {
  687. font-size: calc(30 / 1080 * 83vh);
  688. font-family: Source Han Sans CN-Regular, Source Han Sans CN;
  689. font-weight: 400;
  690. color: #FFFFFF;
  691. margin-left: calc(200 / 1080 * 83vh);
  692. opacity: 0.5;
  693. position: relative;
  694. user-select: none;
  695. >img.decorator {
  696. display: none;
  697. }
  698. &:first-of-type {
  699. margin-left: initial;
  700. }
  701. &.active {
  702. opacity: initial;
  703. font-weight: bold;
  704. >img.decorator {
  705. display: none;
  706. // display: initial;
  707. // position: absolute;
  708. // left: 50%;
  709. // bottom: -calc(15 / 1080 * 83vh);
  710. // transform: translateX(-50%);
  711. // width: 150%;
  712. }
  713. }
  714. }
  715. }
  716. >button.music-switch {
  717. position: fixed;
  718. right: calc((82 + (36 + 80) * 2) / 1080 * 83vh);
  719. bottom: calc(28 / 1080 * 83vh);
  720. width: calc(36 / 1080 * 83vh);
  721. height: calc(36 / 1080 * 83vh);
  722. background-size: cover;
  723. background-repeat: no-repeat;
  724. background-position: center center;
  725. }
  726. >button.info {
  727. position: fixed;
  728. right: calc((82 + (36 + 80) * 1) / 1080 * 83vh);
  729. bottom: calc(28 / 1080 * 83vh);
  730. width: calc(36 / 1080 * 83vh);
  731. height: calc(36 / 1080 * 83vh);
  732. background-size: cover;
  733. background-repeat: no-repeat;
  734. background-position: center center;
  735. }
  736. >button.show-hide {
  737. position: fixed;
  738. right: calc(82 / 1080 * 83vh);
  739. bottom: calc(28 / 1080 * 83vh);
  740. width: calc(36 / 1080 * 83vh);
  741. height: calc(36 / 1080 * 83vh);
  742. background-size: cover;
  743. background-repeat: no-repeat;
  744. background-position: center center;
  745. }
  746. }
  747. }
  748. </style>