PanoView.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  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="default-frames"
  37. src="@/assets/images/A1-min.png"
  38. alt=""
  39. draggable="false"
  40. >
  41. <img
  42. v-show="animationType === 2"
  43. class="frames frames-2"
  44. :class="{
  45. animating: isCharacterSpecialMoving,
  46. state1: isCharacterSpecialMoving === 0,
  47. state2: isCharacterSpecialMoving === 1,
  48. }"
  49. src="@/assets/images/A2-min.png"
  50. alt=""
  51. draggable="false"
  52. >
  53. <img
  54. v-show="animationType === 3"
  55. class="frames frames-3"
  56. :class="{
  57. animating: isCharacterSpecialMoving,
  58. state1: isCharacterSpecialMoving === 0,
  59. state2: isCharacterSpecialMoving === 1,
  60. }"
  61. src="@/assets/images/A3-min.png"
  62. alt=""
  63. draggable="false"
  64. >
  65. </div>
  66. <img
  67. class="btn-track"
  68. :src="require(`@/assets/images/people-btn-track-${sceneIdx + 1}.png`)"
  69. alt=""
  70. draggable="false"
  71. >
  72. <button
  73. class="one btn-on-track"
  74. @click="showingContentIdx = 1"
  75. >
  76. <span>{{ btnOnTrack1Name }}</span>
  77. </button>
  78. <button
  79. class="two btn-on-track"
  80. @click="showingContentIdx = 2"
  81. >
  82. <span>{{ btnOnTrack2Name }}</span>
  83. </button>
  84. <button
  85. class="three btn-on-track"
  86. @click="showingContentIdx = 3"
  87. >
  88. <span>{{ btnOnTrack3Name }}</span>
  89. </button>
  90. <button
  91. class="four btn-on-track"
  92. @click="router.push({
  93. name: 'RelicList',
  94. query: {
  95. sceneIdx: route.query.sceneIdx,
  96. cameraIdx: route.query.cameraIdx,
  97. }
  98. })"
  99. >
  100. <span>文物长卷</span>
  101. </button>
  102. </div>
  103. <div class="camera-list">
  104. <button
  105. v-for="(item, idx) in currentCameraList"
  106. :key="idx"
  107. class="camera-entry"
  108. :class="{
  109. active: idx === (mouseEnterCameraItemIdx === -1 ? cameraIdx : mouseEnterCameraItemIdx)
  110. }"
  111. @mouseenter="mouseEnterCameraItemIdx = idx"
  112. @mouseleave="mouseEnterCameraItemIdx = -1"
  113. @click="router.push({
  114. name: route.name,
  115. query:{
  116. sceneIdx: route.query.sceneIdx,
  117. cameraIdx: idx,
  118. }
  119. })"
  120. >
  121. <span>{{ item.name }}</span>
  122. <img
  123. class="bg-normal"
  124. :src="require(`@/assets/images/camera-list-item-bg-${sceneIdx + 1}.png`)"
  125. alt=""
  126. draggable="false"
  127. >
  128. <img
  129. class="bg-active"
  130. :src="require(`@/assets/images/camera-list-item-bg-active-${sceneIdx + 1}.png`)"
  131. alt=""
  132. draggable="false"
  133. >
  134. </button>
  135. <button
  136. class="next-camera"
  137. @click="onClickNextCamera"
  138. />
  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. import sceneTree from '/public/sceneTree.js'
  166. const btnReturnHomeImgUrl = computed(() => {
  167. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/btn-return-home-${sceneIdx.value + 1}.png`) + ')'
  168. })
  169. const btnReturnHomeActiveImgUrl = computed(() => {
  170. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/btn-return-home-active-${sceneIdx.value + 1}.png`) + ')'
  171. })
  172. const btnOnTrack1ImgUrl = computed(() => {
  173. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-1.png`) + ')'
  174. })
  175. const btnOnTrack1ActiveImgUrl = computed(() => {
  176. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-1-active.png`) + ')'
  177. })
  178. const btnOnTrack2ImgUrl = computed(() => {
  179. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-2.png`) + ')'
  180. })
  181. const btnOnTrack2ActiveImgUrl = computed(() => {
  182. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-2-active.png`) + ')'
  183. })
  184. const btnOnTrack3ImgUrl = computed(() => {
  185. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-3.png`) + ')'
  186. })
  187. const btnOnTrack3ActiveImgUrl = computed(() => {
  188. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-3-active.png`) + ')'
  189. })
  190. const btnOnTrack4ImgUrl = computed(() => {
  191. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-4.png`) + ')'
  192. })
  193. const btnOnTrack4ActiveImgUrl = computed(() => {
  194. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-btn-${sceneIdx.value + 1}-${cameraIdx.value + 1}-4-active.png`) + ')'
  195. })
  196. const cameraListBgUrl = computed(() => {
  197. return `url(${process.env.VUE_APP_CLI_MODE === 'dev' ? '' : '../'}` + require(`@/assets/images/camera-list-bg-${sceneIdx.value + 1}.png`) + ')'
  198. })
  199. const btnOnTrack1Name = computed(() => {
  200. return currentCameraList.value[cameraIdx.value].contentPageBtnNameList[0]
  201. })
  202. const btnOnTrack2Name = computed(() => {
  203. return currentCameraList.value[cameraIdx.value].contentPageBtnNameList[1]
  204. })
  205. const btnOnTrack3Name = computed(() => {
  206. return currentCameraList.value[cameraIdx.value].contentPageBtnNameList[2]
  207. })
  208. const CameraContent1 = defineAsyncComponent(() =>
  209. import(`@/components/CameraContent-${Number(route.query.sceneIdx) + 1}-${Number(route.query.cameraIdx) + 1}-1.vue`)
  210. )
  211. const CameraContent2 = defineAsyncComponent(() =>
  212. import(`@/components/CameraContent-${Number(route.query.sceneIdx) + 1}-${Number(route.query.cameraIdx) + 1}-2.vue`)
  213. )
  214. const CameraContent3 = defineAsyncComponent(() =>
  215. import(`@/components/CameraContent-${Number(route.query.sceneIdx) + 1}-${Number(route.query.cameraIdx) + 1}-3.vue`)
  216. )
  217. const {
  218. windowSizeInCssForRef,
  219. windowSizeWhenDesignForRef,
  220. } = useSizeAdapt()
  221. const route = useRoute()
  222. const router = useRouter()
  223. const store = useStore()
  224. const sceneIdx = computed(() => {
  225. return Number(route.query.sceneIdx)
  226. })
  227. const cameraIdx = computed(() => {
  228. return Number(route.query.cameraIdx)
  229. })
  230. const isCharacterSpecialMoving = ref(0)
  231. const animationType = ref(1)
  232. const isShowCameraDesc = ref(false)
  233. const isShowCharacterDesc = ref(false)
  234. const showingContentIdx = ref(0)
  235. function onClickCharacter() {
  236. isShowCameraDesc.value = true
  237. if (!isCharacterSpecialMoving.value) {
  238. animationType.value = Math.floor(Math.random() * 2) + 2
  239. let duration = 0
  240. switch (animationType.value) {
  241. case 2:
  242. duration = 2000
  243. break
  244. case 3:
  245. duration = 1500
  246. break
  247. default:
  248. break
  249. }
  250. setTimeout(() => {
  251. isCharacterSpecialMoving.value = 1
  252. setTimeout(() => {
  253. isCharacterSpecialMoving.value = 0
  254. animationType.value = 1
  255. }, duration)
  256. }, 200)
  257. }
  258. }
  259. const currentCameraList = computed(() => {
  260. return sceneTree[sceneIdx.value].cameraList
  261. })
  262. const mouseEnterCameraItemIdx = ref(-1)
  263. function onClickNextCamera() {
  264. router.push({
  265. name: route.name,
  266. query: {
  267. sceneIdx: sceneIdx.value + 1,
  268. cameraIdx: cameraIdx.value,
  269. }
  270. })
  271. }
  272. /**
  273. * 全景图
  274. */
  275. let __krfn = krfn.default
  276. window.__krfn = __krfn
  277. let scene = null
  278. function fixPanoData(panoData) {
  279. // 丢弃没有包含场景的二级分组
  280. let tmp = []
  281. panoData.scenes.forEach((item) => {
  282. panoData.catalogs.forEach((sub) => {
  283. if (item.category == sub.id) {
  284. if (tmp.indexOf(sub) < 0) {
  285. tmp.push(sub)
  286. }
  287. }
  288. })
  289. })
  290. tmp = utils.unique(tmp)
  291. panoData.catalogs = tmp
  292. // 丢弃没有包含二级分组的一级分组
  293. let rootmp = []
  294. tmp.forEach((item) => {
  295. panoData.catalogRoot.forEach((sub) => {
  296. sub.children = utils.unique(sub.children)
  297. if (sub.children.indexOf(item.id) > -1) {
  298. rootmp.push(sub)
  299. }
  300. })
  301. })
  302. rootmp = utils.unique(rootmp)
  303. // 一级分组按名称排序
  304. let sortArr = panoData.catalogRoot.map((item) => item.name)
  305. rootmp.sort((a, b) => {
  306. return sortArr.indexOf(a.name) - sortArr.indexOf(b.name)
  307. })
  308. // 各个一级分组的children去重,只留下有实际的二级分组相对应的那些children item。
  309. panoData.catalogRoot = rootmp.map((item) => {
  310. let temp = []
  311. item.children = utils.unique(item.children)
  312. item.children.forEach((sub) => {
  313. tmp.forEach((jj) => {
  314. if (jj.id == sub) {
  315. temp.push(sub)
  316. }
  317. })
  318. })
  319. return {
  320. ...item,
  321. children: temp,
  322. }
  323. })
  324. // 多余
  325. panoData.catalogs = tmp
  326. // 如果没有一级分组(一定也就没有二级分组)就创建一级分组和二级分组 有必要吗?
  327. let cid = "c_" + utils.randomWord(true, 8, 8)
  328. if (panoData.catalogRoot.length <= 0) {
  329. panoData.catalogRoot.push({
  330. id: "r_" + utils.randomWord(true, 8, 8),
  331. name: "全部场景",
  332. children: [cid],
  333. })
  334. }
  335. if (panoData.catalogs.length <= 0) {
  336. panoData.catalogs.push({
  337. id: cid,
  338. name: "默认二级分组",
  339. })
  340. }
  341. // 如果有初始场景,改为引用场景列表中对应的那个场景的js对象
  342. if (panoData.firstScene) {
  343. panoData.firstScene = panoData.scenes.find(
  344. (item) => item.sceneCode == panoData.firstScene.sceneCode
  345. )
  346. }
  347. }
  348. function loadScene(sceneIdx, cameraIdx) {
  349. scene = store.getters.catalogTopology[sceneIdx].children[0].children[cameraIdx]
  350. $("#pano").empty()
  351. window.vrInitFn = () => {
  352. // eslint-disable-next-line no-undef
  353. // $smallWaiting.hide()
  354. var krpano = document.getElementById("krpanoSWFObject")
  355. __krfn.utils.initHotspot(krpano, scene.someData, false)
  356. }
  357. window.vrViewFn = () => {
  358. try {
  359. let tmp = scene.initVisual || {}
  360. var krpano = document.getElementById("krpanoSWFObject")
  361. krpano.set("view.vlookat", tmp.vlookat || 0)
  362. krpano.set("view.hlookat", tmp.hlookat || 0)
  363. krpano.set("autorotate.enabled", Boolean(store.state.panoData.isAuto))
  364. } catch (error) {
  365. console.log(error)
  366. }
  367. }
  368. let settings = {
  369. "events[skin_events].onxmlcomplete": "js(window.vrViewFn());",
  370. "events[skin_events].onloadcomplete": "js(window.vrInitFn());",
  371. }
  372. // eslint-disable-next-line no-undef
  373. removepano("#pano")
  374. // eslint-disable-next-line no-undef
  375. embedpano({
  376. xml: `https://4dkk.4dage.com/720yun_fd_manage/${scene.sceneCode}/vtour/tour.xml`,
  377. swf: `${process.env.BASE_URL}static/template/tour.swf`, // 文件名tour.swf没看出来有啥作用,不写也行。但它的路径决定了 %SWFPATH% 的值。
  378. target: "pano",
  379. html5: "auto",
  380. mobilescale: 1,
  381. vars: settings,
  382. passQueryParameters: true,
  383. })
  384. }
  385. onMounted(() => {
  386. api.fetchPanoData('WK1730428603763576832').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. // loadScene(Number(to.query.sceneIdx), Number(to.query.cameraIdx))
  397. // }
  398. })
  399. </script>
  400. <style lang="less" scoped>
  401. *{
  402. user-select: none;
  403. }
  404. .pano-view{
  405. position: relative;
  406. height: 100%;
  407. >#pano{
  408. position: absolute;
  409. left: 0;
  410. top: 0;
  411. width: 100%;
  412. height: 100%;
  413. }
  414. >button.return-home{
  415. position: absolute;
  416. width: 77px;
  417. height: 77px;
  418. top: 43px;
  419. right: 51px;
  420. background-image: v-bind(btnReturnHomeImgUrl);
  421. background-size: cover;
  422. background-repeat: no-repeat;
  423. background-position: center center;
  424. &:hover{
  425. background-image: v-bind(btnReturnHomeActiveImgUrl);
  426. }
  427. }
  428. >.camera-desc{
  429. z-index: 5;
  430. }
  431. >.character-desc{
  432. z-index: 5;
  433. }
  434. >.character-wrap{
  435. position: absolute;
  436. left: 40px;
  437. bottom: 0;
  438. width: 300px;
  439. height: 452px;
  440. >button.name{
  441. position: absolute;
  442. top: 50px;
  443. left: 0;
  444. transform: translateX(-50%);
  445. width: 36px;
  446. height: 178px;
  447. z-index: 3;
  448. font-size: 23px;
  449. font-family: Source Han Serif SC, Source Han Serif SC;
  450. font-weight: 400;
  451. color: #43310E;
  452. line-height: 27px;
  453. letter-spacing: 7px;
  454. writing-mode: vertical-lr;
  455. background-image: url(@/assets/images/people-name-bg.png);
  456. background-size: contain;
  457. background-repeat: no-repeat;
  458. background-position: center center;
  459. >span{
  460. position: absolute;
  461. left: 45%;
  462. top: 50%;
  463. transform: translate(-50%, -50%);
  464. }
  465. }
  466. @frame-width: 256px;
  467. @frame-height: 512px;
  468. @duration-1: 3s;
  469. @frame-num-1: 72;
  470. @duration-2: 2s;
  471. @frame-num-2: 48;
  472. @duration-3: 1.5s;
  473. @frame-num-3: 36;
  474. >.character-frames-wrapper {
  475. position: absolute;
  476. left: 0;
  477. top: -60px;
  478. height: @frame-height;
  479. width: @frame-width;
  480. overflow: hidden;
  481. z-index: 1;
  482. cursor: pointer;
  483. >.default-frames{
  484. position: absolute;
  485. left: 0;
  486. height: 100%;
  487. animation-name: character-default-animation;
  488. animation-timing-function: steps(73, end);
  489. animation-duration: 3s;
  490. animation-iteration-count: infinite;
  491. }
  492. >.frames {
  493. position: absolute;
  494. height: 100%;
  495. transition-property: none;
  496. &.animating{
  497. transition-property: left;
  498. }
  499. &.state1 {
  500. left: 0;
  501. }
  502. }
  503. >.frames-2{
  504. transition-duration: @duration-2;
  505. transition-timing-function: steps(@frame-num-2 - 1, jump-end);
  506. &.state2 {
  507. left: calc(-100% * (@frame-num-2 - 1));
  508. }
  509. }
  510. >.frames-3{
  511. transition-duration: @duration-3;
  512. transition-timing-function: steps(@frame-num-3 - 1, jump-end);
  513. &.state2 {
  514. left: calc(-100% * (@frame-num-3 - 1));
  515. }
  516. }
  517. }
  518. >img.btn-track{
  519. position: absolute;
  520. width: 598px;
  521. height: 598px;
  522. left: -150px;
  523. bottom: -101px;
  524. }
  525. >button.btn-on-track{
  526. position: absolute;
  527. width: 78px;
  528. height: 78px;
  529. background-size: cover;
  530. background-repeat: no-repeat;
  531. background-position: center center;
  532. text-align: left;
  533. z-index: 3;
  534. >span{
  535. margin-left: 120px;
  536. display: none;
  537. font-size: 23px;
  538. font-family: Source Han Serif SC, Source Han Serif SC;
  539. font-weight: 600;
  540. color: #FFF1BE;
  541. line-height: 27px;
  542. letter-spacing: 5px;
  543. }
  544. &:hover{
  545. width: 397px;
  546. height: 91px;
  547. transform: translate(-13px, -5px);
  548. >span{
  549. display: initial;
  550. }
  551. }
  552. }
  553. >button.one{
  554. left: 210px;
  555. top: -42px;
  556. background-image: v-bind(btnOnTrack1ImgUrl);
  557. &:hover{
  558. background-image: v-bind(btnOnTrack1ActiveImgUrl);
  559. }
  560. }
  561. >button.two{
  562. left: 336px;
  563. top: 62px;
  564. background-image: v-bind(btnOnTrack2ImgUrl);
  565. &:hover{
  566. background-image: v-bind(btnOnTrack2ActiveImgUrl);
  567. }
  568. }
  569. >button.three{
  570. left: 385px;
  571. top: 205px;
  572. background-image: v-bind(btnOnTrack3ImgUrl);
  573. &:hover{
  574. background-image: v-bind(btnOnTrack3ActiveImgUrl);
  575. }
  576. }
  577. >button.four{
  578. left: 352px;
  579. top: 353px;
  580. background-image: v-bind(btnOnTrack4ImgUrl);
  581. &:hover{
  582. background-image: v-bind(btnOnTrack4ActiveImgUrl);
  583. }
  584. }
  585. }
  586. >div.camera-list{
  587. position: absolute;
  588. bottom: 0;
  589. right: 0;
  590. width: calc(1346 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  591. height: calc(161 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  592. background-image: v-bind(cameraListBgUrl);
  593. background-size: cover;
  594. background-repeat: no-repeat;
  595. background-position: center center;
  596. display: flex;
  597. justify-content: flex-end;
  598. align-items: center;
  599. padding-top: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  600. padding-right: calc(204 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  601. >button.camera-entry{
  602. width: calc(198 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  603. height: calc(41 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  604. font-size: calc(21 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  605. font-family: Source Han Serif SC, Source Han Serif SC;
  606. font-weight: 600;
  607. color: #FFED87;
  608. line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  609. letter-spacing: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  610. position: relative;
  611. z-index: 0;
  612. >img.bg-normal{
  613. display: initial;
  614. position: absolute;
  615. left: 50%;
  616. top: 50%;
  617. transform: translate(-50%, -50%);
  618. width: calc(198/ v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  619. height: calc(55 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  620. z-index: -1;
  621. }
  622. >img.bg-active{
  623. display: none;
  624. position: absolute;
  625. left: 50%;
  626. top: 0%;
  627. transform: translate(-50%, -50%);
  628. width: calc(230 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  629. height: auto;
  630. z-index: -1;
  631. }
  632. }
  633. >button.camera-entry.active{
  634. font-size: calc(21 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  635. font-family: Source Han Serif SC, Source Han Serif SC;
  636. font-weight: 600;
  637. color: #794A00;
  638. line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  639. letter-spacing: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  640. >img.bg-normal{
  641. display: none;
  642. }
  643. >img.bg-active{
  644. display: initial;
  645. }
  646. }
  647. >button.next-camera{
  648. position: absolute;
  649. top: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  650. right: calc(45 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  651. width: calc(70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  652. height: calc(100 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
  653. }
  654. }
  655. >.camera-content{
  656. z-index: 10;
  657. }
  658. }
  659. @keyframes character-default-animation {
  660. 0% {
  661. translate: 0 0;
  662. }
  663. 100% {
  664. translate: -100% 0;
  665. }
  666. }
  667. </style>