目录

大体介绍

具体思路

修改useBlockDragger.js函数

修改主函数对useBlockDragger.js函数的引用

预期结果


大体介绍

在上一篇文章中,我们实现了预览区组件的拖拽渲染的功能,在一篇文章中,我们将实现在组件拖拽的过程中形成辅助线的功能。(让组件更容易上下左右对齐的功能)。

具体思路

我们想要实现的辅助线,就是在一个组件靠近另一个组件的水平或竖直的顶、中、底的时候可以触发,形成一组水平或者是竖直的辅助线。我们在上一篇博客中所写的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);

预期结果

 

 

 

Logo

低代码爱好者的网上家园

更多推荐