123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- <template>
- <div class="common-con">
- <SerialFrames
- :frame-total-num="72"
- :frame-interval="45"
- :image-src-func="getImg"
- :auto-play="true"
- :repeat="true"
- :audio-url="info.voiceDuration ? getAudioUrl(`${info.textCn}.mp3`) : ''"
- />
- <div class="right-info"
- :class="{
- large: isLargeDesc,
- }"
- >
- <SquareWord :word="info.textCn" size="mini" />
- <div class="intro">
- <ul class="introduce">
- <li v-for="item in info.introduce" :key="item">
- <span v-for="innerItem in item" :key="innerItem">
- <span v-if="!(innerItem === '𨢑' && $isMobile)">{{ innerItem }}</span>
- <img v-if="innerItem === '𨢑' && $isMobile" class="special-font" src="@/assets/images/font/u28891.svg" alt="" draggable="false">
- </span>
- </li>
- </ul>
- <div class="hotspots">
- <swiper :slides-per-view="5" :space-between="10" @swiper="onSwiper" @slideChange="onSlideChange">
- <swiper-slide @click="onClickItem(item)" v-for="item in info.hotspots" :key="item" v-show="showHotspotPoint">
- <div class="himg">
- <img :src="getImgUrl(`hotspot/${item.img}`)" alt="">
- </div>
- <span>{{ item.name }}</span>
- </swiper-slide>
- </swiper>
- <template v-if="info.hotspots && info.hotspots.length > 5">
- <img class="navigation left" @click="mySwiper.slidePrev()" :src="getImgUrl('icon_left.png')" alt="">
- <img class="navigation right" @click="mySwiper.slideNext()" :src="getImgUrl('icon_right.png')" alt="">
- </template>
- </div>
- </div>
- </div>
- <img
- class="hotspot-icon animation-show-hide"
- v-for="item in info.hotspots.filter((hotspot) => {
- return hotspot.x && hotspot.y
- })"
- @click="onClickItem(item)"
- :key="item.id"
- :style="{
- left: item.x + ($isRotate ? 'vw' : 'vh'),
- top: item.y + ($isRotate ? 'vw' : 'vh'),
- display: showHotspotPoint ? '' : 'none',
- }"
- draggable="false"
- src="@/assets/images/hotspot_icon.png"
- />
- </div>
- </template>
- <script setup>
- import SquareWord from "@/components/SquareWord.vue";
- import { getCurrentInstance, ref, computed, } from 'vue'
- import appStore from "@/store/index";
- import { Swiper, SwiperSlide } from 'swiper/vue';
- import 'swiper/css';
- const store = appStore();
- const getImgUrl = utils.getImageUrl
- const getAudioUrl = utils.getAudioUrl
- const instance = getCurrentInstance()
- const globalProperties = instance.appContext.app.config.globalProperties
- const props = defineProps({
- info: Object,
- isLargeDesc: Boolean,
- })
- const mySwiper = ref(null)
- const getImg = (index) => {
- return config.cdnDir + `images/long-image${globalProperties.$isMobile ? '-mobile' : ''}/${props.info.id}/${props.info.img}_${(index - 1).toString().padStart(5, '0')}.png`
- }
- const onSwiper = (swiper) => {
- mySwiper.value = swiper
- };
- const onSlideChange = () => {
- console.log('slide change');
- };
- const showHotspotPoint = computed(() => {
- return store.getShowHotspotPoint
- })
- const onClickItem = item => {
- console.log('result:', item);
- if (item.url) {
- window.open(item.url,'_blank')
- return
- }
- store.currentHotspot = {
- thumb: utils.getImageUrl(`hotspot_big/${item.img}`),
- name: item.name,
- info: {
- img: utils.getImageUrl(`hotspot_big/${item.img}`),
- introduce: [
- item.detail,
- ]
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .common-con {
- --thiscolor: #72928E;
- height: 100%;
- display: flex;
- justify-content: flex-start;
- position: relative;
- .right-info {
- display: flex;
- align-items: flex-start;
- justify-content: flex-start;
- height: 100%;
- margin: 0 3rem;
- padding-top: 4%;
- .intro {
- margin-left: 2rem;
- overflow: auto;
- padding-right: 1rem;
- height: 70%;
- .introduce {
- text-align: justify;
- >li {
- font-size: 1rem;
- line-height: 1.5;
- text-indent: 2rem;
- display: inline-block;
- color: #695757;
- > span {
- > img {
- width: 1em;
- height: 1em;
- vertical-align: -0.1em;
- }
- }
- }
- }
- .hotspots {
- width: 20rem;
- float: right;
- position: relative;
- margin-top: 0.8rem;
- margin-right: 1rem;
- .swiper {
- z-index: 0;
- .swiper-slide {
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- text-align: center;
- cursor: pointer;
- .himg {
- border-radius: 50%;
- overflow: hidden;
- border: 0.12rem solid var(--thiscolor);
- width: 2.8rem;
- height: 2.8rem;
- object-fit: contain;
- >img {
- width: 100%;
- height: 100%;
- }
- }
- >span {
- color: var(--thiscolor);
- font-size: 0.6rem;
- margin-top: 0.4rem;
- }
- &:hover,
- &.active {
- --thiscolor: #783435;
- }
- }
- }
- .navigation {
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- cursor: pointer;
- width: 0.5rem;
- &.left {
- left: -2rem;
- }
- &.right {
- right: -2rem;
- }
- }
- }
- }
- }
- .right-info.large {
- margin: 0 2rem;
- padding-top: 2%;
- .intro {
- margin-left: 1rem;
- height: 80%;
- }
- }
- .hotspot-icon {
- position: absolute;
- width: 3.5rem;
- height: 3.5rem;
- transform: translate(-40%, -40%);
- }
- }
- </style>
|