Resizable
描述
下面为了方便,排除掉中间点的影响,只用四个点来控制
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,
};
拖动行为
- 左上角。x、y、width 和 height 都会发生变化
- 右上角。x 不变,y、width 和 height 可能改变
- 左下角。y 不变,x、width 和 height 可能改变
- 右下角。x 和 y 不变,width 和 height 都改变
宽高,不可能是负数,需要处理,一般两种处理方式:1,小于0的情况话取0;2,小于 0 取绝对值。
这里不难发现的是,如果把焦点放在不同的点上,我们需要给每一个点做不同的处理
case '左上角':
// 处理左上角
case '右上角':
// 处理右上角
case '左下角':
// 处理左下角
case '右下角':
// 处理右下角
这里可以思考一个问题,如何确定一个矩形?
-
左上角的坐标(x, y) + 宽 width + 高 height。 通过匹配拖动不同的点,来改变左上角坐标(x, y)、宽(width)和高(height)。这种计算方式非常的费力,逻辑也比较复杂,因为拖动的点不同,改变的逻辑也不同。
-
对角的两个坐标。base(x, y) + opposite(x, y)
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
mouse 事件如何实现从 A 容器移动到 B 容器?
mouseover 和 mouseenter 都可以做到响应鼠标移动进来的事件。
问题又来了,你拖动一个组件时,是没法触发 mouseover 和 mouseenter 事件的
// mousedown 时,给组件加上这个属性
pointer-events: none;
总结
demo 可优化的地方很多,比如 mouseup 时再做相关逻辑处理,提高性能。简单来说,大概这样。