|  | @@ -0,0 +1,87 @@
 | 
	
		
			
				|  |  | +import { useProjectStore } from "@/store/modules/project";
 | 
	
		
			
				|  |  | +import { calcComboInfo } from "@/utils/calc";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const ABSORB_DISTANCE = 10;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export function useAdsorb() {
 | 
	
		
			
				|  |  | +  const projectStore = useProjectStore();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const getAdsorb = ( move: number, xy: number, wh: number, targetVal: number) => {
 | 
	
		
			
				|  |  | +    // 始端吸附
 | 
	
		
			
				|  |  | +    if (Math.abs((xy + move) - targetVal) < ABSORB_DISTANCE) {
 | 
	
		
			
				|  |  | +      move = targetVal - xy;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // 中间吸附
 | 
	
		
			
				|  |  | +    if (Math.abs((xy + wh / 2 + move) - targetVal) < ABSORB_DISTANCE) {
 | 
	
		
			
				|  |  | +      move = targetVal - xy - wh / 2;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // 终端吸附
 | 
	
		
			
				|  |  | +    if (Math.abs((xy + wh + move) - targetVal) < ABSORB_DISTANCE) {
 | 
	
		
			
				|  |  | +      move = targetVal - xy - wh;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    return move;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /**
 | 
	
		
			
				|  |  | +   * 获取吸附信息
 | 
	
		
			
				|  |  | +   * @param moveX 移动x坐标
 | 
	
		
			
				|  |  | +   * @param moveY 移动y坐标
 | 
	
		
			
				|  |  | +   * @param moveW 移动宽度
 | 
	
		
			
				|  |  | +   * @param moveH 移动高度
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  const getAdsorbInfo = ({ moveX, moveY, moveW, moveH }: { moveX: number, moveY: number, moveW: number, moveH: number }) => {
 | 
	
		
			
				|  |  | +    // 1、获取当前操作元素
 | 
	
		
			
				|  |  | +    const selcetedElements = projectStore.currentSelectedElements;
 | 
	
		
			
				|  |  | +    // 2、获取所有组件及参考线
 | 
	
		
			
				|  |  | +    const referLines = projectStore.showReffer ? projectStore.referLines : [];
 | 
	
		
			
				|  |  | +    const elements = projectStore.elements.filter(item => selcetedElements.findIndex(ele => ele.key === item.key) === -1);
 | 
	
		
			
				|  |  | +    // 3、将当前的操作元素当作一个整体 计算出x y w h
 | 
	
		
			
				|  |  | +    const { minX: x, minY: y, maxX, maxY } = calcComboInfo(selcetedElements);
 | 
	
		
			
				|  |  | +    const w = maxX - x;
 | 
	
		
			
				|  |  | +    const h = maxY - y;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 组件间吸附
 | 
	
		
			
				|  |  | +    elements.forEach(item => {
 | 
	
		
			
				|  |  | +      const { x: itemX = 0, y: itemY = 0, width = 0, height = 0 } = item.container.props;
 | 
	
		
			
				|  |  | +      // 左
 | 
	
		
			
				|  |  | +      moveX = getAdsorb(moveX, x, w, itemX);
 | 
	
		
			
				|  |  | +      // 中
 | 
	
		
			
				|  |  | +      moveX = getAdsorb(moveX, x, w, itemX + (width / 2));
 | 
	
		
			
				|  |  | +      // 右
 | 
	
		
			
				|  |  | +      moveX = getAdsorb(moveX, x, w, itemX + width);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 上
 | 
	
		
			
				|  |  | +      moveY = getAdsorb(moveY, y, h, itemY);
 | 
	
		
			
				|  |  | +      // 中
 | 
	
		
			
				|  |  | +      moveY = getAdsorb(moveY, y, h, itemY + (height / 2));
 | 
	
		
			
				|  |  | +      // 下
 | 
	
		
			
				|  |  | +      moveY = getAdsorb(moveY, y, h, itemY + height);
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    referLines.forEach(line => {
 | 
	
		
			
				|  |  | +      if (line.type === "vertical") {
 | 
	
		
			
				|  |  | +        moveY = getAdsorb(moveY, y, h, line.value);
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        moveX = getAdsorb(moveX, x, w, line.value);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 屏幕边线吸附
 | 
	
		
			
				|  |  | +    moveY = getAdsorb(moveY, y, h, 0);
 | 
	
		
			
				|  |  | +    moveY = getAdsorb(moveY, y, h, projectStore.projectInfo.height);
 | 
	
		
			
				|  |  | +    moveX = getAdsorb(moveX, x, w, 0);
 | 
	
		
			
				|  |  | +    moveX = getAdsorb(moveX, x, w, projectStore.projectInfo.width);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    return {
 | 
	
		
			
				|  |  | +      newMoveX: moveX,
 | 
	
		
			
				|  |  | +      newMoveY: moveY,
 | 
	
		
			
				|  |  | +      newMoveW: moveW,
 | 
	
		
			
				|  |  | +      newMoveH: moveH
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return {
 | 
	
		
			
				|  |  | +    getAdsorbInfo
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 |