当前位置: 首页 > news >正文

VUE3+TS实现图片缩放移动弹窗

完整代码

使用VUE3、TS,实现将图片通过鼠标拖拽缩放以及选择缩放比例。

<template><div><el-dialogv-model="dialogVisible"title="查看图片":close-on-click-modal="false":close-on-press-escape="false"fullscreenstyle="overflow: hidden;"><div style="margin-bottom: 10px;"><el-selectv-model="magnification"placeholder="请选择图片放大尺寸"size="large"style="width: 240px"@change="changePicSize"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"/></el-select></div><div class="img_area" ref="container" @wheel.prevent="handleWheel"@mousemove="handleDrag"@mouseup="endDrag"@mouseleave="endDrag"><img :style="imageStyle" class="auto-scale-image" :src="props.imgSrc" ref="image"@mousedown="startDrag"draggable="false"/></div><template #footer></template></el-dialog></div>
</template>
<script lang='ts' setup>// 显隐设置const props = defineProps<{modelValue: boolean,imgSrc:any}>()const emit = defineEmits<{(e: 'update:modelValue', value: boolean): void}>()const dialogVisible = computed({get: () => props.modelValue,set: (value) => emit('update:modelValue', value)})let magnification = $ref(null) as anylet options = [{value: 0.1,label: '0.1',},{value: 1,label: '1',},{value: 2,label: '2',},]const translate = ref({ x: 0, y: 0 });const scale = ref(1);const isDragging = ref(false);const container = ref<HTMLDivElement | null>(null);const step = ref(0.1)const minScale = ref(0.1) const maxScale = ref(3) const imageStyle = computed(() => ({transform: `scale(${scale.value}) translate(${translate.value.x}px, ${translate.value.y}px)`,transformOrigin: 'center center',cursor: isDragging.value ? 'grabbing' : 'grab'}));// 处理鼠标滚轮缩放const handleWheel = (e: WheelEvent) => {if (!container.value) return;const delta = e.deltaY > 0 ? -step.value : step.value;const newScale = Math.max(minScale.value, Math.min(maxScale.value, scale.value + delta));// 计算缩放中心点const rect = container.value.getBoundingClientRect();const mouseX = e.clientX - rect.left;const mouseY = e.clientY - rect.top;// 计算缩放后的偏移量,使鼠标位置保持相对不变const scaleRatio = newScale / scale.value;translate.value = {x: translate.value.x * scaleRatio + (1 - scaleRatio) * (mouseX - rect.width / 2 - translate.value.x),y: translate.value.y * scaleRatio + (1 - scaleRatio) * (mouseY - rect.height / 2 - translate.value.y)};scale.value = newScale;};// 响应式状态const image = ref<HTMLImageElement | null>(null);const startPos = ref({ x: 0, y: 0 });// 开始拖拽const startDrag = (e: MouseEvent) => {if (e.button !== 0) return; // 只响应左键isDragging.value = true;startPos.value = {x: e.clientX - translate.value.x,y: e.clientY - translate.value.y};e.preventDefault();};// 处理拖拽const handleDrag = (e: MouseEvent) => {if (!isDragging.value) return;let newX = e.clientX - startPos.value.x;let newY = e.clientY - startPos.value.y;translate.value = { x: newX, y: newY };};// 结束拖拽const endDrag = () => {isDragging.value = false;};// 通过选择器改变图片大小const changePicSize = () => {scale.value = magnification;centerImage();}// 居中图片const centerImage = () => {if (!container.value) return;const imageContainer = container.value;imageContainer.scrollLeft = (imageContainer.scrollWidth - imageContainer.clientWidth) / 2;imageContainer.scrollTop = (imageContainer.scrollHeight - imageContainer.clientHeight) / 2;};
</script>
<style scope lang="less">.img_area{width: 100%;height: calc(100vh - 130px);text-align: center;.auto-scale-image{max-width: 100%;max-height: 100%;object-fit: contain; /* 保持宽高比 */}}
</style>

相关文章:

  • Docker安装MinIO对象存储中间件
  • 基于Browser Use + Playwright 实现AI Agent操作Web UI自动化
  • 面向未来,遨游推出5G-A智能防爆对讲机等系列终端
  • COMPUTEX 2025 | 广和通率先发布基于MediaTek T930 平台的5G模组FG390
  • leetcode 92. Reverse Linked List II
  • 告别手动绘图!2分钟用 AI 生成波士顿矩阵
  • Linux网络 网络基础一
  • HTTP/HTTPS 协议浅解
  • 【Axure高保真原型】全选、反选、全部取消
  • 代码管理平台Gitlab如何通过快解析实现远程访问?
  • WPS深度适配鸿蒙电脑折叠形态,国产替代下的未来何在?
  • chromedp -—— 基于 go 的自动化操作浏览器库
  • 树形展示三级分类数据
  • Linux系统编程-DAY02
  • 【Rust智能指针】Rust智能指针原理剖析与应用指导
  • Panasonic松下焊接机器人节气
  • 第9.2讲、Tiny Decoder(带 Mask)详解与实战
  • opencv的直方图
  • OpenCv高阶(十五)——EigenFace人脸识别
  • spring-boot-starter-data-redis应用详解
  • wordpress网站模板/直播回放老卡怎么回事
  • 宁波方太集团网站建设/关键词的分类和优化
  • 海关申报网站怎么做/品牌推广策略怎么写
  • 做那个免费视频网站/百度号码认证平台个人号码申诉
  • 网站做服务端/百度网盘登陆
  • 武汉网站建设的费用/网站推广的方式和方法