从零搭建低代码平台(七)实现预览区组件拖拽渲染功能

目录

大体介绍

具体思路

写一个useBlockDragger.js函数

在主函数中进行引用

预期效果


大体介绍

在上一篇文章中,我们实现了预览区中组件获取焦点的功能。那么这一篇文章我们将着重介绍一下在预览区中利用拖拽将获取焦点的组件进行移动,从而达到渲染的功能。

具体思路

我们可以写一个js函数,接收focusData(获取焦点组件的属性),传入之后,我们可以写两个鼠标监听事件,在鼠标点击(mousedown)事件发生后触发两个鼠标监听事件,一个是鼠标移动事件(mousemove),另外一个是是鼠标松开事件(drop)。在鼠标移动事件中,我们可以通过获取鼠标移动的坐标,给传来的focusData的部分属性进行赋值,在鼠标松开的时候关闭鼠标鼠标监听事件。这样的话,我们可以返回鼠标点击事件,从而实现预览区组件拖拽渲染的功能。

写一个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})),
                }
            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;
          
        }

        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;
            }
        }
      

        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) {
           
            dragState.dragging = false
        }
    }
    return {
        mousedown
    }
}

在主函数中进行引用

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} = useBlockDragger(focusData, lastSelectBlock);

预期效果

从零搭建低代码平台(七)实现预览区组件拖拽渲染功能_第1张图片

从零搭建低代码平台(七)实现预览区组件拖拽渲染功能_第2张图片

你可能感兴趣的:(低代码开发平台,elementui,sass,css,javascript,vue.js)