1
0
mirror of https://github.com/sahadev/vue-component-creater-ui.git synced 2025-09-12 05:53:28 +08:00
2021-04-09 20:06:44 +08:00

178 lines
4.9 KiB
JavaScript

let currentPostion = null,
currentTarget = null,
preSelectTarget = null; // 记录上一次鼠标所在位置
const TOP = 1,
MIDDLE = 2,
BOTTOM = 3;
import { findCodeElemNode, findRawVueInfo } from "@/utils/forCode";
import { getRawComponentContent } from "@/utils/common";
export function initContainerForLine(targetElement, _currentPointer = () => {}) {
const crossX = document.querySelector(".x");
const currentPointer = (...args) => {
_currentPointer(...args);
};
targetElement.addEventListener("dragover", (event) => {
event.preventDefault();
drawLine(event);
});
targetElement.addEventListener("dragleave", (event) => {
if (event.target === targetElement) {
targetElement.classList.remove("in-element");
crossX.style = "display: none;";
} else {
clearTargetOutline();
}
});
/**
* 获得一个元素在父元素中的索引
* @param {*} element
* @returns
*/
function findElementIndex(element) {
// 根据代码结构查找
const parentElementNode = findCodeElemNode(element.parentElement);
const lc_id = element.getAttribute("lc_id");
if (parentElementNode) {
const parentRawInfo = findRawVueInfo(parentElementNode);
const attributes = getRawComponentContent(parentRawInfo);
if (attributes) {
const childrenArray = attributes.__children;
const index = childrenArray.findIndex((item) => {
return getRawComponentContent(item).lc_id == lc_id;
});
return index;
}
}
return -1;
}
function clearTargetOutline() {
if (preSelectTarget) {
preSelectTarget.classList.remove("in-element");
}
}
function drawLine(event) {
const realTarget = event.target;
// 2021年03月26日15:56:35 新的逻辑是:只有上下定位辅助线,不再计算左右辅助线
const directionObj = judgeTopOrBottom(realTarget, event.clientX, event.clientY);
const position = getElCoordinate(realTarget);
// 如果鼠标点在目标的上部分则绘制上部分辅助线
if (directionObj.top && targetElement !== realTarget) {
if (currentPostion === TOP && currentTarget === realTarget) {
return;
}
currentPostion = TOP;
currentTarget = realTarget;
clearTargetOutline();
crossX.style = `top:${position.top}px;width:${position.width}px;left:${position.left}px;display:block;`;
currentPointer(realTarget.parentElement, findElementIndex(realTarget));
} else if (directionObj.bottom && targetElement !== realTarget) {
// 如果鼠标点在目标的下部分,则绘制下部分辅助线
if (currentPostion === BOTTOM && currentTarget === realTarget) {
return;
}
currentPostion = BOTTOM;
currentTarget = realTarget;
clearTargetOutline();
crossX.style = `top:${position.bottom}px;width:${position.width}px;left:${position.left}px;display:block;`;
currentPointer(realTarget.parentElement, findElementIndex(realTarget) + 1);
} else {
currentPostion = MIDDLE;
currentTarget = realTarget;
realTarget.classList.add("in-element");
preSelectTarget = realTarget;
crossX.style = `display:none;`;
currentPointer(realTarget, -1);
}
}
}
// 获取一个元素在屏幕上的坐标点
function getElCoordinate(e) {
const rect = e.getBoundingClientRect();
return rect;
}
// 判断一个点是否在该元素内
function judgeEleIsContentPoint(e, x, y) {
const position = getElCoordinate(e);
return x >= position.left && x <= position.right && y >= position.top && y <= position.bottom;
}
/**
* 判断上还是下
* @param {*} e
* @param {*} x
* @param {*} y
* @returns
*/
function judgeTopOrBottom(e, x, y) {
const position = getElCoordinate(e);
const cutDistance = Math.round((position.bottom - position.top) / 3);
return {
top: y < position.top + cutDistance,
middle: y >= position.top + cutDistance && y <= position.top + cutDistance * 2,
bottom: y > position.top + cutDistance * 2,
};
}
// 判断点在元素的方向
function direction(e, x, y) {
const position = getElCoordinate(e);
// 基本方向判定
const direction = {
left: x < position.left ? position.left - x : 0,
right: x > position.right ? x - position.right : 0,
top: y < position.top ? position.top - y : 0,
bottom: y > position.bottom ? y - position.bottom : 0,
};
// 判定方向更靠近哪个
let count = 0;
let directionStrArray = [];
for (const key in direction) {
const element = direction[key];
if (element) {
directionStrArray.push(key);
count++;
}
}
if (count === 2) {
// 进一步判定更靠近哪个方向
const num1 = direction[directionStrArray[0]];
const num2 = direction[directionStrArray[1]];
direction[directionStrArray[0]] = num1 > num2;
direction[directionStrArray[1]] = num2 > num1;
}
direction.position = position;
return direction;
}