完美实现按下鼠标移动元素功能

先上代码
 1 const handleChangePosition = () => {
 2   const element = canvasBox.value as HTMLDivElement;
 3   let startX = 0, startY = 0, initialX = 0, initialY = 0;
 4 
 5   element.onmousedown = function (e) {
 6     // 获取当前的transform值
 7     const transform = window.getComputedStyle(element).transform;
 8     if (transform !== 'none') {
 9       const matrix = new DOMMatrixReadOnly(transform);
10       initialX = matrix.m41;
11       initialY = matrix.m42;
12     }
13 
14     // 记录起始位置
15     startX = e.clientX;
16     startY = e.clientY;
17 
18     // 添加鼠标移动事件监听器
19     document.onmousemove = function (em) {
20       requestAnimationFrame(() => {
21         const dx = em.clientX - startX + initialX;
22         const dy = em.clientY - startY + initialY;
23         element.style.transform = `translate(${dx}px, ${dy}px)`;
24       });
25     };
26   };
27 
28   document.onmouseup = function () {
29     // 移除鼠标移动事件监听器
30     document.onmousemove = null;
31   };
32 };

为什么要减去 startXstartY

这里的 startXstartY 代表了鼠标按下时的初始位置。在鼠标移动过程中,我们需要计算从这个起始点到当前鼠标位置的相对移动距离。这样做的目的是为了确定鼠标移动了多远,然后将这个距离应用到元素的平移上。

当鼠标移动时,em.clientXem.clientY 表示鼠标当前的位置。通过从当前位置减去初始位置(startXstartY),我们得到了鼠标相对于按下时的移动距离。然后,这个移动距离加上元素的初始位置(initialXinitialY)得到了元素的新位置。

如果不加上initialX 和initialY,鼠标点击和第一次移动时,startX 和startY总是与clientX和clientY相等,这样会导致元素每次移动都会先回到(0,0)的位置。

window.getComputedStyle(element).transformDOMMatrixReadOnly

window.getComputedStyle(element).transform: 这行代码的作用是获取元素当前的样式,包括由CSS或之前的JavaScript操作所应用的所有样式。在这里,我们关心的是transform属性,它包含了元素的变换信息,比如它是如何被平移或旋转的。

  • DOMMatrixReadOnly 对象: 当transform属性返回的不是none时,表示元素有一些变换。transform属性的值通常是一个矩阵或一个矩阵的字符串表示(比如matrix(1, 0, 0, 1, 100, 50))。为了更容易地读取这些值,我们使用DOMMatrixReadOnly来解析这个矩阵。这是一个专门用来处理二维和三维变换矩阵的Web API。下面是控制台打印的值

  • matrix.m41matrix.m42: 在一个2D变换矩阵中,m41m42 分别代表矩阵在X轴和Y轴的平移距离。通过读取这些值,我们可以得到元素当前的平移位置。
    有其他方法欢迎留言讨论

 

posted @ 2024-01-18 15:39  初生土豆  阅读(13)  评论(0编辑  收藏  举报