<template>
<div v-if="showViewer" class="previewImg" :style="'top: '+ imgTop + 'px; left:'+ imgLeft+'px'" @mousewheel.prevent="wheelChange" @mousedown.self="mousedown" @mousemove.self="mousemove" @mouseleave.self="mouseleave" @mouseup.self="mouseleave">
<span class="title">{{ titleName }}</span>
<img src="../../assets/images/close.png" class="close-img" @click="doCloseImgView">
<div ref="img" class="img-view">
<div @mousedown.prevent="imgDownChange" @mousemove.prevent="imgMoveChange" @mouseleave.prevent="imgLeaveChange" @mouseup.prevent="imgLeaveChange">
<el-image lazy :style="'top:'+ imgMarginTop +'px;left:'+ imgMarginLeft +'px;transform:scale(' + imgWidth + ') rotate('+imgTransform+'deg);'" :src="url[imgIndex]" />
</div>
</div>
<template v-if="url.length > 1">
<div class="arrowRight" @click="arrowChange(2)">
<i class="el-icon-arrow-right" />
</div>
<div class="arrowRight" style="left:5%" @click="arrowChange(1)">
<i class="el-icon-arrow-left" />
</div>
</template>
<div class="operateBtn">
<i class="el-icon-zoom-out" @click="zoomOut(1)" />
<i class="el-icon-zoom-in" @click="zoomOut(2)" />
<i :class="fullStatus?'el-icon-c-scale-to-original':'el-icon-full-screen'" @click="fullScreen" />
<i class="el-icon-refresh-left" @click="imgRefresh(1)" />
<i class="el-icon-refresh-right" @click="imgRefresh(2)" />
</div>
</div>
</template>
<script>
/*
show-viewer: 是否展示状态,在需要展示时变为true 类型为布尔值
url: 图片的路径,类型为数组
imgIndex: 查看图片下标
fullscreenStatus: false 是否放大全屏
close-viewer: 关闭弹框事件 类型为方法 将布尔值变为false
closeViewer() {
this.showViewer = false
}
imgIndexChange 下标切换事件
imgChange(type) {
if (type === 1) {
this.imgIndex -= 1
} else if (type === 2) {
this.imgIndex += 1
}
}
<preview-img :show-viewer="" :url="" :close-viewer="" />
import PreviewImg from '@/components/PreviewImg'
components: {
PreviewImg
},
*/
export default {
name: 'Index',
props: {
showViewer: { // 是否展示
type: Boolean,
default: false
},
url: { // 展示图片路径
type: Array,
default: null
},
titleName: {
type: String,
default: '大图预览'
},
imgIndex: {
type: Number,
default: 0
},
fullscreenStatus: {
type: Boolean,
default: false
}
},
data() {
return {
imgTop: 100,
imgLeft: 500,
boxTop: 0,
boxLeft: 0,
mouseStatus: false,
boxStatus: true,
imgWidth: 0.5, // 图片放大比例
fullStatus: false, // 是否全屏显示
imgTransform: 0, // 旋转角度
imgStatus: false, // 图片拖动状态
imgMarginTop: 0, // 图片拖动marginTop
imgMarginLeft: 0, // 图片拖动marginLeft
imgScrollLeft: 0, // 图片按下位置left(用于计算)
imgScrollTop: 0 // 图片按下位置top(用于计算)
}
},
watch: {
showViewer(newVal) {
if (newVal && this.fullscreenStatus) {
this.fullStatus = this.fullscreenStatus
this.imgWidth = 1
}
}
},
mounted() {
if (this.fullscreenStatus) {
this.fullStatus = this.fullscreenStatus
this.imgWidth = 1
}
},
methods: {
arrowChange(type) {
// -1
this.resetVal()
if ((type === 1 && this.imgIndex !== 0) || (type === 2 && this.imgIndex !== this.url.length - 1)) {
this.$emit('imgIndexChange', type)
}
},
resetVal() {
this.imgWidth = 0.5
this.fullStatus = false
this.imgTransform = 0
this.imgStatus = false
this.imgMarginTop = 0
this.imgMarginLeft = 0
this.imgScrollLeft = 0
this.imgScrollTop = 0
},
// 图片旋转
imgRefresh(status) {
if (status === 1) {
this.imgTransform += 90
} else {
this.imgTransform -= 90
}
this.imgTransform = Math.abs(this.imgTransform) === 360 ? 0 : this.imgTransform
this.$refs.img.scrollTop = 0
this.$refs.img.scrollLeft = 0
},
// 图片放大缩小
zoomOut(status) {
if (status === 1) {
this.imgWidth = this.imgWidth <= 0.1 ? 0.1 : this.imgWidth - 0.2
} else if (status === 2) {
this.imgWidth += 0.2
}
},
// 全屏|缩小
fullScreen() {
this.fullStatus = !this.fullStatus
this.imgWidth = this.fullStatus ? 1 : 0.5
this.imgMarginTop = 0
this.imgMarginLeft = 0
},
// 滚轮滑动
wheelChange(e) {
const direction = e.deltaY > 0 ? 'down' : 'up'
if (direction === 'up') {
this.imgWidth += 0.2
} else {
this.imgWidth = this.imgWidth <= 0.1 ? 0.1 : this.imgWidth - 0.2
}
},
// 图片区域按下
imgDownChange(e) {
this.imgStatus = true
this.imgScrollLeft = e.pageX
this.imgScrollTop = e.pageY
},
// 离开图片区域
imgLeaveChange() {
this.imgStatus = false
},
// 图片移动
imgMoveChange(e) {
if (this.imgStatus) {
if (e.pageX < 0 && this.imgMarginLeft < 0) {
this.imgMarginLeft -= (e.pageX - this.imgScrollLeft)
} else {
this.imgMarginLeft += (e.pageX - this.imgScrollLeft)
}
if (e.pageY < 0 && this.imgMarginTop < 0) {
this.imgMarginTop -= (e.pageY - this.imgScrollTop)
} else {
this.imgMarginTop += (e.pageY - this.imgScrollTop)
}
this.imgScrollLeft = e.pageX
this.imgScrollTop = e.pageY
console.log(222, this.imgScrollLeft, this.imgScrollTop)
}
},
// 鼠标移出|鼠标抬起
mouseleave() {
if (this.mouseStatus) {
this.mouseStatus = false
}
},
// 鼠标按下
mousedown() {
this.mouseStatus = true
this.boxStatus = true
},
// 鼠标移动(弹框拖拽)
mousemove(e) {
if (this.mouseStatus) {
this.boxTop = (!this.boxStatus && this.boxTop) ? this.boxTop : e.screenY - Number(this.imgTop)
this.boxLeft = (!this.boxStatus && this.boxLeft) ? this.boxLeft : e.screenX - Number(this.imgLeft)
this.imgLeft = e.screenX - this.boxLeft
this.imgTop = e.screenY - this.boxTop
this.boxStatus = false
}
},
closeViewer() {
this.imgLeft = 500
this.imgTop = 100
},
doCloseImgView() {
this.resetVal()
this.$emit('closeViewer')
}
}
}
</script>
<style lang="scss" scoped>
@import '~@/styles/mixin.scss';
.operateBtn{
position: absolute;
z-index: 1;
display: flex;
align-items: center;
justify-content: space-around;
cursor: pointer;
box-sizing: border-box;
left: 50%;
bottom: 40px;
transform: translateX(-50%);
width: 282px;
padding: 10px 23px;
background-color: rgba(32, 31, 31, 0.8);
border-color: #fff;
border-radius: 22px;
i{
font-size: 23px;
color: #fff;
}
}
.title{
margin-left: 5px;
font-size:16px;
color:#222;
line-height:22px;
@include fontMedium;
}
.close-img{
width:24px;
float: right;
cursor: pointer;
}
.previewImg{
background:#fff;
width: 587px;
height: 667px;
position: fixed;
top: 20%;
left: 30%;
box-shadow:0px 2px 12px 0px rgba(0,0,0,0.1);
border-radius:4px;
overflow: hidden;
padding:20px;
z-index: 3000;
.img-view {
position: relative;
left: 0;
top: 0;
>div{
width: 543px;
height: 587px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
-webkit-app-region: no-drag
::-webkit-scrollbar {
width: 0px;
height: 10px;
background-color: #ccc;
}
img{
width: 100%;
}
}
}
}
.arrowRight{
width: 44px;
height: 44px;
font-size: 24px;
color: #fff;
background-color: #606266;
border-color: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
right: 5%;
top: 50%;
cursor: pointer;
}
</style>
vue 图片查看放大组件(包括拖拽,旋转,放大,切换下一张)
最新推荐文章于 2024-04-22 10:39:31 发布