PanoView.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. <template>
  2. <div class="pano-view">
  3. <div id="pano" />
  4. <button
  5. class="return-home"
  6. @click="router.push({
  7. name: 'HomeView',
  8. })"
  9. />
  10. <CameraDesc
  11. v-if="isShowCameraDesc"
  12. class="camera-desc"
  13. @close="isShowCameraDesc = false"
  14. />
  15. <CharacterDesc
  16. v-if="isShowCharacterDesc"
  17. class="character-desc"
  18. @close="isShowCharacterDesc = false"
  19. />
  20. <div
  21. class="character-wrap"
  22. draggable="false"
  23. >
  24. <button
  25. class="name"
  26. @click="isShowCharacterDesc = true"
  27. >
  28. <span>趙孟頫</span>
  29. </button>
  30. <div
  31. class="character-frames-wrapper"
  32. @click="onClickCharacter"
  33. >
  34. <img
  35. v-show="animationType === 1"
  36. class="frames frames-1"
  37. :class="{
  38. animating: isCharacterAnimating,
  39. state1: characterState === 0,
  40. state2: characterState === 1,
  41. }"
  42. src="@/assets/images/A1-min.png"
  43. alt=""
  44. draggable="false"
  45. >
  46. <img
  47. v-show="animationType === 2"
  48. class="frames frames-2"
  49. :class="{
  50. animating: isCharacterAnimating,
  51. state1: characterState === 0,
  52. state2: characterState === 1,
  53. }"
  54. src="@/assets/images/A2-min.png"
  55. alt=""
  56. draggable="false"
  57. >
  58. <img
  59. v-show="animationType === 3"
  60. class="frames frames-3"
  61. :class="{
  62. animating: isCharacterAnimating,
  63. state1: characterState === 0,
  64. state2: characterState === 1,
  65. }"
  66. src="@/assets/images/A3-min.png"
  67. alt=""
  68. draggable="false"
  69. >
  70. </div>
  71. <img
  72. class="btn-track"
  73. src="@/assets/images/people-btn-track.png"
  74. alt=""
  75. draggable="false"
  76. >
  77. <button
  78. class="one btn-on-track"
  79. @click="showingContentIdx = 1"
  80. >
  81. <span>{{ btnOnTrack1Name }}</span>
  82. </button>
  83. <button
  84. class="two btn-on-track"
  85. @click="showingContentIdx = 2"
  86. >
  87. <span>{{ btnOnTrack2Name }}</span>
  88. </button>
  89. <button
  90. class="three btn-on-track"
  91. @click="showingContentIdx = 3"
  92. >
  93. <span>{{ btnOnTrack3Name }}</span>
  94. </button>
  95. <button
  96. class="four btn-on-track"
  97. @click="router.push({
  98. name: 'RelicList',
  99. query: {
  100. sceneIdx: route.query.sceneIdx,
  101. cameraIdx: route.query.cameraIdx,
  102. }
  103. })"
  104. >
  105. <span>文物长卷</span>
  106. </button>
  107. </div>
  108. <div class="camera-list">
  109. <button
  110. v-for="(item, idx) in currentCameraList"
  111. :key="idx"
  112. class="camera-entry"
  113. :class="{
  114. active: idx === Number(route.query.cameraIdx)
  115. }"
  116. @click="router.push({
  117. name: route.name,
  118. query:{
  119. sceneIdx: route.query.sceneIdx,
  120. cameraIdx: idx,
  121. }
  122. })"
  123. >
  124. <span>{{ item.name }}</span>
  125. <img
  126. class="bg-normal"
  127. src="@/assets/images/camera-list-item-bg.png"
  128. alt=""
  129. draggable="false"
  130. >
  131. <img
  132. class="bg-active"
  133. src="@/assets/images/camera-list-item-bg-active.png"
  134. alt=""
  135. draggable="false"
  136. >
  137. </button>
  138. <button class="next-camera" />
  139. </div>
  140. <CameraContent1
  141. v-if="showingContentIdx === 1"
  142. class="camera-content"
  143. @close="showingContentIdx = 0"
  144. />
  145. <CameraContent2
  146. v-if="showingContentIdx === 2"
  147. class="camera-content"
  148. @close="showingContentIdx = 0"
  149. />
  150. <CameraContent3
  151. v-if="showingContentIdx === 3"
  152. class="camera-content"
  153. @close="showingContentIdx = 0"
  154. />
  155. </div>
  156. </template>
  157. <script setup>
  158. import { ref, computed, watch, onMounted, nextTick } from "vue"
  159. import { useRoute, useRouter, onBeforeRouteUpdate } from "vue-router"
  160. import { useStore } from "vuex"
  161. import * as krfn from "@/libs/pano-core/index.js"
  162. import CameraDesc from '@/components/CameraDesc.vue'
  163. import CharacterDesc from '@/components/CharacterDesc.vue'
  164. import { defineAsyncComponent } from 'vue'
  165. const CameraContent1 = defineAsyncComponent(() =>
  166. import(`@/components/CameraContent-${Number(route.query.sceneIdx) + 1}-${Number(route.query.cameraIdx) + 1}-1.vue`)
  167. )
  168. const CameraContent2 = defineAsyncComponent(() =>
  169. import(`@/components/CameraContent-${Number(route.query.sceneIdx) + 1}-${Number(route.query.cameraIdx) + 1}-2.vue`)
  170. )
  171. const CameraContent3 = defineAsyncComponent(() =>
  172. import(`@/components/CameraContent-${Number(route.query.sceneIdx) + 1}-${Number(route.query.cameraIdx) + 1}-3.vue`)
  173. )
  174. const {
  175. windowSizeInCssForRef,
  176. windowSizeWhenDesignForRef,
  177. } = useSizeAdapt()
  178. const route = useRoute()
  179. const router = useRouter()
  180. const store = useStore()
  181. const sceneIdx = computed(() => {
  182. return Number(route.query.sceneIdx)
  183. })
  184. const cameraIdx = computed(() => {
  185. return Number(route.query.cameraIdx)
  186. })
  187. const characterState = ref(0)
  188. const isCharacterAnimating = ref(false)
  189. const animationType = ref(1)
  190. const isShowCameraDesc = ref(false)
  191. const isShowCharacterDesc = ref(false)
  192. const showingContentIdx = ref(0)
  193. function onClickCharacter() {
  194. isShowCameraDesc.value = true
  195. if (!isCharacterAnimating.value) {
  196. animationType.value = Math.floor(Math.random() * 3) + 1
  197. let duration = 0
  198. switch (animationType.value) {
  199. case 1:
  200. duration = 3000
  201. break
  202. case 2:
  203. duration = 2000
  204. break
  205. case 3:
  206. duration = 1500
  207. break
  208. default:
  209. break
  210. }
  211. setTimeout(() => {
  212. isCharacterAnimating.value = true
  213. characterState.value = 1
  214. setTimeout(() => {
  215. isCharacterAnimating.value = false
  216. characterState.value = 0
  217. }, duration)
  218. }, 200)
  219. }
  220. }
  221. const sceneList = ref([
  222. {
  223. sceneName: '大汗之城',
  224. cameraList: [
  225. {
  226. name: '雄伟帝都',
  227. panoCode: 'WK1730419346750099456',
  228. contentPageBtnNameList: [
  229. '整体设计与规划',
  230. '营都人员与机构',
  231. '史料中的元大都',
  232. ],
  233. },
  234. {
  235. name: '大都宫阙',
  236. panoCode: 'WK1730165377477955584',
  237. contentPageBtnNameList: [
  238. '皇城与宫城',
  239. '皇城内的建筑布局',
  240. '忽必烈召见赵孟頫',
  241. ],
  242. },
  243. {
  244. name: '大都览胜',
  245. panoCode: 'WK1730164600466362368',
  246. contentPageBtnNameList: [
  247. '大都城内的寺庙建筑',
  248. '大都城内的官署机构',
  249. '重要建筑构件',
  250. ],
  251. },
  252. ]
  253. },
  254. {
  255. sceneName: '河润大都',
  256. cameraList: [
  257. {
  258. name: '通惠河畅',
  259. contentPageBtnNameList: [
  260. '大运河的历史演变',
  261. '元大都用水水系',
  262. '水利专家及对通惠河段的治理',
  263. ],
  264. },
  265. {
  266. name: '舳舻蔽水',
  267. contentPageBtnNameList: [
  268. '菏泽沉船',
  269. '磁县漕船',
  270. '聊城古船',
  271. ],
  272. },
  273. {
  274. name: '繁华富庶',
  275. contentPageBtnNameList: [
  276. '造福百姓',
  277. '元代瓷器的发展',
  278. ' 商品贸易中的货币',
  279. ],
  280. },
  281. ]
  282. },
  283. {
  284. sceneName: '大都风华',
  285. cameraList: [
  286. {
  287. name: '文人雅集',
  288. contentPageBtnNameList: [
  289. '元代文化艺术的发展',
  290. '上流社会的雅集盛会',
  291. '百工精巧',
  292. ],
  293. },
  294. {
  295. name: '曲苑杂剧',
  296. contentPageBtnNameList: [
  297. '元曲的文化成就',
  298. '著名元曲作家与作品',
  299. '表演元曲的著名演员',
  300. ],
  301. },
  302. ]
  303. },
  304. ])
  305. const currentCameraList = computed(() => {
  306. return sceneList.value[sceneIdx.value].cameraList
  307. })
  308. const btnOnTrack1ImgUrl = computed(() => {
  309. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-1.png`) + ')'
  310. })
  311. const btnOnTrack1ActiveImgUrl = computed(() => {
  312. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-1-active.png`) + ')'
  313. })
  314. const btnOnTrack2ImgUrl = computed(() => {
  315. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-2.png`) + ')'
  316. })
  317. const btnOnTrack2ActiveImgUrl = computed(() => {
  318. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-2-active.png`) + ')'
  319. })
  320. const btnOnTrack3ImgUrl = computed(() => {
  321. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-3.png`) + ')'
  322. })
  323. const btnOnTrack3ActiveImgUrl = computed(() => {
  324. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-3-active.png`) + ')'
  325. })
  326. const btnOnTrack4ImgUrl = computed(() => {
  327. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-4.png`) + ')'
  328. })
  329. const btnOnTrack4ActiveImgUrl = computed(() => {
  330. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-4-active.png`) + ')'
  331. })
  332. const btnOnTrack1Name = computed(() => {
  333. return currentCameraList.value[cameraIdx.value].contentPageBtnNameList[0]
  334. })
  335. const btnOnTrack2Name = computed(() => {
  336. return currentCameraList.value[cameraIdx.value].contentPageBtnNameList[1]
  337. })
  338. const btnOnTrack3Name = computed(() => {
  339. return currentCameraList.value[cameraIdx.value].contentPageBtnNameList[2]
  340. })
  341. /**
  342. * 全景图
  343. */
  344. let __krfn = krfn.default
  345. window.__krfn = __krfn
  346. let scene = null
  347. function loadScene(sceneIdx, cameraIdx) {
  348. scene = store.getters.catalogTopology[sceneIdx].children[0].children[Number(cameraIdx)]
  349. $("#pano").empty()
  350. window.vrInitFn = () => {
  351. // eslint-disable-next-line no-undef
  352. // $smallWaiting.hide()
  353. var krpano = document.getElementById("krpanoSWFObject")
  354. __krfn.utils.initHotspot(krpano, scene.someData, false)
  355. }
  356. window.vrViewFn = () => {
  357. try {
  358. let tmp = scene.initVisual || {}
  359. var krpano = document.getElementById("krpanoSWFObject")
  360. krpano.set("view.vlookat", tmp.vlookat || 0)
  361. krpano.set("view.hlookat", tmp.hlookat || 0)
  362. krpano.set("autorotate.enabled", Boolean(store.state.panoData.isAuto))
  363. } catch (error) {
  364. console.log(error)
  365. }
  366. }
  367. let settings = {
  368. "events[skin_events].onxmlcomplete": "js(window.vrViewFn());",
  369. "events[skin_events].onloadcomplete": "js(window.vrInitFn());",
  370. }
  371. // eslint-disable-next-line no-undef
  372. removepano("#pano")
  373. // eslint-disable-next-line no-undef
  374. embedpano({
  375. xml: `https://4dkk.4dage.com/720yun_fd_manage/${sceneList.value[sceneIdx].cameraList[cameraIdx].panoCode}/tour.xml`,
  376. swf: `${process.env.BASE_URL}static/template/tour.swf`, // 文件名tour.swf没看出来有啥作用,不写也行。但它的路径决定了 %SWFPATH% 的值。
  377. target: "pano",
  378. html5: "auto",
  379. mobilescale: 1,
  380. vars: settings,
  381. passQueryParameters: true,
  382. })
  383. }
  384. onMounted(() => {
  385. console.log()
  386. api.fetchPanoData(sceneList.value[sceneIdx.value].cameraList[cameraIdx.value].panoCode).then((res) => {
  387. // fixPanoData(res)
  388. store.commit('setPanoData', res)
  389. console.log('catalogTopology', store.getters.catalogTopology)
  390. loadScene(Number(sceneIdx.value), Number(cameraIdx.value))
  391. })
  392. })
  393. onBeforeRouteUpdate((to, from) => {
  394. console.log('to: ', to)
  395. if (to.name === route.name) {
  396. api.fetchPanoData(sceneList.value[to.query.sceneIdx].cameraList[to.query.cameraIdx].panoCode).then((res) => {
  397. // fixPanoData(res)
  398. store.commit('setPanoData', res)
  399. console.log('catalogTopology', store.getters.catalogTopology)
  400. loadScene(Number(to.query.sceneIdx), Number(to.query.cameraIdx))
  401. })
  402. }
  403. })
  404. </script>
  405. <style lang="less" scoped>
  406. *{
  407. user-select: none;
  408. }
  409. .pano-view{
  410. position: relative;
  411. height: 100%;
  412. >#pano{
  413. position: absolute;
  414. left: 0;
  415. top: 0;
  416. width: 100%;
  417. height: 100%;
  418. }
  419. >button.return-home{
  420. position: absolute;
  421. width: 77px;
  422. height: 77px;
  423. top: 43px;
  424. right: 51px;
  425. background-image: url(@/assets/images/btn-return-home.png);
  426. background-size: cover;
  427. background-repeat: no-repeat;
  428. background-position: center center;
  429. &:hover{
  430. background-image: url(@/assets/images/btn-return-home-active.png);
  431. }
  432. }
  433. >.camera-desc{
  434. z-index: 5;
  435. }
  436. >.character-desc{
  437. z-index: 5;
  438. }
  439. >.character-wrap{
  440. position: absolute;
  441. left: 40px;
  442. bottom: 0;
  443. width: 300px;
  444. height: 452px;
  445. >button.name{
  446. position: absolute;
  447. top: 50px;
  448. left: 0;
  449. transform: translateX(-50%);
  450. width: 36px;
  451. height: 178px;
  452. z-index: 3;
  453. font-size: 23px;
  454. font-family: Source Han Serif SC, Source Han Serif SC;
  455. font-weight: 400;
  456. color: #43310E;
  457. line-height: 27px;
  458. letter-spacing: 7px;
  459. writing-mode: vertical-lr;
  460. background-image: url(@/assets/images/people-name-bg.png);
  461. background-size: contain;
  462. background-repeat: no-repeat;
  463. background-position: center center;
  464. >span{
  465. position: absolute;
  466. left: 45%;
  467. top: 50%;
  468. transform: translate(-50%, -50%);
  469. }
  470. }
  471. @frame-width: 256px;
  472. @frame-height: 512px;
  473. @duration-1: 3s;
  474. @frame-num-1: 72;
  475. @duration-2: 2s;
  476. @frame-num-2: 48;
  477. @duration-3: 1.5s;
  478. @frame-num-3: 36;
  479. >.character-frames-wrapper {
  480. position: absolute;
  481. left: 0;
  482. top: -60px;
  483. height: @frame-height;
  484. width: @frame-width;
  485. overflow: hidden;
  486. z-index: 1;
  487. cursor: pointer;
  488. >.frames {
  489. position: absolute;
  490. height: 100%;
  491. transition-property: none;
  492. &.animating{
  493. transition-property: left;
  494. }
  495. &.state1 {
  496. left: 0;
  497. }
  498. }
  499. >.frames-1{
  500. transition-duration: @duration-1;
  501. transition-timing-function: steps(@frame-num-1 - 1, jump-end);
  502. &.state2 {
  503. left: calc(-100% * (@frame-num-1 - 1));
  504. }
  505. }
  506. >.frames-2{
  507. transition-duration: @duration-2;
  508. transition-timing-function: steps(@frame-num-2 - 1, jump-end);
  509. &.state2 {
  510. left: calc(-100% * (@frame-num-2 - 1));
  511. }
  512. }
  513. >.frames-3{
  514. transition-duration: @duration-3;
  515. transition-timing-function: steps(@frame-num-3 - 1, jump-end);
  516. &.state2 {
  517. left: calc(-100% * (@frame-num-3 - 1));
  518. }
  519. }
  520. }
  521. >img.btn-track{
  522. position: absolute;
  523. width: 598px;
  524. height: 598px;
  525. left: -150px;
  526. bottom: -101px;
  527. }
  528. >button.btn-on-track{
  529. position: absolute;
  530. width: 78px;
  531. height: 78px;
  532. background-size: cover;
  533. background-repeat: no-repeat;
  534. background-position: center center;
  535. text-align: left;
  536. z-index: 3;
  537. >span{
  538. margin-left: 120px;
  539. display: none;
  540. font-size: 23px;
  541. font-family: Source Han Serif SC, Source Han Serif SC;
  542. font-weight: 600;
  543. color: #FFF1BE;
  544. line-height: 27px;
  545. letter-spacing: 5px;
  546. }
  547. &:hover{
  548. width: 397px;
  549. height: 91px;
  550. transform: translate(-13px, -5px);
  551. >span{
  552. display: initial;
  553. }
  554. }
  555. }
  556. >button.one{
  557. left: 210px;
  558. top: -42px;
  559. background-image: v-bind(btnOnTrack1ImgUrl);
  560. &:hover{
  561. background-image: v-bind(btnOnTrack1ActiveImgUrl);
  562. }
  563. }
  564. >button.two{
  565. left: 336px;
  566. top: 62px;
  567. background-image: v-bind(btnOnTrack2ImgUrl);
  568. &:hover{
  569. background-image: v-bind(btnOnTrack2ActiveImgUrl);
  570. }
  571. }
  572. >button.three{
  573. left: 385px;
  574. top: 205px;
  575. background-image: v-bind(btnOnTrack3ImgUrl);
  576. &:hover{
  577. background-image: v-bind(btnOnTrack3ActiveImgUrl);
  578. }
  579. }
  580. >button.four{
  581. left: 352px;
  582. top: 353px;
  583. background-image: v-bind(btnOnTrack4ImgUrl);
  584. &:hover{
  585. background-image: v-bind(btnOnTrack4ActiveImgUrl);
  586. }
  587. }
  588. }
  589. >div.camera-list{
  590. position: absolute;
  591. bottom: 0;
  592. right: 0;
  593. width: calc(1346 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  594. height: calc(161 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  595. background-image: url(@/assets/images/camera-list-bg.png);
  596. background-size: cover;
  597. background-repeat: no-repeat;
  598. background-position: center center;
  599. display: flex;
  600. justify-content: flex-end;
  601. align-items: center;
  602. padding-top: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  603. padding-right: calc(204 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  604. >button.camera-entry{
  605. width: calc(198 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  606. height: calc(41 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  607. font-size: calc(21 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  608. font-family: Source Han Serif SC, Source Han Serif SC;
  609. font-weight: 600;
  610. color: #FFED87;
  611. line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  612. letter-spacing: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  613. position: relative;
  614. z-index: 0;
  615. >img.bg-normal{
  616. display: initial;
  617. position: absolute;
  618. left: 50%;
  619. top: 50%;
  620. transform: translate(-50%, -50%);
  621. width: calc(198/ v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  622. height: calc(55 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  623. z-index: -1;
  624. }
  625. >img.bg-active{
  626. display: none;
  627. position: absolute;
  628. left: 50%;
  629. top: 0%;
  630. transform: translate(-50%, -50%);
  631. width: calc(230 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  632. height: auto;
  633. z-index: -1;
  634. }
  635. }
  636. >button.camera-entry.active{
  637. font-size: calc(21 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  638. font-family: Source Han Serif SC, Source Han Serif SC;
  639. font-weight: 600;
  640. color: #794A00;
  641. line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  642. letter-spacing: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  643. >img.bg-normal{
  644. display: none;
  645. }
  646. >img.bg-active{
  647. display: initial;
  648. }
  649. }
  650. >button.next-camera{
  651. position: absolute;
  652. top: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  653. right: calc(45 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  654. width: calc(70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  655. height: calc(100 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  656. }
  657. }
  658. >.camera-content{
  659. z-index: 10;
  660. }
  661. }
  662. </style>