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

本文介绍了如何在预览区中通过编写useBlockDragger.js函数,利用鼠标事件实现获取焦点组件的拖拽功能。通过mousedown、mousemove和mouseup事件处理,允许用户调整组件位置,以达到渲染的目的。
摘要由CSDN通过智能技术生成

目录

大体介绍

具体思路

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

预期效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值