目录
大体介绍
在上一篇文章中,我们实现了预览区组件的拖拽渲染的功能,在一篇文章中,我们将实现在组件拖拽的过程中形成辅助线的功能。(让组件更容易上下左右对齐的功能)。
具体思路
我们想要实现的辅助线,就是在一个组件靠近另一个组件的水平或竖直的顶、中、底的时候可以触发,形成一组水平或者是竖直的辅助线。我们在上一篇博客中所写的useBlockDragger.js函数中,接收了focusData数值,我们可以通过遍历所有的data值,与被选定的组件进行逐一的对比,从而实现生成辅助线的功能。
修改useBlockDragger.js函数
// 实现组件拖拽功能
import {reactive} from "vue";
import {events} from "@/packages/events";
export function useBlockDragger(focusData, lastSelectBlock) {
let dragState = {
startX: 0,
startY: 0,
dragging: false
}
let markLine = reactive({
x: null,
y: null
})
const mousedown = (e) => {
if (focusData.value.focus[0].lock === false) {
// e.dataTransfer.dropEffect = 'move';
const {width: BWidth, height: BHeight} = lastSelectBlock.value;
dragState = {
startX: e.clientX,
startY: e.clientY,
startLeft: lastSelectBlock.value.left,
startTop: lastSelectBlock.value.top,
dragging: false,
startPos: focusData.value.focus.map(({top, left}) => ({top, left})),
lines: (() => {
const {unfocused} = focusData.value;
let lines = {x: [], y: []};
unfocused.forEach((block) => {
const {top: ATop, left: ALeft, width: AWidth, height: AHeight} = block;
// 顶对顶辅助线
lines.y.push({showTop: ATop, top: ATop});
// 顶对底辅助线
lines.y.push({showTop: ATop, top: ATop - BHeight});
// 中对中辅助线
lines.y.push({showTop: ATop + AHeight / 2, top: ATop + AHeight / 2 - BHeight / 2});
// 底对顶辅助线
lines.y.push({showTop: ATop + AHeight, top: ATop + AHeight});
// 底对底辅助线
lines.y.push({showTop: ATop + AHeight, top: ATop + AHeight - BHeight});
// 左对左辅助线
lines.x.push({showLeft: ALeft, left: ALeft});
// 右对左辅助线
lines.x.push({showLeft: ALeft + AWidth, left: ALeft + AWidth});
// 中对中辅助线
lines.x.push({showLeft: ALeft + AWidth / 2, left: ALeft + AWidth / 2 - BWidth / 2});
// 右对右辅助线
lines.x.push({showLeft: ALeft + AWidth, left: ALeft + AWidth - BWidth});
// 左对右辅助线
lines.x.push({showLeft: ALeft, left: ALeft - BWidth});
});
return lines
})()
}
document.addEventListener('mousemove', mousemove, {passive: false})
document.addEventListener('mouseup', mouseup, {passive: false})
}
}
const mousemove = (e) => {
let {clientX: moveX, clientY: moveY} = e;
if (!dragState.dragging) {
dragState.dragging = true;
events.emit('start');
}
let left = moveX - dragState.startX + dragState.startLeft;
// console.log(moveX)
// console.log(dragState.startX)
// console.log(typeof(dragState.startLeft))
let top = moveY - dragState.startY + dragState.startTop;
//计算横线
let y = null;
let x = null;
for (let i = 0; i < dragState.lines.y.length; i++) {
const {top: t, showTop: s} = dragState.lines.y[i];
if (Math.abs(t - top) < 5) {
y = s;
moveY = dragState.startY - dragState.startTop + t;
break;
}
}
for (let i = 0; i < dragState.lines.x.length; i++) {
const {left: l, showLeft: s} = dragState.lines.x[i];
if (Math.abs(l - left) < 5) {
x = s;
moveX = dragState.startX - dragState.startLeft + l;
break;
}
}
markLine.x = x;
markLine.y = y;
let durX = moveX - dragState.startX;
let durY = moveY - dragState.startY;
focusData.value.focus.forEach((block, idx) => {
block.top = dragState.startPos[idx].top + durY;
block.left = dragState.startPos[idx].left + durX;
// console.log(block.top)
})
}
const mouseup = (e) => {
document.removeEventListener('mousemove', mousemove, {passive: false})
document.removeEventListener('mousemove', mouseup, {passive: false})
markLine.x = null;
markLine.y = null;
if (dragState.dragging) {
events.emit('end');
dragState.dragging = false
}
}
return {
mousedown,
markLine
}
}
在其中
// 顶对顶辅助线
就是拿被选定组件的顶与靠近的组件顶来进行对比,差值小于5就会自动对齐。
// 顶对底辅助线
就是拿被选定组件的顶与靠近的组件底来进行对比,差值小于5就会自动对齐。
// 中对中辅助线
就是拿被选定组件的中间与靠近的组件中间来进行对比,差值小于5就会自动对齐。
// 底对顶辅助线
就是拿被选定组件的底与靠近的组件顶来进行对比,差值小于5就会自动对齐。
// 底对底辅助线
就是拿被选定组件的底与靠近的组件底来进行对比,差值小于5就会自动对齐。
// 左对左辅助线
就是拿被选定组件的左与靠近的组件左来进行对比,差值小于5就会自动对齐。
// 右对左辅助线
就是拿被选定组件的右与靠近的组件左来进行对比,差值小于5就会自动对齐。
// 中对中辅助线
就是拿被选定组件的中间与靠近的组件中间来进行对比,差值小于5就会自动对齐。
// 右对右辅助线
就是拿被选定组件的右与靠近的组件右来进行对比,差值小于5就会自动对齐。
// 左对右辅助线
就是拿被选定组件的左与靠近的组件右来进行对比,差值小于5就会自动对齐。
修改主函数对useBlockDragger.js函数的引用
// 实现获取焦点
let {blockMousedown, focusData, containerMousedown, lastSelectBlock} = useFocus(data, copyContent, (e) => {
mousedown(e)
// console.log(JSON.stringify(attrs_style.value.attribute))
// console.log(JSON.stringify(attrs_style.value.block))
});
// 实现组件拖拽功能
let {mousedown, markLine} = useBlockDragger(focusData, lastSelectBlock);
预期结果