vue 实现图片以鼠标为中心放大,并可以随意在div内拖动

需求:前端接收后端传过来图片渲染,并且可以直接在渲染的地方,以鼠标滚轮为中心放大图片,还可以随意拖动图片

调研:目前有很多现成的插件都是,点击图片,然后弹出遮罩层,在遮罩层里面操作,由于不符合需求,就只能自己写了。

开始使用了css3 的scale ,但是发现自由拖动有bug ,在放大后会导致左侧和上方的图片拖动不下来,类似于溢出隐藏(此出具体不做具体说明)

实现原理:

1:在img 外层套一个div ,此div 宽高固定,用来放 放大的img,然后产生滚动条。

2:计算鼠标相对于图片的位置(注意,此处有坑,不能直接用offsetX,offsetY,因为连续滚动,会导致 offsetX,offsetY 发生变化,导致计算出错)

3:放大缩小原理就是找到鼠标相对于图片的x ,y 轴的距离然后乘以倍数,动态设置图片的宽高,div 的scrollerLeft ,scrollerTop,使图片相对于div 的位置不变,从而实现效果。

4:鼠标在图片上随意拖动图片,原来就是动态的计算鼠标移动的x,y 轴的距离,然后动态的设置滚动条的位置

一:拖动组件:

const dragscroll = (el) => {
    el.onmousedown = ev => {
        const disX = ev.clientX;
        const disY = ev.clientY; // 需要上下移动可以加
        const originalScrollLeft = el.scrollLeft;
        const originalScrollTop = el.scrollTop; // 需要上下移动可以加
        const originalScrollBehavior = el.style['scroll-behavior'];
        const originalPointerEvents = el.style['pointer-events'];
        el.style['scroll-behavior'] = 'auto';
        // 鼠标移动事件是监听的整个document,这样可以使鼠标能够在元素外部移动的时候也能实现拖动
        document.onmousemove = dv => {
            dv.preventDefault();
            const distanceX = dv.clientX - disX;
       
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的示例代码: ```html <template> <div class="container" ref="container" @mousemove="handleMouseMove"> <div class="image-container" ref="imageContainer" :style="imageStyle" @mousedown="handleMouseDown" @mouseup="handleMouseUp"> <img :src="imageUrl" alt="image" class="image" /> </div> </div> </template> <script> export default { data() { return { imageUrl: "https://picsum.photos/800/600", // 图片地址 isDragging: false, // 是否在拖拽 lastX: 0, // 上一次鼠标位置 lastY: 0, scale: 1 // 缩放比例 }; }, computed: { imageStyle() { return { transform: `scale(${this.scale})` }; } }, methods: { handleMouseMove(event) { if (this.isDragging) { const deltaX = event.clientX - this.lastX; const deltaY = event.clientY - this.lastY; const container = this.$refs.container; const imageContainer = this.$refs.imageContainer; const containerRect = container.getBoundingClientRect(); const imageRect = imageContainer.getBoundingClientRect(); if ( imageRect.left + deltaX <= containerRect.left && imageRect.right + deltaX >= containerRect.right ) { imageContainer.style.left = `${imageRect.left + deltaX}px`; } if ( imageRect.top + deltaY <= containerRect.top && imageRect.bottom + deltaY >= containerRect.bottom ) { imageContainer.style.top = `${imageRect.top + deltaY}px`; } this.lastX = event.clientX; this.lastY = event.clientY; } }, handleMouseDown(event) { this.isDragging = true; this.lastX = event.clientX; this.lastY = event.clientY; }, handleMouseUp() { this.isDragging = false; } } }; </script> <style> .container { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; background-color: #f0f0f0; } .image-container { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .image { display: block; max-width: 100%; height: auto; } </style> ``` 这里使用了 `mousemove` 监听鼠标移动事件, `mousedown` 监听鼠标按下事件, `mouseup` 监听松开事件,实现了拖拽功能。同时,通过计算鼠标移动的距离,实现图片的拖拽,并且限制了图片在容器内部移动。 同时,通过 `scale` 属性实现图片的缩放功能,代码中通过 `computed` 计算属性来实现样式的动态绑定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值