vue实现PC端图片放大缩小可鼠标拖动,鼠标滚轮控制放大缩小完整代码付效果图

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>