timecommon.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <template>
  2. <div class="common-con">
  3. <SerialFrames
  4. :frame-total-num="72"
  5. :frame-interval="45"
  6. :image-src-func="getImg"
  7. :auto-play="true"
  8. :repeat="true"
  9. :audio-url="info.voiceDuration ? getAudioUrl(`${info.textCn}.mp3`) : ''"
  10. />
  11. <div class="right-info"
  12. :class="{
  13. large: isLargeDesc,
  14. }"
  15. >
  16. <SquareWord :word="info.textCn" size="mini" />
  17. <div class="intro">
  18. <ul class="introduce">
  19. <li v-for="item in info.introduce" :key="item">
  20. <span v-for="innerItem in item" :key="innerItem">
  21. <span v-if="!(innerItem === '𨢑' && $isMobile)">{{ innerItem }}</span>
  22. <img v-if="innerItem === '𨢑' && $isMobile" class="special-font" src="@/assets/images/font/u28891.svg" alt="" draggable="false">
  23. </span>
  24. </li>
  25. </ul>
  26. <div class="hotspots">
  27. <swiper :slides-per-view="5" :space-between="10" @swiper="onSwiper" @slideChange="onSlideChange">
  28. <swiper-slide @click="onClickItem(item)" v-for="item in info.hotspots" :key="item" v-show="showHotspotPoint">
  29. <div class="himg">
  30. <img :src="getImgUrl(`hotspot/${item.img}`)" alt="">
  31. </div>
  32. <span>{{ item.name }}</span>
  33. </swiper-slide>
  34. </swiper>
  35. <template v-if="info.hotspots && info.hotspots.length > 5">
  36. <img class="navigation left" @click="mySwiper.slidePrev()" :src="getImgUrl('icon_left.png')" alt="">
  37. <img class="navigation right" @click="mySwiper.slideNext()" :src="getImgUrl('icon_right.png')" alt="">
  38. </template>
  39. </div>
  40. </div>
  41. </div>
  42. <img
  43. class="hotspot-icon animation-show-hide"
  44. v-for="item in info.hotspots.filter((hotspot) => {
  45. return hotspot.x && hotspot.y
  46. })"
  47. @click="onClickItem(item)"
  48. :key="item.id"
  49. :style="{
  50. left: item.x + ($isRotate ? 'vw' : 'vh'),
  51. top: item.y + ($isRotate ? 'vw' : 'vh'),
  52. display: showHotspotPoint ? '' : 'none',
  53. }"
  54. draggable="false"
  55. src="@/assets/images/hotspot_icon.png"
  56. />
  57. </div>
  58. </template>
  59. <script setup>
  60. import SquareWord from "@/components/SquareWord.vue";
  61. import { getCurrentInstance, ref, computed, } from 'vue'
  62. import appStore from "@/store/index";
  63. import { Swiper, SwiperSlide } from 'swiper/vue';
  64. import 'swiper/css';
  65. const store = appStore();
  66. const getImgUrl = utils.getImageUrl
  67. const getAudioUrl = utils.getAudioUrl
  68. const instance = getCurrentInstance()
  69. const globalProperties = instance.appContext.app.config.globalProperties
  70. const props = defineProps({
  71. info: Object,
  72. isLargeDesc: Boolean,
  73. })
  74. const mySwiper = ref(null)
  75. const getImg = (index) => {
  76. return config.cdnDir + `images/long-image${globalProperties.$isMobile ? '-mobile' : ''}/${props.info.id}/${props.info.img}_${(index - 1).toString().padStart(5, '0')}.png`
  77. }
  78. const onSwiper = (swiper) => {
  79. mySwiper.value = swiper
  80. };
  81. const onSlideChange = () => {
  82. console.log('slide change');
  83. };
  84. const showHotspotPoint = computed(() => {
  85. return store.getShowHotspotPoint
  86. })
  87. const onClickItem = item => {
  88. console.log('result:', item);
  89. if (item.url) {
  90. window.open(item.url,'_blank')
  91. return
  92. }
  93. store.currentHotspot = {
  94. thumb: utils.getImageUrl(`hotspot_big/${item.img}`),
  95. name: item.name,
  96. info: {
  97. img: utils.getImageUrl(`hotspot_big/${item.img}`),
  98. introduce: [
  99. item.detail,
  100. ]
  101. }
  102. }
  103. }
  104. </script>
  105. <style lang="scss" scoped>
  106. .common-con {
  107. --thiscolor: #72928E;
  108. height: 100%;
  109. display: flex;
  110. justify-content: flex-start;
  111. position: relative;
  112. .right-info {
  113. display: flex;
  114. align-items: flex-start;
  115. justify-content: flex-start;
  116. height: 100%;
  117. margin: 0 3rem;
  118. padding-top: 4%;
  119. .intro {
  120. margin-left: 2rem;
  121. overflow: auto;
  122. padding-right: 1rem;
  123. height: 70%;
  124. .introduce {
  125. text-align: justify;
  126. >li {
  127. font-size: 1rem;
  128. line-height: 1.5;
  129. text-indent: 2rem;
  130. display: inline-block;
  131. color: #695757;
  132. > span {
  133. > img {
  134. width: 1em;
  135. height: 1em;
  136. vertical-align: -0.1em;
  137. }
  138. }
  139. }
  140. }
  141. .hotspots {
  142. width: 20rem;
  143. float: right;
  144. position: relative;
  145. margin-top: 0.8rem;
  146. margin-right: 1rem;
  147. .swiper {
  148. z-index: 0;
  149. .swiper-slide {
  150. display: flex;
  151. flex-direction: column;
  152. justify-content: center;
  153. align-items: center;
  154. text-align: center;
  155. cursor: pointer;
  156. .himg {
  157. border-radius: 50%;
  158. overflow: hidden;
  159. border: 0.12rem solid var(--thiscolor);
  160. width: 2.8rem;
  161. height: 2.8rem;
  162. object-fit: contain;
  163. >img {
  164. width: 100%;
  165. height: 100%;
  166. }
  167. }
  168. >span {
  169. color: var(--thiscolor);
  170. font-size: 0.6rem;
  171. margin-top: 0.4rem;
  172. }
  173. &:hover,
  174. &.active {
  175. --thiscolor: #783435;
  176. }
  177. }
  178. }
  179. .navigation {
  180. position: absolute;
  181. top: 50%;
  182. transform: translateY(-50%);
  183. cursor: pointer;
  184. width: 0.5rem;
  185. &.left {
  186. left: -2rem;
  187. }
  188. &.right {
  189. right: -2rem;
  190. }
  191. }
  192. }
  193. }
  194. }
  195. .right-info.large {
  196. margin: 0 2rem;
  197. padding-top: 2%;
  198. .intro {
  199. margin-left: 1rem;
  200. height: 80%;
  201. }
  202. }
  203. .hotspot-icon {
  204. position: absolute;
  205. width: 3.5rem;
  206. height: 3.5rem;
  207. transform: translate(-40%, -40%);
  208. }
  209. }
  210. </style>