|
@@ -6,47 +6,71 @@
|
|
|
</div>
|
|
|
|
|
|
<div class="realimgcon" :class="{ fullimgcon: objectFit === 'contain' }">
|
|
|
- <img class="image" :src="currentTag.image[currentIndex].ossPath" :style="imageStyle"
|
|
|
- @wheel.prevent="onImageWheel" />
|
|
|
+ <img
|
|
|
+ class="image"
|
|
|
+ :src="currentTag.image[currentIndex].ossPath"
|
|
|
+ :style="imageStyle"
|
|
|
+ @wheel.prevent="onImageWheel"
|
|
|
+ />
|
|
|
</div>
|
|
|
|
|
|
<div class="toolbar">
|
|
|
- <i v-if="currentTag.image.length > 1" class="iconfont icon-material_preview_previous hover-tips"
|
|
|
- :class="{ disabled: currentIndex === 0 }" @click="onClickPrevious()">
|
|
|
+ <i
|
|
|
+ v-if="currentTag.image.length > 1"
|
|
|
+ class="iconfont icon-material_preview_previous hover-tips"
|
|
|
+ :class="{ disabled: currentIndex === 0 }"
|
|
|
+ @click="onClickPrevious()"
|
|
|
+ >
|
|
|
<div>
|
|
|
- <div class="remark">{{$t('common.prev')}}</div>
|
|
|
+ <div class="remark">{{ $t("common.prev") }}</div>
|
|
|
</div>
|
|
|
</i>
|
|
|
- <i v-if="currentTag.image.length > 1" class="iconfont icon-material_preview_next1 hover-tips append-splitter"
|
|
|
- :class="{ disabled: currentIndex === currentTag.image.length - 1 }" @click="onClickNext()">
|
|
|
+ <i
|
|
|
+ v-if="currentTag.image.length > 1"
|
|
|
+ class="iconfont icon-material_preview_next1 hover-tips append-splitter"
|
|
|
+ :class="{ disabled: currentIndex === currentTag.image.length - 1 }"
|
|
|
+ @click="onClickNext()"
|
|
|
+ >
|
|
|
<div>
|
|
|
- <div class="remark">{{$t('common.next')}}</div>
|
|
|
+ <div class="remark">{{ $t("common.next") }}</div>
|
|
|
</div>
|
|
|
</i>
|
|
|
- <i :class="{ disabled: scaleRate >= 2 }" class="iconfont icon-material_preview_enlarge hover-tips"
|
|
|
- @click="onClickZoomIn()">
|
|
|
+ <i
|
|
|
+ :class="{ disabled: scaleRate >= maxScaleRate }"
|
|
|
+ class="iconfont icon-material_preview_enlarge hover-tips"
|
|
|
+ @click="onClickZoomIn()"
|
|
|
+ >
|
|
|
<div>
|
|
|
- <div class="remark">{{$t('common.zoomIn')}}</div>
|
|
|
+ <div class="remark">{{ $t("common.zoomIn") }}</div>
|
|
|
</div>
|
|
|
</i>
|
|
|
<span>{{ Math.floor(scaleRate.toFixed(2) * 100) }}%</span>
|
|
|
- <i :class="{ disabled: scaleRate <= 0.5 }" class="iconfont icon-material_preview_narrow hover-tips"
|
|
|
- @click="onClickZoomOut()">
|
|
|
+ <i
|
|
|
+ :class="{ disabled: scaleRate <= 0.5 }"
|
|
|
+ class="iconfont icon-material_preview_narrow hover-tips"
|
|
|
+ @click="onClickZoomOut()"
|
|
|
+ >
|
|
|
<div>
|
|
|
- <div class="remark">{{$t('common.zoomOut')}}</div>
|
|
|
+ <div class="remark">{{ $t("common.zoomOut") }}</div>
|
|
|
</div>
|
|
|
</i>
|
|
|
|
|
|
- <i v-if="canFullScreen && objectFit === 'scale-down'"
|
|
|
- class="iconfont icon-material_preview_full_screen hover-tips" @click="onClickFullScreen()">
|
|
|
+ <i
|
|
|
+ v-if="canFullScreen && objectFit === 'scale-down'"
|
|
|
+ class="iconfont icon-material_preview_full_screen hover-tips"
|
|
|
+ @click="onClickFullScreen()"
|
|
|
+ >
|
|
|
<div>
|
|
|
- <div class="remark">{{$t('common.fullScene')}}</div>
|
|
|
+ <div class="remark">{{ $t("common.fullScene") }}</div>
|
|
|
</div>
|
|
|
</i>
|
|
|
- <i v-if="canFullScreen && objectFit === 'contain'" class="iconfont icon-material_preview_drop_out hover-tips"
|
|
|
- @click="onClickCancelFullScreen()">
|
|
|
+ <i
|
|
|
+ v-if="canFullScreen && objectFit === 'contain'"
|
|
|
+ class="iconfont icon-material_preview_drop_out hover-tips"
|
|
|
+ @click="onClickCancelFullScreen()"
|
|
|
+ >
|
|
|
<div>
|
|
|
- <div class="remark">{{$t('common.exitFullScene')}}</div>
|
|
|
+ <div class="remark">{{ $t("common.exitFullScene") }}</div>
|
|
|
</div>
|
|
|
</i>
|
|
|
</div>
|
|
@@ -55,78 +79,82 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
-
|
|
|
<script setup>
|
|
|
-import { reactive, defineEmits, onBeforeMount, onMounted, ref, watchEffect, computed, watch, nextTick } from "vue";
|
|
|
+import {
|
|
|
+ reactive,
|
|
|
+ defineEmits,
|
|
|
+ onBeforeMount,
|
|
|
+ onMounted,
|
|
|
+ ref,
|
|
|
+ watchEffect,
|
|
|
+ computed,
|
|
|
+ watch,
|
|
|
+ nextTick,
|
|
|
+} from "vue";
|
|
|
import { useStore } from "vuex";
|
|
|
const store = useStore();
|
|
|
|
|
|
+const scaleRate = ref(1);
|
|
|
+const maxScaleRate = ref(5);
|
|
|
+const objectFit = ref("scale-down");
|
|
|
|
|
|
-const scaleRate = ref(1)
|
|
|
-
|
|
|
-const objectFit = ref('scale-down')
|
|
|
-
|
|
|
-const canFullScreen = ref(true)
|
|
|
+const canFullScreen = ref(true);
|
|
|
|
|
|
const imageStyle = computed(() => {
|
|
|
return {
|
|
|
transform: `scale(${scaleRate.value})`,
|
|
|
objectFit: objectFit.value,
|
|
|
- }
|
|
|
-})
|
|
|
+ };
|
|
|
+});
|
|
|
|
|
|
-const currentTag = computed(() => store.getters['tags/currentTag'])
|
|
|
+const currentTag = computed(() => store.getters["tags/currentTag"]);
|
|
|
|
|
|
-const currentIndex = ref(0)
|
|
|
+const currentIndex = ref(0);
|
|
|
|
|
|
const onImageWheel = (e) => {
|
|
|
-
|
|
|
if (e.deltaY < 0) {
|
|
|
- let scle = scaleRate.value * 1.1
|
|
|
- if (scle > 2) {
|
|
|
- scaleRate.value = 2
|
|
|
+ let scle = scaleRate.value * 1.1;
|
|
|
+ if (scle > maxScaleRate.value) {
|
|
|
+ scaleRate.value = maxScaleRate.value;
|
|
|
} else {
|
|
|
- scaleRate.value = scle
|
|
|
+ scaleRate.value = scle;
|
|
|
}
|
|
|
} else {
|
|
|
- let scle = scaleRate.value * 0.9
|
|
|
+ let scle = scaleRate.value * 0.9;
|
|
|
if (scle < 0.5) {
|
|
|
- scaleRate.value = 0.5
|
|
|
+ scaleRate.value = 0.5;
|
|
|
} else {
|
|
|
- scaleRate.value = scle
|
|
|
+ scaleRate.value = scle;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const onClickZoomIn = () => {
|
|
|
- scaleRate.value = Math.min(scaleRate.value * 1.1, 2)
|
|
|
-}
|
|
|
+ scaleRate.value = Math.min(scaleRate.value * 1.1, maxScaleRate.value);
|
|
|
+};
|
|
|
const onClickZoomOut = () => {
|
|
|
- scaleRate.value = Math.max(scaleRate.value * 0.9, 0.5)
|
|
|
-}
|
|
|
+ scaleRate.value = Math.max(scaleRate.value * 0.9, 0.5);
|
|
|
+};
|
|
|
|
|
|
const onClickPrevious = () => {
|
|
|
if (currentIndex.value > 0) {
|
|
|
- currentIndex.value--
|
|
|
+ currentIndex.value--;
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
const onClickNext = () => {
|
|
|
if (currentIndex.value < currentTag.value.image.length - 1) {
|
|
|
- currentIndex.value++
|
|
|
+ currentIndex.value++;
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const onClickFullScreen = () => {
|
|
|
- scaleRate.value = 1
|
|
|
- objectFit.value = 'contain'
|
|
|
-}
|
|
|
+ scaleRate.value = 1;
|
|
|
+ objectFit.value = "contain";
|
|
|
+};
|
|
|
const onClickCancelFullScreen = () => {
|
|
|
- scaleRate.value = 1
|
|
|
- objectFit.value = 'scale-down'
|
|
|
-}
|
|
|
-
|
|
|
+ scaleRate.value = 1;
|
|
|
+ objectFit.value = "scale-down";
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -137,7 +165,7 @@ const onClickCancelFullScreen = () => {
|
|
|
height: 100%;
|
|
|
width: 100%;
|
|
|
|
|
|
- >video {
|
|
|
+ > video {
|
|
|
max-width: 960px;
|
|
|
height: 540px;
|
|
|
}
|
|
@@ -157,7 +185,7 @@ const onClickCancelFullScreen = () => {
|
|
|
font-size: 14px;
|
|
|
z-index: 999;
|
|
|
|
|
|
- >i {
|
|
|
+ > i {
|
|
|
margin-right: 4px;
|
|
|
}
|
|
|
}
|
|
@@ -192,7 +220,7 @@ const onClickCancelFullScreen = () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- >span {
|
|
|
+ > span {
|
|
|
color: #fff;
|
|
|
text-align: center;
|
|
|
display: inline-block;
|
|
@@ -235,26 +263,22 @@ const onClickCancelFullScreen = () => {
|
|
|
.fullimgcon {
|
|
|
top: 0;
|
|
|
height: 100%;
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-
|
|
|
.hover-tips,
|
|
|
.hover-tips-warn {
|
|
|
position: relative;
|
|
|
font-size: 18px;
|
|
|
|
|
|
&:hover {
|
|
|
- >div {
|
|
|
+ > div {
|
|
|
display: block;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// tip的方框
|
|
|
- >div {
|
|
|
+ > div {
|
|
|
background: rgba(0, 0, 0, 0.6);
|
|
|
border: none;
|
|
|
cursor: default;
|
|
@@ -292,19 +316,22 @@ const onClickCancelFullScreen = () => {
|
|
|
color: #fff;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
.btnmask {
|
|
|
- width: 100%;
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- pointer-events: none;
|
|
|
- opacity: 0.5;
|
|
|
- z-index: 1;
|
|
|
- height: 60px;
|
|
|
- background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.7) 52%, #000000 100%);
|
|
|
- }
|
|
|
-</style>
|
|
|
+ width: 100%;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ pointer-events: none;
|
|
|
+ opacity: 0.5;
|
|
|
+ z-index: 1;
|
|
|
+ height: 60px;
|
|
|
+ background: linear-gradient(
|
|
|
+ 180deg,
|
|
|
+ rgba(0, 0, 0, 0) 0%,
|
|
|
+ rgba(0, 0, 0, 0.7) 52%,
|
|
|
+ #000000 100%
|
|
|
+ );
|
|
|
+}
|
|
|
+</style>
|