vue实现图片放大缩小可鼠标拖动,鼠标滚轮控制放大缩小完整代码付效果图
效果图:
创建一个ImageViewer 组件,并且在当前页面引用完整代码如下:
代码引用:
<template>
<view>
<image-viewer :imageUrl="imageUrl" />
</view>
</template>
<script>
import ImageViewer from '@/components/image-viewer.vue';
export default {
components: {
ImageViewer,
},
data() {
return {
imageUrl: 'https://profile-avatar.csdnimg.cn/2c10a3762fec44aea81f7c8fc58921af_qq_35713752.jpg!1', // 替换为你的图片地址
};
},
};
</script>
组件代码:
<template>
<view class="container">
<view class="movable-area" id="movableArea" @mousedown="startDrag" @mousemove="onDrag" @mouseup="endDrag" @mouseleave="endDrag">
<image :src="imageUrl" class="image" :style="{
transform: `translate(${translateX}px, ${translateY}px) scale(${scale})`,
cursor: dragging ? 'grabbing' : 'grab'
}" />
</view>
<view class="controls">
<button @click="setScale(5)">放大5倍</button>
<button @click="setScale(10)">放大10倍</button>
<button @click="setScale(20)">放大20倍</button>
<button @click="setScale(30)">放大30倍</button>
<button @click="incrementScale(0.5)">放大</button>
<button @click="incrementScale(-0.5)">缩小</button>
</view>
</view>
</template>
<script>
export default {
props: {
imageUrl: {
type: String,
required: true,
},
},
data() {
return {
scale: 1,
maxScale: 30,
translateX: 0,
translateY: 0,
dragging: false,
startX: 0,
startY: 0,
initialX: 0,
initialY: 0,
};
},
mounted() {
// 监听滚轮事件
this.movableArea = document.getElementById('movableArea');
this.movableArea.addEventListener('wheel', this.onWheel);
},
beforeDestroy() {
// 组件销毁前移除监听器
this.movableArea.removeEventListener('wheel', this.onWheel);
},
methods: {
onWheel(event) {
const delta = event.deltaY > 0 ? -0.5 : 0.5;
console.log('delta', event.deltaY);
this.incrementScale(delta);
},
setScale(value) {
this.scale = value;
},
incrementScale(value) {
this.scale = Math.min(Math.max(this.scale + value, 1), this.maxScale);
},
startDrag(event) {
this.dragging = true;
this.startX = event.clientX;
this.startY = event.clientY;
this.initialX = this.translateX;
this.initialY = this.translateY;
document.addEventListener('mousemove', this.onDrag);
document.addEventListener('mouseup', this.endDrag);
},
onDrag(event) {
console.log('鼠标移动', this.dragging, event);
if (this.dragging) {
const deltaX = event.clientX - this.startX;
const deltaY = event.clientY - this.startY;
this.translateX = this.initialX + deltaX;
this.translateY = this.initialY + deltaY;
}
},
endDrag() {
this.dragging = false;
document.removeEventListener('mousemove', this.onDrag);
document.removeEventListener('mouseup', this.endDrag);
},
},
};
</script>
<style scoped>
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.movable-area {
width: 100%;
height: 400px;
position: relative;
overflow: hidden;
border: 1px solid #ddd;
}
.image {
user-select: none;
width: 100px;
height: 100px;
}
.controls {
margin-top: 20px;
display: flex;
flex-direction: row;
justify-content: space-around;
width: 100%;
}
button {
padding: 10px;
margin: 0 5px;
}
</style>