|
@@ -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
|
|
|
+ }
|
|
|
+}
|