最近需求中老是遇到这样的需求,一个model拖拽+缩放的功能。
只是在实现的时候,光想总是有点问题,所以就画了一下图,结果打开了新世界,好简单啊
有人可能会问,一些插件就够了,还要写它干嘛,不是不会,只是有时老是把 clientX、clientY、offsetX、offsetY、screenX、screenY 这些搞混。
今天让你看完图,彻底搞明白实现一个拖拽+缩放的功能,用到了那些属性,首先需要了解这些属性是干嘛的。废话不多说,开搞
介绍下clientxx、offsetxx、screenxx
- clientX、clientY 针对鼠标点击时,距离浏览器左上角(body)的坐标
- offsetX、offsetY 针对目标元素的左上角坐标
- screenX、screenY 相对屏幕左上角的位置
了解了这些那我们就知道了
拖拽 + 缩放
要用到哪些属性了,没错就是clientX、clientY
,本次缩放是4个角进行缩放,从小字体就不好,请忽略字体哈,坐标(x, y)
缩放的实现:
1.右下角实现
代码示例
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. 左上角实现
代码示例
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...
}
右上角、左下角实现,画图就一目了然,就不做多介绍了,大家有兴趣可以自行画画
拖拽也是一样,拖拽比缩放更简单,也可以画图看,就不在此叙述了
总结: 当我们在日常中遇到鼠标移动事件时,如果容易搞混,不妨画图试试,便一目了然了