|
@@ -1,61 +1,241 @@
|
|
|
<template>
|
|
|
- <div class="txtcon">
|
|
|
- <div class="title">
|
|
|
- <i class="iconfont icon-material_text" />
|
|
|
- {{ currentTag.hotspotTitle }}
|
|
|
+ <div class="imagetext-container">
|
|
|
+ <div class="metas-imagetext">
|
|
|
+ <div class="image-content">
|
|
|
+ <Swiper
|
|
|
+ :pagination="{
|
|
|
+ type: 'fraction',
|
|
|
+ }"
|
|
|
+ :zoom="true"
|
|
|
+ class="mySwiper"
|
|
|
+ :modules="modules"
|
|
|
+ :slides-per-view="1"
|
|
|
+ :free-mode="true"
|
|
|
+ >
|
|
|
+ <swiper-slide
|
|
|
+ v-for="(item, index) in currentTag.imageTextInfo.imageList"
|
|
|
+ :key="index"
|
|
|
+ >
|
|
|
+ <img :src="item.ossPath" />
|
|
|
+ </swiper-slide>
|
|
|
+ </Swiper>
|
|
|
+ <div class="audio-control" v-if="hasAudio">
|
|
|
+ <ui-icon
|
|
|
+ @click="pauseAudio"
|
|
|
+ type="player_pause"
|
|
|
+ v-if="isPlaying"
|
|
|
+ ></ui-icon>
|
|
|
+ <ui-icon @click="playAudio" type="player_playback" v-else></ui-icon>
|
|
|
+ <span class="timeline">{{ time }} / {{ audioAllTime }}</span>
|
|
|
+ <audio
|
|
|
+ id="audioTag"
|
|
|
+ class="noshow"
|
|
|
+ autoplay
|
|
|
+ :src="currentTag.imageTextInfo.audio.ossPath"
|
|
|
+ ></audio>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="text-content">
|
|
|
+ <div v-html="currentTag.imageTextInfo.text"></div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="txtbody" v-html="currentTag.articleInfo.html"></div>
|
|
|
</div>
|
|
|
</template>
|
|
|
-
|
|
|
<script setup>
|
|
|
-import { computed, onMounted } from "vue";
|
|
|
+import {
|
|
|
+ reactive,
|
|
|
+ nextTick,
|
|
|
+ onMounted,
|
|
|
+ ref,
|
|
|
+ computed,
|
|
|
+ onUnmounted,
|
|
|
+ unref,
|
|
|
+} from "vue";
|
|
|
import { useStore } from "vuex";
|
|
|
+import { useI18n, getLocale } from "@/i18n";
|
|
|
+import { Swiper, SwiperSlide } from "swiper/vue";
|
|
|
+import { Pagination, Navigation } from "swiper";
|
|
|
+// Import Swiper styles
|
|
|
+import "swiper/css";
|
|
|
+// import "swiper/swiper.scss";
|
|
|
+// swiper-bundle.min.css 决定了小圆点和左右翻页标签,如果不需要可以不引用
|
|
|
+
|
|
|
const store = useStore();
|
|
|
+const { t } = useI18n({ useScope: "global" });
|
|
|
|
|
|
const currentTag = computed(() => store.getters["tags/currentTag"]);
|
|
|
|
|
|
+const modules = ref([Pagination, Navigation]);
|
|
|
+const hasAudio = computed(
|
|
|
+ () => currentTag.value.imageTextInfo.audio.ossPath.length > 0
|
|
|
+);
|
|
|
+const time = ref("00:00");
|
|
|
+const audioAllTime = ref("");
|
|
|
+const isPlaying = ref(false);
|
|
|
+
|
|
|
+function transTime(time) {
|
|
|
+ var duration = parseInt(time);
|
|
|
+ var minute = parseInt(duration / 60);
|
|
|
+ var sec = (duration % 60) + "";
|
|
|
+ var isM0 = ":";
|
|
|
+ if (minute == 0) {
|
|
|
+ minute = "00";
|
|
|
+ } else if (minute < 10) {
|
|
|
+ minute = "0" + minute;
|
|
|
+ }
|
|
|
+ if (sec.length == 1) {
|
|
|
+ sec = "0" + sec;
|
|
|
+ }
|
|
|
+ return minute + isM0 + sec;
|
|
|
+}
|
|
|
+onMounted(() => {
|
|
|
+ const audio = document.querySelector("#audioTag");
|
|
|
+ nextTick(() => {
|
|
|
+ if (unref(hasAudio)) {
|
|
|
+ audio.addEventListener("loadedmetadata", (e) => {
|
|
|
+ audioAllTime.value = transTime(e.currentTarget.duration);
|
|
|
+ console.log("e", unref(audioAllTime));
|
|
|
+ isPlaying.value = true;
|
|
|
+ });
|
|
|
+
|
|
|
+ console.log("audio", audio);
|
|
|
+ audio.addEventListener(
|
|
|
+ "playing",
|
|
|
+ function (e) {
|
|
|
+ isPlaying.value = true;
|
|
|
+ },
|
|
|
+ false
|
|
|
+ );
|
|
|
+ audio.addEventListener(
|
|
|
+ "pause",
|
|
|
+ function (e) {
|
|
|
+ isPlaying.value = false;
|
|
|
+ },
|
|
|
+ false
|
|
|
+ );
|
|
|
+ audio.addEventListener(
|
|
|
+ "timeupdate",
|
|
|
+ function (event) {
|
|
|
+ time.value = transTime(event.target.currentTime);
|
|
|
+ },
|
|
|
+ false
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+const playAudio = () => {
|
|
|
+ const audio = document.querySelector("#audioTag");
|
|
|
+ audio && audio.play();
|
|
|
+};
|
|
|
+const pauseAudio = () => {
|
|
|
+ const audio = document.querySelector("#audioTag");
|
|
|
+ audio && audio.pause();
|
|
|
+};
|
|
|
+onUnmounted(() => {
|
|
|
+ pauseAudio();
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped>
|
|
|
-.txtcon {
|
|
|
- display: flex;
|
|
|
- align-items: flex-start;
|
|
|
- justify-content: center;
|
|
|
- height: 100%;
|
|
|
+<style lang="scss">
|
|
|
+.imagetext-container {
|
|
|
+ overflow-y: scroll;
|
|
|
+ height: calc(100vh - 50px);
|
|
|
width: 100%;
|
|
|
- padding-top: 70px;
|
|
|
-
|
|
|
- .txtbody {
|
|
|
- width: 744px;
|
|
|
- background: rgba(0, 0, 0, 0.6);
|
|
|
- border-radius: 10px;
|
|
|
- font-size: 14px;
|
|
|
- color: #fff;
|
|
|
- padding: 30px;
|
|
|
- max-height: calc(100vh - 100px);
|
|
|
- overflow-y: auto;
|
|
|
- line-height: 1.5;
|
|
|
- :deep(p) {
|
|
|
- line-height: 24px;
|
|
|
+ overflow-x: hidden;
|
|
|
+}
|
|
|
+.metas-imagetext {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ min-height: 180%;
|
|
|
+ .image-content {
|
|
|
+ height: 80vh;
|
|
|
+ width: 100%;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ .mySwiper {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ .swiper-slide {
|
|
|
+ text-align: center;
|
|
|
+ font-size: 18px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .swiper-slide img {
|
|
|
+ display: block;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: contain;
|
|
|
+ }
|
|
|
+
|
|
|
+ .audio-control {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 50px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: rgba(0, 0, 0, 0.6);
|
|
|
+ width: 122px;
|
|
|
+ height: 32px;
|
|
|
+ background: rgba(0, 0, 0, 0.4);
|
|
|
+ opacity: 1;
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.2);
|
|
|
+ left:70%;
|
|
|
+ transform: translateX(-70%);
|
|
|
+ line-height: 32px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ .iconfont {
|
|
|
+ margin-left: 0;
|
|
|
+ color: #fff;
|
|
|
+ margin-right: 2px;
|
|
|
+ }
|
|
|
+ .timeline {
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- .title {
|
|
|
- position: absolute;
|
|
|
- left: 20px;
|
|
|
- top: 20px;
|
|
|
- height: 36px;
|
|
|
- line-height: 36px;
|
|
|
- padding: 0 16px;
|
|
|
- background: rgba(0, 0, 0, 0.6);
|
|
|
- border-radius: 20px;
|
|
|
- color: #fff;
|
|
|
- font-size: 14px;
|
|
|
- z-index: 999;
|
|
|
- > i {
|
|
|
- margin-right: 4px;
|
|
|
+ .text-content {
|
|
|
+ background-color: #fff;
|
|
|
+ box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3);
|
|
|
+ min-height: 90vh;
|
|
|
+ padding: 30px 20px 25px;
|
|
|
+ word-wrap: break-word;
|
|
|
+ border-top-left-radius: 10px;
|
|
|
+ border-top-right-radius: 10px;
|
|
|
+ position: relative;
|
|
|
+ &::before {
|
|
|
+ content: "";
|
|
|
+ width: 35px;
|
|
|
+ height: 4px;
|
|
|
+ background: #444444;
|
|
|
+ border-radius: 13px 13px 13px 13px;
|
|
|
+ opacity: 1;
|
|
|
+ position: absolute;
|
|
|
+ top: 14px;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+.swiper-pagination {
|
|
|
+ width: 56px;
|
|
|
+ height: 32px;
|
|
|
+ line-height: 30px;
|
|
|
+ background: rgba(0, 0, 0, 0.4);
|
|
|
+ opacity: 1;
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.2);
|
|
|
+ color: #fff;
|
|
|
+ border-radius: 15px;
|
|
|
+ left: 20%;
|
|
|
+ transform: translateX(-20%);
|
|
|
+ bottom: 50px;
|
|
|
+ .swiper-pagination-total {
|
|
|
+ color: #858586;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|