可视化搭建中的拖动

903

Resizable

描述

image.png

下面为了方便,排除掉中间点的影响,只用四个点来控制

const styles = {
    x: 0,
    y: 0,
    width: 100,
    height: 100,
};
// 拖动了 10px
const distance = {
    x: 10,
    y: 10,
};

// 如果拖动的是右下角的点,方向是右下
const curStyles = {
    x: 0,
    y: 0,
    width: 110,
    height: 110,
};
// 如果拖动的是左上角的点,方向是右下
const curStyles = {
    x: 10,
    y: 10,
    width: 90,
    height: 90,
};

拖动行为

  1. 左上角。x、y、width 和 height 都会发生变化
  2. 右上角。x 不变,y、width 和 height 可能改变
  3. 左下角。y 不变,x、width 和 height 可能改变
  4. 右下角。x 和 y 不变,width 和 height 都改变

宽高,不可能是负数,需要处理,一般两种处理方式:1,小于0的情况话取0;2,小于 0 取绝对值。

这里不难发现的是,如果把焦点放在不同的点上,我们需要给每一个点做不同的处理

case '左上角':
    // 处理左上角
case '右上角':
    // 处理右上角
case '左下角':
    // 处理左下角
case '右下角':
    // 处理右下角

这里可以思考一个问题,如何确定一个矩形?

  1. 左上角的坐标(x, y) + 宽 width + 高 height。 通过匹配拖动不同的点,来改变左上角坐标(x, y)、宽(width)和高(height)。这种计算方式非常的费力,逻辑也比较复杂,因为拖动的点不同,改变的逻辑也不同。

  2. 对角的两个坐标。base(x, y) + opposite(x, y) image.png

const getLocList = (loc) => {
    const { x, y, width, height } = loc;

    const one = {
        x,
        y
    };
    const two = {
        x: x + width,
        y
    };
    const three = {
        x,
        y: y + height
    };
    const four = {
        x: x + width,
        y: y + height
    };

    return [one, two, three, four];
};
const list = getLocList(styles);
// 对角,index 为你点击点的下标
const [cur, opposite] = [
  list[index],
  list[dotsList.length - 1 - index],
];

后续拖动的操作就会变得简单很多 demo

Moveable

image.png

demo

mouse 事件如何实现从 A 容器移动到 B 容器?

参考 react-beautiful-dnd

image.png

image.png mouseover 和 mouseenter 都可以做到响应鼠标移动进来的事件。

问题又来了,你拖动一个组件时,是没法触发 mouseover 和 mouseenter 事件的

// mousedown 时,给组件加上这个属性
pointer-events: none;

demo

总结

demo 可优化的地方很多,比如 mouseup 时再做相关逻辑处理,提高性能。简单来说,大概这样。