组件
<template>
<!-- -->
<div class="imgCont"
ref="imgCont"
@mousewheel.prevent="rollImg($event)"
>
<div class="iconBtn">
<span class="refreshBtn">
<i class="el-icon-zoom-out"
@click.stop="outImg('out')"></i>
<i class="el-icon-zoom-in"
@click.stop="outImg('in')"></i>
<i class="el-image-viewer__actions__divider"></i>
<i :class="mode.icon" @click="toggleMode"></i>
<i class="el-image-viewer__actions__divider"></i>
<i @click.stop="rotate('left')"
class="el-icon-refresh-left"></i>
<i @click.stop="rotate('right')"
class="el-icon-refresh-right right"></i>
<slot name="addIcon"></slot>
</span>
</div>
<img class="bigImage"
ref="imgDiv"
@mousedown.stop.prevent="moveImg($event)"
id="img"
:src="url" />
</div>
</template>
<script>
const Mode = {
CONTAIN: {
name: "contain",
icon: "el-icon-full-screen"
},
ORIGINAL: {
name: "original",
icon: "el-icon-c-scale-to-original"
}
};
export default {
name: 'imgDeal',
props: {
url: {},
},
components: {},
data () {
return {
mode: Mode.CONTAIN,
// 图片参数
params: {
zoomVal: 1,
left: 0,
top: 0,
currentX: 0,
currentY: 0,
},
deg: 0,
};
},
computed: {
},
watch: {
},
created () {
this.restImg();
},
mounted () {
},
methods: {
//1:1自适应
toggleMode () {
const modeNames = Object.keys(Mode);
const modeValues = Object.values(Mode);
const index = modeValues.indexOf(this.mode);
const nextIndex = (index + 1) % modeNames.length;
this.mode = Mode[modeNames[nextIndex]];
if (this.mode.name == 'original') {
this.originalFunc();
} else {
this.restImg();
}
},
// mode==original 默认放大图片
originalFunc () {
this.params.zoomVal = 2;
this.restFunc();
},
// 初始化数据,重置数据
restImg () {
this.params.zoomVal = 1;
this.restFunc();
this.mode = Mode['CONTAIN'];
},
restFunc () {
this.params.left = 0;
this.params.top = 0;
this.params.currentX = 0;
this.params.currentY = 0;
this.deg = 0;
if (this.$refs.imgDiv) {
let img = this.$refs.imgDiv;
img.style.transform = `translate(-50%, -50%) scale(${this.params.zoomVal}) rotate(${this.deg}deg)`;
img.style.left = '50%';
img.style.top = '50%';
}
},
// 图片滚动放大
rollImg (event) {
this.params.zoomVal += event.wheelDelta / 1200;
this.rollFunc()
},
outImg (flag) {
if (flag == 'out') {
this.params.zoomVal -= 0.2;
} else {
this.params.zoomVal += 0.2;
}
this.rollFunc()
},
rollFunc () {
let e = this.$refs.imgDiv;
if (this.params.zoomVal >= 0.2) {
e.style.transform = `translate(-50%, -50%) scale(${this.params.zoomVal}) rotate(${this.deg}deg)`;
} else {
this.params.zoomVal = 0.2;
e.style.transform = `translate(-50%, -50%) scale(${this.params.zoomVal}) rotate(${this.deg}deg)`;
return false;
}
},
// 图片旋转
rotate (type) {
let res = this.$refs.imgDiv;
this.deg = type == 'right' ? this.deg + 90 : this.deg - 90
res.style.transform = `translate(-50%, -50%) scale(${this.params.zoomVal}) rotate(${this.deg}deg)`
},
// 图片移动
moveImg (e) {
// 获得该时间触发的时间戳
let mouseDate = new Date().getTime();
this.$emit('getMouseDate',mouseDate)
e.preventDefault()
// 获取元素
let imgWrap = this.$refs.imgCont
let img = this.$refs.imgDiv
let x = e.pageX - img.offsetLeft
let y = e.pageY - img.offsetTop
// 添加鼠标移动事件
imgWrap.addEventListener('mousemove', move)
function move (e) {
img.style.left = e.pageX - x + 'px'
img.style.top = e.pageY - y + 'px'
}
// 添加鼠标抬起事件,鼠标抬起,将事件移除
img.addEventListener('mouseup', () => {
imgWrap.removeEventListener('mousemove', move)
})
// 鼠标离开父级元素,把事件移除
imgWrap.addEventListener('mouseout', () => {
imgWrap.removeEventListener('mousemove', move)
})
},
},
};
</script>
<style scoped lang="scss">
.imgCont {
text-align: center;
vertical-align: middle;
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
.iconBtn {
position: absolute;
left: 0;
bottom: 0;
height: 35px;
line-height: 35px;
background-color: rgba(0, 0, 0, 0.2);
color: #fff;
width: 100%;
z-index: 100;
font-size: 20px;
.refreshBtn {
i {
cursor: pointer;
margin: 0 10px;
}
}
}
.bigImage {
max-width: 100%;
max-height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
cursor: move;
margin: 0 auto;
}
}
</style>
组件使用
import ImgDeal from "@/components/imgDeal.vue";
components: {
ImgDeal
},
<ImgDeal ref="imgDeal" :url="imgUrl"></ImgDeal>