|
@@ -1,6 +1,6 @@
|
|
|
<template>
|
|
|
<div class="hotspot-page">
|
|
|
- <div class="hotspot-page-container">
|
|
|
+ <div v-if="!isTextType" class="hotspot-page-container">
|
|
|
<!-- 音频播放器 -->
|
|
|
<audio
|
|
|
id="myAudio"
|
|
@@ -13,110 +13,95 @@
|
|
|
|
|
|
<!-- 模型页面 -->
|
|
|
<Swiper
|
|
|
- v-if="myType === 'model'"
|
|
|
- class="hotspot-page-swiper hotspot-page-model"
|
|
|
+ :modules="modules"
|
|
|
+ class="hotspot-page-swiper"
|
|
|
+ :slides-per-view="myType === 'model' || isMobile ? 1 : 3"
|
|
|
+ :centered-slides="true"
|
|
|
+ :navigation="Boolean(curList.length) && !isMobile"
|
|
|
+ :pagination="
|
|
|
+ isMobile
|
|
|
+ ? false
|
|
|
+ : {
|
|
|
+ clickable: true,
|
|
|
+ }
|
|
|
+ "
|
|
|
@swiper="initSwiper"
|
|
|
@slideChange="handleChange"
|
|
|
>
|
|
|
<SwiperSlide v-for="(item, index) in curList" :key="item.url">
|
|
|
- <iframe v-if="index === myInd" :src="item" frameborder="0" />
|
|
|
- </SwiperSlide>
|
|
|
- </Swiper>
|
|
|
-
|
|
|
- <!-- 视频页面 -->
|
|
|
- <div v-if="myType === 'video'" class="hotspot-page-swiper hotspot-page-video">
|
|
|
- <template v-for="(item, index) in curList" :key="item.url">
|
|
|
- <video
|
|
|
- v-if="index === myInd"
|
|
|
- id="videoID"
|
|
|
- class="hotspot-page-video"
|
|
|
- controls
|
|
|
- :src="item.url"
|
|
|
- autoplay
|
|
|
- />
|
|
|
- </template>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 图片页面 -->
|
|
|
- <Swiper
|
|
|
- v-if="myType === 'img'"
|
|
|
- class="hotspot-page-swiper hotspot-page-img-swiper"
|
|
|
- @swiper="initSwiper"
|
|
|
- @slideChange="handleChange"
|
|
|
- >
|
|
|
- <SwiperSlide v-for="(item, idx) in curList" :key="item">
|
|
|
- <div class="hotspot-page-img">
|
|
|
- <el-image
|
|
|
- :src="item"
|
|
|
- fit="contain"
|
|
|
- style="width: 100%; height: 100%"
|
|
|
- preview-teleported
|
|
|
- :preview-src-list="curList"
|
|
|
- :initial-index="idx"
|
|
|
- />
|
|
|
- </div>
|
|
|
+ <template v-if="myType === 'model'">
|
|
|
+ <iframe v-if="index === myInd" :src="item" frameborder="0" />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="myType === 'video'">
|
|
|
+ <video controls :src="item.url" />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="myType === 'img'">
|
|
|
+ <el-image :src="item" fit="contain" @click="handlePreview(index)" />
|
|
|
+ </template>
|
|
|
</SwiperSlide>
|
|
|
</Swiper>
|
|
|
+ </div>
|
|
|
|
|
|
- <template v-if="curList.length > 1">
|
|
|
- <div class="hotspot-page-swiper__left" @click="handlePre" />
|
|
|
- <div class="hotspot-page-swiper__right" @click="handleNext" />
|
|
|
- </template>
|
|
|
-
|
|
|
- <!-- 底部的tab -->
|
|
|
- <div v-if="flooTab.length > 1" class="hotspot-page-nav">
|
|
|
- <div
|
|
|
- v-for="item in flooTab"
|
|
|
- :key="item.id"
|
|
|
- :class="[
|
|
|
- 'hotspot-page-nav__item',
|
|
|
- {
|
|
|
- active: myType === item.type,
|
|
|
- },
|
|
|
- ]"
|
|
|
- @click="handleTab(item)"
|
|
|
- >
|
|
|
- <img :class="`${item.type}-icon`" :src="myType === item.type ? item.acIcon : item.icon" />
|
|
|
- <!-- {{ item.name }}
|
|
|
- {{ item.type === 'img' ? `${myInd + 1}/${data.img.length}` : '' }} -->
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
+ <!-- 底部的tab -->
|
|
|
+ <ul v-if="flooTab.length > 1" class="hotspot-page-nav">
|
|
|
<!-- 音频图标 -->
|
|
|
- <div
|
|
|
+ <li
|
|
|
v-if="audio && !isOneAduio"
|
|
|
- class="audioIcon"
|
|
|
- :title="audioSta ? '关闭音频' : '打开音频'"
|
|
|
+ :class="[
|
|
|
+ 'hotspot-page-nav__item',
|
|
|
+ {
|
|
|
+ active: audioSta,
|
|
|
+ },
|
|
|
+ ]"
|
|
|
@click="audioSta = !audioSta"
|
|
|
>
|
|
|
- <img :src="audioSta ? VolumeOff : VolumeOn" alt="" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <img :src="VolumeOn" :alt="audioSta ? '关闭音频' : '打开音频'" />
|
|
|
+ <span>音频</span>
|
|
|
+ </li>
|
|
|
+ <li
|
|
|
+ v-for="item in flooTab"
|
|
|
+ :key="item.id"
|
|
|
+ :class="[
|
|
|
+ 'hotspot-page-nav__item',
|
|
|
+ {
|
|
|
+ active: myType === item.type,
|
|
|
+ },
|
|
|
+ ]"
|
|
|
+ @click="handleTab(item)"
|
|
|
+ >
|
|
|
+ <img :class="`${item.type}-icon`" :src="item.icon" />
|
|
|
+ <span>{{ item.name }}</span>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
|
|
|
- <el-scrollbar :height="150" style="margin-top: 20px; height: 150px; flex-shrink: 0">
|
|
|
- <div class="hotspot-page-info">
|
|
|
- <h3>{{ myTitle }}</h3>
|
|
|
- <p>{{ myTxt }}</p>
|
|
|
- </div>
|
|
|
- </el-scrollbar>
|
|
|
+ <div
|
|
|
+ v-if="isMobile ? isTextType : true"
|
|
|
+ class="hotspot-page-scrollbar"
|
|
|
+ :class="{ isTop: !flooTab.length && !isMobile }"
|
|
|
+ >
|
|
|
+ <h3>{{ myTitle }}</h3>
|
|
|
+ <p>{{ myTxt }}</p>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { Swiper, SwiperSlide } from 'swiper/vue';
|
|
|
+ import { Navigation, Pagination } from 'swiper/modules';
|
|
|
import 'swiper/css';
|
|
|
- import { parseUrlParams } from '@/utils';
|
|
|
+ import 'swiper/css/navigation';
|
|
|
+ import 'swiper/css/pagination';
|
|
|
|
|
|
- import ModelIcon from '@hotspot/assets/images/icon-model@2x.png';
|
|
|
- import AcModelIcon from '@hotspot/assets/images/icon-model-1@2x.png';
|
|
|
- import ImageIcon from '@hotspot/assets/images/icon-image@2x.png';
|
|
|
- import AcImageIcon from '@hotspot/assets/images/icon-image-1@2x.png';
|
|
|
- import VideoIcon from '@hotspot/assets/images/icon-video@2x.png';
|
|
|
- import AcVideoIcon from '@hotspot/assets/images/icon-video-1@2x.png';
|
|
|
- import VolumeOn from '@hotspot/assets/images/Volume-on.png';
|
|
|
- import VolumeOff from '@hotspot/assets/images/Volume-off.png';
|
|
|
+ import { parseUrlParams, judgeIsMobile } from '@/utils';
|
|
|
+
|
|
|
+ import ModelIcon from '@hotspot/assets/images/model-icon.png';
|
|
|
+ import ImageIcon from '@hotspot/assets/images/img-icon.png';
|
|
|
+ import VideoIcon from '@hotspot/assets/images/video-icon.png';
|
|
|
+ import VolumeOn from '@hotspot/assets/images/audio-icon.png';
|
|
|
+ import infoIcon from '@hotspot/assets/images/info-icon.png';
|
|
|
|
|
|
const urlParams = parseUrlParams(window.location.href);
|
|
|
+ const isMobile = judgeIsMobile();
|
|
|
|
|
|
export default {
|
|
|
name: 'hotspot',
|
|
@@ -126,8 +111,8 @@
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
+ isMobile,
|
|
|
VolumeOn,
|
|
|
- VolumeOff,
|
|
|
m: urlParams.m,
|
|
|
id: urlParams.id,
|
|
|
// 音频地址
|
|
@@ -164,12 +149,17 @@
|
|
|
|
|
|
// 只有标题和文字(没有视频,没有模型,没有图片)
|
|
|
oneTxt: false,
|
|
|
+
|
|
|
+ modules: [Navigation, Pagination],
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
curList() {
|
|
|
return this.data[this.myType] || [];
|
|
|
},
|
|
|
+ isTextType() {
|
|
|
+ return this.myType === 'text';
|
|
|
+ },
|
|
|
},
|
|
|
watch: {
|
|
|
audioSta(val) {
|
|
@@ -201,13 +191,13 @@
|
|
|
// 底部的tab
|
|
|
const arr = [];
|
|
|
const obj = {};
|
|
|
- if (resData.model) {
|
|
|
- obj.model = resData.model;
|
|
|
- arr.push({ id: 1, type: 'model', name: '模型', icon: ModelIcon, acIcon: AcModelIcon });
|
|
|
+ if (resData.images) {
|
|
|
+ obj.img = resData.images;
|
|
|
+ arr.push({ id: 3, type: 'img', name: '图片', icon: ImageIcon });
|
|
|
}
|
|
|
if (resData.video) {
|
|
|
obj.video = resData.video;
|
|
|
- arr.push({ id: 2, type: 'video', name: '视频', icon: VideoIcon, acIcon: AcVideoIcon });
|
|
|
+ arr.push({ id: 2, type: 'video', name: '视频', icon: VideoIcon });
|
|
|
} else {
|
|
|
this.$nextTick(() => {
|
|
|
if (
|
|
@@ -220,17 +210,22 @@
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
- if (resData.images) {
|
|
|
- obj.img = resData.images;
|
|
|
- arr.push({ id: 3, type: 'img', name: '图片', icon: ImageIcon, acIcon: AcImageIcon });
|
|
|
+ if (resData.model) {
|
|
|
+ obj.model = resData.model;
|
|
|
+ arr.push({ id: 1, type: 'model', name: '模型', icon: ModelIcon });
|
|
|
+ }
|
|
|
+ if (isMobile) {
|
|
|
+ arr.push({ id: 4, type: 'text', name: '介绍', icon: infoIcon });
|
|
|
}
|
|
|
+
|
|
|
this.flooTab = arr;
|
|
|
this.data = obj;
|
|
|
|
|
|
// 当前type的值 应该为
|
|
|
- if (resData.model) this.myType = 'model';
|
|
|
+ if (resData.images) this.myType = 'img';
|
|
|
+ else if (resData.model) this.myType = 'model';
|
|
|
else if (resData.video) this.myType = 'video';
|
|
|
- else if (resData.images) this.myType = 'img';
|
|
|
+ else this.myType = 'text';
|
|
|
|
|
|
this.myTitle = resData.title || '';
|
|
|
this.myTxt = resData.content || '';
|
|
@@ -255,19 +250,11 @@
|
|
|
handleChange({ activeIndex }) {
|
|
|
this.myInd = activeIndex;
|
|
|
},
|
|
|
- handlePre() {
|
|
|
- if (this.myType === 'video') {
|
|
|
- this.myInd = this.myInd > 0 ? this.myInd - 1 : this.curList.length - 1;
|
|
|
- } else {
|
|
|
- this.swiper?.slidePrev();
|
|
|
- }
|
|
|
- },
|
|
|
- handleNext() {
|
|
|
- if (this.myType === 'video') {
|
|
|
- this.myInd = this.myInd < this.curList.length - 1 ? this.myInd + 1 : 0;
|
|
|
- } else {
|
|
|
- this.swiper?.slideNext();
|
|
|
- }
|
|
|
+
|
|
|
+ handlePreview(idx) {
|
|
|
+ this.$viewerApi({
|
|
|
+ images: [this.curList[idx]],
|
|
|
+ });
|
|
|
},
|
|
|
},
|
|
|
};
|
|
@@ -275,4 +262,8 @@
|
|
|
|
|
|
<style lang="scss">
|
|
|
@use './index.scss';
|
|
|
+
|
|
|
+ .viewer-button.viewer-close {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
</style>
|