效果图
DEMO
组件(子组件改为自己的路径和名称)
<template>
<div class="box">
<ImageViewr ref="ImageViewrRef" :imageUrl="url" />
<button @click="reset">重置</button>
</div>
</template>
<script>
import ImageViewr from './components/ImageViewr.vue'
export default {
data() {
return {
url:'https://yaoliangliang-oss.oss-cn-beijing.aliyuncs.com/efa6c859-83cd-4749-89e3-667bbcebbd03.jpg'
}
},
methods: {
reset(){
this.$refs.ImageViewrRef.resetImage();
}
},
components:{ImageViewr,},
computed:{},
watch:{},
created() {},
}
</script>
<style lang="scss" scoped>
.box{
width: 500px;
height: 400px;
border: 1px solid red;
}
button{
position: absolute;
top: 320px;
}
</style>
子组件
<template>
<div class="imageView" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseleave="onMouseUp" @mouseup="onMouseUp">
<img :src="imageUrl" ref="image" @wheel="onWheel">
</div>
</template>
<script>
export default {
props: {
imageUrl: {
type: String,
require: true,
},
},
data() {
return {
currentScale: 1,// 当前缩放比例
isDragging: false,// 是否正在拖拽图片
startX: 0, // 拖拽起始点x坐标
startY: 0, // 拖拽起始点y坐标
translateX: 0, // 图片平移x方向距离
translateY: 0, // 图片平移y方向距离
dragSpeed: 0.3,// 拖拽速度
zoomSpeed: 0.1, //控制缩放速度
maxScale: 5, //最大缩放值
minScale: 0.1, //最小缩放值
};
},
methods: {
// 鼠标按下事件处理函数
onMouseDown(e) {
e.preventDefault();
this.isDragging = true;
this.startX = e.clientX;
this.startY = e.clientY;
this.$refs.image.style.cursor = "grabbing";
},
// 鼠标移动事件处理函数
onMouseMove(e) {
if (!this.isDragging) return;
const deltaX = (e.clientX - this.startX) * this.dragSpeed;
const deltaY = (e.clientY - this.startY) * this.dragSpeed;
this.translateX += deltaX;
this.translateY += deltaY;
this.$refs.image.style.transform = `scale(${this.currentScale}) translate(${this.translateX}px, ${this.translateY}px)`;
this.startX = e.clientX;
this.startY = e.clientY;
},
// 鼠标松开事件处理函数
onMouseUp() {
this.isDragging = false;
this.$refs.image.style.cursor = "grab";
},
// 鼠标滚轮事件处理函数
onWheel(e) {
e.preventDefault();
const delta = e.deltaY > 0 ? -1 : 1;
this.currentScale = Math.min(this.maxScale, Math.max(this.minScale, this.currentScale + delta * this.zoomSpeed));
this.$refs.image.style.transform = `scale(${this.currentScale}) translate(${this.translateX}px, ${this.translateY}px)`;
},
// 重置图片缩放和移动
resetImage() {
this.currentScale = 1;
this.translateX = 0;
this.translateY = 0;
this.$refs.image.style.transform = "scale(1) translate(0, 0)";
},
},
};
</script>
<style lang="scss" scoped>
.imageView {
width: 100%;
height: 100%;
overflow: hidden;
}
.imageView .elImageclass {
width: 100%;
height: 100%;
touch-action: none;
user-drag: none;
-webkit-user-drag: none;
}
img {
width: 100%;
height: 100%;
cursor: grab;
object-fit: contain !important;
}
</style>