detailPage.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. <script setup lang='ts'>
  2. import { useStore } from '@/stores';
  3. import { baseURl } from '@/utils/https';
  4. const router = useRouter()
  5. const store = useStore()
  6. // info-简介 construction-结构 scene-场景
  7. const curMoudle = ref('')
  8. const curInfoPart = ref({} as any)
  9. const curSelect = ref({} as any)
  10. const curMode = ref({} as any)
  11. const isShowGuide = ref(false)
  12. const goScenefu = () => {
  13. store.mode = curMode.value;
  14. store.currentInfoPart = curInfoPart.value;
  15. console.log(curInfoPart.value)
  16. router.push({
  17. path: '/scene',
  18. query: {
  19. code: curInfoPart.value.sceneCode
  20. }
  21. })
  22. }
  23. const isMobile = ref(false)
  24. const isMobileDevice = () => {
  25. const mobileRegex = /Mobi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
  26. return mobileRegex.test(navigator.userAgent);
  27. }
  28. const time =ref()
  29. onMounted(() => {
  30. if (Object.keys(store.currentInfoPart).length != 0) {
  31. curInfoPart.value = store.currentInfoPart
  32. }
  33. curMoudle.value = 'construction'
  34. curMode.value = store.dataAll.modeList[0]
  35. isMobile.value = isMobileDevice()
  36. // 重新获取高度
  37. // @ts-ignore
  38. time.current = window.setTimeout(() => {
  39. // 根元素
  40. const dom: HTMLDivElement | null = document.querySelector("#app");
  41. if (dom && document.documentElement.clientWidth < 1000) {
  42. dom.style.height = document.documentElement.clientHeight + "px";
  43. dom.style.width = document.documentElement.clientWidth + "px";
  44. }
  45. }, 100);
  46. })
  47. </script>
  48. <template>
  49. <div class='detail-page'
  50. :style="{ backgroundImage: Object.keys(curMode).length === 0 ? '' : `url(${baseURl}/${curMode.name}/${Object.keys(curSelect).length > 0 ? curSelect.id + '.png' : curMode.mainBody})` }">
  51. <!-- 功能区 -->
  52. <div class="logo-welcome" v-if="false">
  53. <div class="item" @click="curMoudle = 'info'">
  54. <div>{{ store.dataAll.info.name }}</div>
  55. <img :style="{ opacity: curMoudle == 'info' ? '1' : '' }" src="@/assets/images/begin-select.png" alt="">
  56. </div>
  57. <div class="item" @click="() => { curMoudle = 'construction', curMode = store.dataAll.modeList[0] }">
  58. <div>结构</div>
  59. <img :style="{ opacity: curMoudle == 'construction' ? '1' : '' }" src="@/assets/images/begin-select.png" alt="">
  60. </div>
  61. <div class="item" @click="() => {
  62. router.push('/scene')
  63. }">
  64. <div>场景</div>
  65. <img :style="{ opacity: curMoudle == 'scene' ? '1' : '' }" src="@/assets/images/begin-select.png" alt="">
  66. </div>
  67. </div>
  68. <!-- 简介弹框 -->
  69. <div class="info-box" v-show="curMoudle == 'info'">
  70. <img src="@/assets/images/close.png" @click="curMoudle = ''" alt="">
  71. <div class="title">{{ store.dataAll.info.content.title }}</div>
  72. <div class="disc">{{ store.dataAll.info.content.disc }}</div>
  73. </div>
  74. <!-- 结构相关样式 -->
  75. <div v-show="curMoudle == 'construction'" class="construction-box">
  76. <!-- 地图 -->
  77. <img class="img-map" src="@/assets/images/map.png" alt="">
  78. <!-- 左侧刻度 -->
  79. <img class="img-left" src="@/assets/images/left.png" alt="">
  80. <!-- 右侧刻度 -->
  81. <img class="img-right" src="@/assets/images/right.png" alt="">
  82. <!-- 底部渐变 -->
  83. <img class="img-bottom" src="@/assets/images/bottom.png" alt="">
  84. <!-- 船体列表 -->
  85. <div class="list-box"
  86. :style="{ backgroundImage: curSelect.name == '顶甲板' && !isMobile ? `url(${baseURl}/selectEnd.png)` : curSelect.name == '救生艇' && !isMobile ? `url(${baseURl}/selectLast.png)` : '' }">
  87. <div class="stereoscopic-box"
  88. @click="() => { curSelect = {}, curMode = store.dataAll.modeList[0], curInfoPart = {}, isShowGuide = false }">
  89. {{ store.dataAll.modeList[0].title }}
  90. </div>
  91. <div class="list-bottom">
  92. <!-- <img class="topAc" src="@/assets/images/topAc.png" alt="">
  93. <img class="bottomAc" src="@/assets/images/bottomAc.png" alt=""> -->
  94. <div class="list-item" :class="{ 'active': item.name == curSelect.name }"
  95. @click="() => { index === store.dataAll.modeList[1].content.length - 1 ? (curInfoPart = item, goScenefu()) : (curSelect = item, curMode = store.dataAll.modeList[1], curInfoPart = item, isShowGuide = true) }"
  96. v-for="(item, index) in store.dataAll.modeList[1].content" :key="item.id"
  97. :style="{ borderBottom: index == store.dataAll.modeList[1].content.length - 1 ? 'none' : '', background: (index == store.dataAll.modeList[1].content.length - 1 || index == 0) && !isMobile ? 'none' : '' }">
  98. {{ item.number + item.name }}
  99. </div>
  100. </div>
  101. <img v-show="isMobile" class="down-line" src="@/assets/images/down-line.png" alt="">
  102. </div>
  103. <!-- 信息框 -->
  104. <div class="info-box-detail" v-show="Object.keys(curSelect).length > 0 && isShowGuide">
  105. <img class="close-icon" @click="isShowGuide = false" src="@/assets/images/close.png" alt="">
  106. <div class="title">{{ curSelect.number + curSelect.name }}</div>
  107. <div class="line"></div>
  108. <div class="bottom-content">
  109. <div v-show="!isMobile">{{ curSelect.info }}</div>
  110. <img @click="goScenefu()" :src="`${baseURl}/plane/pic${curSelect.id}.png`" alt="">
  111. <div v-show="isMobile">{{ curSelect.info }}</div>
  112. </div>
  113. </div>
  114. <!-- 指引 -->
  115. <div class="guide-box" v-if="Object.keys(curSelect).length > 0 && curSelect.name != '救生艇'"
  116. :style="{ top: curInfoPart.guideP.top, left: curInfoPart.guideP.left }">
  117. <img v-show="isMobile ? true : isShowGuide" class="hot-icon"
  118. :style="{ top: curInfoPart.hotP.top, left: curInfoPart.hotP.left }" @click="goScenefu()"
  119. src="@/assets/images/hot.png" alt="">
  120. <img v-show="isShowGuide" class="line"
  121. :style="{ width: curInfoPart.lineP.width, height: curInfoPart.lineP.height, left: curInfoPart.lineP.left }"
  122. :src="`${baseURl}/plane/line${curSelect.id}.png`" alt="">
  123. </div>
  124. </div>
  125. </div>
  126. </template>
  127. <style lang='less' scoped>
  128. .detail-page {
  129. width: 100%;
  130. height: 100%;
  131. background: url(@/assets/images/bg.png);
  132. background-size: 100% 100%;
  133. overflow: hidden;
  134. .logo-welcome {
  135. width: 40vw;
  136. height: 15vh;
  137. position: absolute;
  138. z-index: 2;
  139. left: 50%;
  140. bottom: 0vh;
  141. transform: translateX(-50%);
  142. cursor: pointer;
  143. background: url(@/assets/images/begin-bg2.png);
  144. background-size: 100% 100%;
  145. color: #FFFFFF;
  146. letter-spacing: 3px;
  147. text-shadow: 0px 4px 10px #000000;
  148. display: flex;
  149. justify-content: center;
  150. align-items: center;
  151. font-size: 1.8em;
  152. padding-bottom: 15px;
  153. cursor: pointer;
  154. .item {
  155. display: flex;
  156. flex-direction: column;
  157. justify-content: center;
  158. align-items: center;
  159. width: 18%;
  160. margin-top: 24px;
  161. font-size: 0.9em;
  162. img {
  163. width: 100%;
  164. opacity: 0;
  165. }
  166. }
  167. }
  168. .info-box {
  169. width: 20vw;
  170. height: 100%;
  171. position: fixed;
  172. background: rgba(27, 27, 28, 0.8);
  173. box-shadow: -4px 0px 4px 0px rgba(0, 0, 0, 0.3);
  174. color: #FFFFFF;
  175. padding: 5% 2%;
  176. box-sizing: border-box;
  177. right: 0;
  178. img {
  179. width: 35px;
  180. position: absolute;
  181. right: 10px;
  182. top: 10px;
  183. cursor: pointer;
  184. }
  185. .title {
  186. text-align: center;
  187. margin-bottom: 20px;
  188. font-weight: bold;
  189. font-size: 1.2em;
  190. }
  191. .disc {
  192. letter-spacing: 2px;
  193. font-size: 1em;
  194. text-indent: 2em;
  195. max-height: 100%;
  196. overflow: auto;
  197. }
  198. ::-webkit-scrollbar {
  199. width: 2px;
  200. /* 设置滚动条宽度 */
  201. height: 10px;
  202. /* 对于垂直滚动条的高度,也可以使用此属性 */
  203. background-color: #f5f5f531;
  204. /* 背景颜色 */
  205. border-radius: 5px;
  206. /* 边角圆角 */
  207. }
  208. /* 定义滚动条拖动柄(滑块)样式 */
  209. ::-webkit-scrollbar-thumb {
  210. background-color: #ffffff81;
  211. /* 滑块的颜色 */
  212. border-radius: 5px;
  213. /* 可选,给滑块添加边框 */
  214. box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  215. /* 可选,给滑块添加阴影效果 */
  216. }
  217. }
  218. .construction-box {
  219. width: 100%;
  220. height: 100%;
  221. position: absolute;
  222. left: 0;
  223. top: 0;
  224. overflow: hidden;
  225. .img-map {
  226. position: absolute;
  227. left: 5%;
  228. top: 5%;
  229. @media screen and (max-width: 1000px) {
  230. left: 3vw;
  231. top: 0vh;
  232. width: 150px;
  233. }
  234. }
  235. .img-left {
  236. position: absolute;
  237. left: 26px;
  238. top: 50%;
  239. transform: translateY(-50%);
  240. @media screen and (max-width: 1000px) {
  241. width: 20px;
  242. left: 5px;
  243. height: 100%;
  244. }
  245. }
  246. .img-right {
  247. position: absolute;
  248. right: 26px;
  249. top: 50%;
  250. transform: translateY(-50%);
  251. @media screen and (max-width: 1000px) {
  252. width: 20px;
  253. right: 5px;
  254. height: 100%;
  255. }
  256. }
  257. .img-bottom {
  258. width: 100%;
  259. position: absolute;
  260. bottom: 0;
  261. }
  262. .list-box {
  263. width: 15vw;
  264. height: 62vh;
  265. background: url(@/assets/images/list-bg.png);
  266. background-size: 100% 100%;
  267. position: absolute;
  268. right: 8%;
  269. top: 20px;
  270. z-index: 10px;
  271. color: white;
  272. display: flex;
  273. flex-direction: column;
  274. justify-content: space-between;
  275. padding-bottom: 1%;
  276. box-sizing: border-box;
  277. @media screen and (max-width: 1000px) {
  278. width: 25vw;
  279. height: 98%;
  280. right: 1vw;
  281. top: 1%;
  282. background: url(@/assets/images/list-bg-mo.png);
  283. background-size: 100% 100%;
  284. }
  285. .stereoscopic-box {
  286. width: 100%;
  287. height: 10%;
  288. // background: rgba(0, 128, 0, 0.384);
  289. margin-top: 7%;
  290. display: flex;
  291. justify-content: center;
  292. align-items: center;
  293. font-weight: bold;
  294. font-size: 1.4em;
  295. letter-spacing: 2px;
  296. cursor: pointer;
  297. @media screen and (max-width: 1000px) {
  298. font-size: 1.2em;
  299. margin-top: 4%;
  300. }
  301. }
  302. ::-webkit-scrollbar {
  303. width: 0;
  304. }
  305. .list-bottom {
  306. width: 100%;
  307. margin-top: 8%;
  308. height: 100%;
  309. // background: rgba(0, 128, 0, 0.384);
  310. display: flex;
  311. flex-direction: column;
  312. align-items: center;
  313. justify-content: space-around;
  314. font-size: 1.4em;
  315. letter-spacing: 2px;
  316. position: relative;
  317. @media screen and (max-width: 1000px) {
  318. width: 25vw;
  319. height: 80%;
  320. overflow: auto;
  321. margin-bottom: 10%;
  322. margin-top: 8%;
  323. }
  324. .topAc {
  325. width: 100%;
  326. position: absolute;
  327. }
  328. .bottomAc {
  329. width: 93%;
  330. position: absolute;
  331. bottom: -4%;
  332. }
  333. .list-item {
  334. width: 70%;
  335. padding: 10px 0 10px;
  336. display: flex;
  337. justify-content: center;
  338. align-items: center;
  339. border-bottom: 1px solid rgba(0, 0, 0, 0.219);
  340. cursor: pointer;
  341. flex-basis: 20%;
  342. font-size: 0.7em;
  343. position: relative;
  344. z-index: 2;
  345. @media screen and (max-width: 1000px) {
  346. width: 90%;
  347. text-align: center;
  348. }
  349. }
  350. .active {
  351. background: #1286AB;
  352. border-bottom: none;
  353. width: 96%;
  354. font-weight: bold;
  355. @media screen and (max-width: 1000px) {
  356. width: 90%;
  357. background: url(@/assets/images/active-bg.png);
  358. background-size: 100% 100%;
  359. }
  360. }
  361. }
  362. .down-line {
  363. position: absolute;
  364. bottom: 10px;
  365. width: 80%;
  366. left: 50%;
  367. transform: translateX(-50%);
  368. z-index: 2;
  369. }
  370. }
  371. .info-box-detail {
  372. width: 20vw;
  373. // height: 20vh;
  374. background: rgba(27, 27, 28, 0.6);
  375. box-shadow: -4px 0px 4px 0px rgba(0, 0, 0, 0.3);
  376. border-radius: 4px 4px 4px 4px;
  377. position: absolute;
  378. top: 10%;
  379. right: 25%;
  380. padding: 20px 20px;
  381. z-index: 2;
  382. box-sizing: border-box;
  383. @media screen and (max-width: 1000px) {
  384. height: 70vh;
  385. right: 27%;
  386. top: 16%;
  387. padding: 0;
  388. width: 22vw;
  389. }
  390. .close-icon {
  391. width: 35px;
  392. height: 35px;
  393. cursor: pointer;
  394. position: absolute;
  395. top: 10px;
  396. right: 10px;
  397. @media screen and (max-width: 1000px) {
  398. width: 20px;
  399. height: 20px;
  400. }
  401. }
  402. .title {
  403. color: #FFFFFF;
  404. font-weight: bold;
  405. font-size: 1.2em;
  406. @media screen and (max-width: 1000px) {
  407. font-size: 0.8em;
  408. margin-top: 5px;
  409. padding-left: 10px;
  410. padding-top: 5px;
  411. }
  412. }
  413. .line {
  414. width: 100%;
  415. height: 2px;
  416. background: linear-gradient(to right, rgba(63, 151, 188, 1), rgba(63, 151, 188, 0));
  417. margin: 10px 0;
  418. }
  419. .bottom-content {
  420. display: flex;
  421. color: white;
  422. @media screen and (max-width: 1000px) {
  423. flex-direction: column;
  424. padding: 0px 15px;
  425. overflow: auto;
  426. height: 50vh;
  427. // justify-content: center;
  428. align-items: center;
  429. }
  430. img {
  431. width: 40%;
  432. object-fit: cover;
  433. margin-left: 10px;
  434. cursor: pointer;
  435. @media screen and (max-width: 1000px) {
  436. width: 90%;
  437. height: 20vh;
  438. margin-left: 0px;
  439. box-shadow: -4px 0px 4px 0px rgba(0, 0, 0, 0.3);
  440. margin-bottom: 5px;
  441. }
  442. }
  443. div {
  444. max-height: 10vh;
  445. overflow: auto;
  446. font-size: 0.9em;
  447. @media screen and (max-width: 1000px) {
  448. font-size: 0.7em;
  449. max-height: 25vh;
  450. }
  451. }
  452. ::-webkit-scrollbar {
  453. width: 2px;
  454. /* 设置滚动条宽度 */
  455. height: 2px;
  456. /* 对于垂直滚动条的高度,也可以使用此属性 */
  457. background-color: #f5f5f531;
  458. /* 背景颜色 */
  459. border-radius: 5px;
  460. /* 边角圆角 */
  461. }
  462. /* 定义滚动条拖动柄(滑块)样式 */
  463. ::-webkit-scrollbar-thumb {
  464. background-color: #ffffff81;
  465. /* 滑块的颜色 */
  466. border-radius: 5px;
  467. /* 可选,给滑块添加边框 */
  468. box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
  469. /* 可选,给滑块添加阴影效果 */
  470. }
  471. }
  472. }
  473. .guide-box {
  474. position: absolute;
  475. .hot-icon {
  476. position: absolute;
  477. z-index: 2;
  478. cursor: pointer;
  479. @media screen and (max-width: 1000px) {
  480. width: 60px;
  481. }
  482. }
  483. .line {
  484. position: absolute;
  485. @media screen and (max-width: 1000px) {
  486. display: none;
  487. }
  488. }
  489. }
  490. }
  491. }
  492. </style>