App.vue 20 KB

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