2张图彻底搞懂拖拽+缩放demo

580 阅读2分钟

最近需求中老是遇到这样的需求,一个model拖拽+缩放的功能。

只是在实现的时候,光想总是有点问题,所以就画了一下图,结果打开了新世界,好简单啊

有人可能会问,一些插件就够了,还要写它干嘛,不是不会,只是有时老是把 clientX、clientY、offsetX、offsetY、screenX、screenY 这些搞混。

今天让你看完图,彻底搞明白实现一个拖拽+缩放的功能,用到了那些属性,首先需要了解这些属性是干嘛的。废话不多说,开搞

介绍下clientxx、offsetxx、screenxx

  • clientX、clientY 针对鼠标点击时,距离浏览器左上角(body)的坐标
  • offsetX、offsetY 针对目标元素的左上角坐标
  • screenX、screenY 相对屏幕左上角的位置

了解了这些那我们就知道了 拖拽 + 缩放 要用到哪些属性了,没错就是 clientX、clientY,本次缩放是4个角进行缩放,从小字体就不好,请忽略字体哈,坐标(x, y)

缩放的实现:

1.右下角实现

br.png

代码示例

let width = 200, height = 100;
const mouseDown = (e) => {
    // 鼠标落下时x,y开始坐标
    const startX = e.clientX; 
    const startY = e.clientY;
    
    // 本次只讨论右下角缩放
    const mouseMove = (el) => {
        // 移动x,y坐标 = 移动中的x,y坐标 - 原始x,y左边
        // el.clientX,el.clientY 也就是图片中moveEndX,moveEndY
        let moveX = el.clientX - startX;
        let moveY = el.clientY - startY;
        
        // 移动的宽高 = 原始宽,高 + 移动距离x,y
        // 缩小亦成立,缩小时 移动距离x,y 为负
        let newWdith = width + moveX;
        let newHight = height + moveY;
        // 因为拖动的是右下角,所以top、left都是不变的
    }
    
    xxx...
}

2. 左上角实现

tl.png

代码示例

let width = 200, height = 100, top = 30, left = 30;
const mouseDown = (e) => {
    // 鼠标落下时x,y开始坐标
    const startX = e.clientX; 
    const startY = e.clientY;
    
    // 本次只讨论右下角缩放
    const mouseMove = (el) => {
        // el.clientX,el.clientY 也就是图片中moveEndX,moveEndY
        let moveX = el.clientX - startX;
        let moveY = el.clientY - startY;
        
        // 移动的宽高 = 原始宽,高 - 移动距离x,y
        let newWdith = width - moveX;
        let newHight = height - moveY;
        // 因为拖动的是左上角,所以top,left都是变动的
        let newTop = top + moveY;
        let newLeft = left + moveX;
    }
    
    xxx...
}

右上角、左下角实现,画图就一目了然,就不做多介绍了,大家有兴趣可以自行画画

拖拽也是一样,拖拽比缩放更简单,也可以画图看,就不在此叙述了

总结: 当我们在日常中遇到鼠标移动事件时,如果容易搞混,不妨画图试试,便一目了然了