Vue3图片缩放拖拽组件全攻略
Panzoom 图片缩放拖拽组件使用文档基于Vue 3 panzoom/panzoom的图片缩放拖拽组件支持滚轮缩放和鼠标拖拽大图自动缩小完整显示小图 1:1 居中。目录依赖安装Props 说明完整代码使用步骤功能说明1. 依赖安装npminstallpanzoom/panzoom2. Props 说明Prop类型必填默认值说明imageSrcString否图片地址支持远程 URL 或URL.createObjectURL的 Blob URL3. 完整代码ProcessDialog.vuetemplate !-- 固定高度容器作为 panzoom 的视口 -- div refcontainerRef classpanzoom-viewport !-- panzoom 控制的目标元素transform 在这里生效 -- div refpanzoomRef classpanzoom-layer img v-ifimageSrc :srcimageSrc alt图片 classdraggable-image loadonImageLoad / el-empty v-else description暂无图片 / /div /div /template script setup import { ref, watch, nextTick, onBeforeUnmount } from vue import Panzoom from panzoom/panzoom /** * Props * - imageSrc: 图片地址ObjectURL 或远程 URL */ const props defineProps({ imageSrc: { type: String, default: } }) // DOM 引用 const containerRef ref(null) // 固定高度视口容器 const panzoomRef ref(null) // panzoom 控制的内容层 let panzoomInstance null // Panzoom 实例创建 /** 创建并配置 panzoom 实例 * param {HTMLElement} element - 被控制的内容层 DOM * returns {Panzoom} panzoom 实例 */ function createPanzoom(element) { return Panzoom(element, { maxScale: 5, // 最大放大 5 倍 minScale: 0.05, // 最小缩小到 5% step: 0.15, // 滚轮每格缩放步长 contain: false, // 不限制内容边界允许自由拖拽 /* 鼠标/触摸事件处理避免拖拽时误选文本 */ handleStartEvent: (e) { // 多指触摸 → 允许缩放 if (e.touches e.touches.length 1) return true // 非左键 / 非 touch / 非滚轮 → 不拦截 if (e.button ! 0 e.type ! touchstart e.type ! wheel) return true e.preventDefault() e.stopPropagation() } }) } // 自适应缩放 /** * 内容自适应容器大图缩小、小图居中保持完整显示 * 计算公式 * scale min(容器宽 / 内容宽, 容器高 / 内容高, 1) * panX (容器宽 - 内容宽 × scale) / 2 * panY (容器高 - 内容高 × scale) / 2 * * param {Panzoom} instance - panzoom 实例 * param {HTMLElement} layerEl - 内容层 DOM */ function autoFit(instance, layerEl) { if (!instance || !layerEl || !containerRef.value) return const pw containerRef.value.clientWidth const ph containerRef.value.clientHeight const cw layerEl.scrollWidth const ch layerEl.scrollHeight if (cw 0 || ch 0) return // 刚好完整显示的比例最大不超过 1小图不放大 const scale Math.min(pw / cw, ph / ch, 1) // 先归零 → 设置缩放 → 居中避免位移累积误差 instance.pan({ x: 0, y: 0 }) instance.setScale(scale) instance.pan({ x: (pw - cw * scale) / 2, y: (ph - ch * scale) / 2 }) } // 图片加载回调 /** 图片加载完成后初始化 panzoom 自适应居中 */ function onImageLoad() { if (!panzoomRef.value || !containerRef.value) return // 销毁旧实例避免重复创建 if (panzoomInstance) { panzoomInstance.destroy() panzoomInstance null } panzoomInstance createPanzoom(panzoomRef.value) // 滚轮事件绑定到外层容器确保鼠标在容器内任意位置都能缩放 containerRef.value.addEventListener(wheel, panzoomInstance.zoomWithWheel, { passive: false }) // 等浏览器完成布局后自适应 nextTick(() { requestAnimationFrame(() autoFit(panzoomInstance, panzoomRef.value)) }) } // 监听 imageSrc 变化 watch( () props.imageSrc, (src) { if (src) { nextTick(() { // 如果图片已缓存loaded直接初始化 if (panzoomRef.value?.querySelector(img)?.complete) { onImageLoad() } }) } } ) // 组件销毁时清理 onBeforeUnmount(() { if (containerRef.value panzoomInstance) { containerRef.value.removeEventListener(wheel, panzoomInstance.zoomWithWheel) } if (panzoomInstance) { panzoomInstance.destroy() panzoomInstance null } }) /script style scoped langscss /* 视口容器固定高度裁剪溢出 */ .panzoom-viewport { width: 100%; height: 65vh; overflow: hidden; position: relative; background: #f5f6f8; border: 1px solid #e8eaed; border-radius: 4px; user-select: none; /* 拖拽时不选中文本 */ } /* panzoom 控制的内容层transform 在这里生效 */ .panzoom-layer { display: inline-block; transform-origin: 0 0; /* 以左上角为缩放原点配合 autoFit 的 pan 居中 */ } /* 图片样式 */ .draggable-image { display: block; max-width: none; /* 允许图片超出容器由 panzoom 控制缩放 */ } /style4. 使用步骤第 1 步安装依赖npminstallpanzoom/panzoom第 2 步在父组件中使用template div stylepadding: 20px; ProcessDialog :image-srcimageUrl / /div /template script setup import { ref } from vue import ProcessDialog from /views/mytodolist/components/dialogs/ProcessDialog.vue // 可以是远程 URL const imageUrl ref(https://example.com/flow-diagram.png) // 或者通过后端 Blob 接口获取 import { diagram } from /api/mytodolist/index async function loadImage(processInstanceId) { const res await diagram({ processInstanceId }) imageUrl.value URL.createObjectURL(res) // Blob → ObjectURL } /script5. 功能说明5.1 滚轮缩放鼠标悬停在图片上滚动滚轮即可缩放以鼠标位置为中心点缩放缩放步长 15%最大放大 5 倍最小缩小到 5%5.2 鼠标拖拽按住鼠标左键拖动图片可拖出容器边界contain: false支持触摸屏手势拖拽5.3 自适应显示图片大小效果图片 容器自动缩小到完整显示居中图片 容器保持 1:1 原始大小居中不放大5.4 生命周期图片加载完成后自动初始化 panzoom 自适应居中imageSrc变化时重新初始化组件销毁时自动清理 panzoom 实例和事件监听5.5 autoFit 缩放计算公式scale min(容器宽 / 图片宽, 容器高 / 图片高, 1) ↑ ↑ 取宽高比中较小的一个 不超过 1不大 panX (容器宽 - 图片宽 × scale) / 2 panY (容器高 - 图片高 × scale) / 2

相关新闻

最新新闻

日新闻

周新闻

月新闻