需求:点击预览pdf和图片,模拟element预览图片效果
使用到了swiper版本7.2.0 和阿里图标库图标
swiper需要在main.js里引入
import 'swiper/swiper-bundle.min.css';
import "swiper/swiper-bundle.min.js";
html部分
<template>
<div class="mask left" @mousewheel.prevent="rollImg">
<div class="swiper mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="(item, index) in props.srcList" :key="index">
<embed v-if="item.endsWith('.pdf') == true" :src="item" type />
<div class="img-box" v-else>
<img :src="item" alt class="Img" :draggable="false" id="Img" @mousedown.stop="handleMove" />
<div class="img-box-button">
<div @click="handleRotate('负')">
<svg class="icons" aria-hidden="true">
<use xlink:href="#lhgj-rotate-left" />
</svg>
</div>
<div @click="handleScale(2)">
<svg class="icons" aria-hidden="true">
<use xlink:href="#lhgj-fangda" />
</svg>
</div>
<div @click="handleScale(1)">
<svg class="icons" aria-hidden="true">
<use xlink:href="#lhgj-suoxiao" />
</svg>
</div>
<div @click="handleRotate('正')">
<svg class="icons" aria-hidden="true">
<use xlink:href="#lhgj-rotate-right" />
</svg>
</div>
</div>
</div>
</div>
</div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
<div class="delete" @click="previewClose">
<svg class="icons" aria-hidden="true">
<use xlink:href="#lhgj-chacha" />
</svg>
</div>
</div>
</template>
js部分
<script setup>
import Swiper, { Navigation } from "swiper"
import { defineEmits, defineProps, onMounted, ref } from "vue"
Swiper.use([Navigation])
const emits = defineEmits(["previewClose"])
const props = defineProps({
srcList: {
type: Array,
default: () => [],
},
})
let deg = ref(0)
let activeIndex = ref(0)
let scaleValue = ref(1) // 放大倍数
let scaleNumber = ref(1) // 放大倍数变化的值
const previewClose = () => {
emits("previewClose")
}
// 点击旋转
const handleRotate = (e) => {
if (e == "负") {
deg.value -= 90
} else {
deg.value += 90
}
var img = document.getElementsByClassName("Img")[activeIndex.value]
img.style.transform =
"translateX(-50%) scale(" +
scaleValue.value +
") rotate(" +
deg.value +
"deg)"
}
// 点击放大缩小
const handleScale = (e) => {
var img = document.getElementsByClassName("Img")[activeIndex.value]
if (e == 2) {
// 放大
scaleValue.value = scaleNumber.value || e
scaleValue.value += 0.2
scaleNumber.value = scaleValue.value
img.style.transform =
"translateX(-50%) scale(" +
scaleValue.value +
") rotate(" +
deg.value +
"deg)"
} else if (e == 1) {
// 缩小
scaleValue.value = scaleNumber.value || e
scaleValue.value -= 0.2
scaleNumber.value = scaleValue.value
img.style.transform =
"translateX(-50%) scale(" +
scaleValue.value +
") rotate(" +
deg.value +
"deg)"
}
}
// 鼠标拖动图片
const handleMove = (e) => {
var left = document.querySelector(".left")
var img = document.getElementsByClassName("Img")[activeIndex.value]
var x = e.pageX - img.offsetLeft
var y = e.pageY - img.offsetTop
// 添加鼠标移动事件
left.addEventListener("mousemove", move)
function move(e) {
img.style.left = e.pageX - x + "px"
img.style.top = e.pageY - y + "px"
}
// 添加鼠标抬起事件,鼠标抬起,将事件移除
img.addEventListener("mouseup", function () {
left.removeEventListener("mousemove", move)
})
// 鼠标离开父级元素,把事件移除
left.addEventListener("mouseout", function () {
left.removeEventListener("mousemove", move)
})
}
// 鼠标滚动图片放大缩小
const rollImg = () => {
var img = document.getElementsByClassName("Img")[activeIndex.value]
// 判断滚轮方向
if (event.wheelDelta > 0) scaleNumber.value += 0.2
else scaleNumber.value -= 0.2
// 修改图片scalc
img.style.transform =
"translateX(-50%) scale(" +
scaleNumber.value +
") rotate(" +
deg.value +
"deg)"
return false
}
// 初始化图片状态
const initPictureStatus = () => {
deg.value = 0
scaleValue.value = 1
scaleNumber.value = 1
var img = document.getElementsByClassName("Img")[activeIndex.value]
img.style.transform =
"translateX(-50%) scale(" +
scaleValue.value +
") rotate(" +
deg.value +
"deg)"
}
onMounted(() => {
var img = document.getElementsByClassName("Img")[0]
new Swiper(".mySwiper", {
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev",
},
touchStartPreventDefault: false,
noSwipingSelector: "img",
on: {
slideChange: function () {
activeIndex.value = this.activeIndex
initPictureStatus()
},
},
})
})
</script>
css部分
<style scoped>
.swiper {
width: 100%;
height: 100%;
}
.mask {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
position: fixed;
top: 0;
left: 0;
z-index: 99999;
}
.img-box {
height: 100%;
position: relative;
}
.img-box > img {
max-width: 60%;
max-height: 86%;
/* margin: 0 auto; */
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
z-index: 999999;
}
.img-box-button {
position: absolute;
bottom: 24px;
left: 50%;
transform: translateX(-50%);
width: 340px;
height: 50px;
background: rgba(0, 0, 0, 0.2);
border-radius: 30px;
display: flex;
align-items: center;
justify-content: center;
z-index: 999999;
}
embed {
width: 80%;
height: 100%;
margin-left: 50%;
transform: translateX(-50%);
}
.delete {
position: absolute;
top: 20px;
right: 20px;
font-size: 24px;
font-weight: bold;
cursor: pointer;
z-index: 999999;
}
.delete > .icons :hover {
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
}
.icons {
fill: #fff;
margin: 0 10px !important;
}
.swiper-button-next,
.swiper-button-prev {
color: #fff !important;
}
</style>