簡單的低開編輯器(三):實現元件畫布內拖拽

2023-11-24 15:00:30

好傢伙,

0.程式碼已開源

Fattiger4399/lowcode-demo: 一個簡單的低程式碼編輯器 技術棧:Vue3 element-plus jsx (github.com)

 

本篇實現效果如下:

 

1.分析

這玩意的思路很好理解

本質上就是給元件綁個拖拽方法

拽到哪裡,就把位置更新給元件就好了,簡單粗暴

當然,需要做選中判定,知道我選中了哪些元件

 

 

2.選中判定實現

//editor.jsx

import { useFocus } from "./useFocus";

let { blockMousedown, focusData } = useFocus(data, (e) => {
            mousedown(e)
        });

 

 

 

//useFocus.js

import {computed} from 'vue'

//useFocus用於處理畫布中元件元素的選中
export function useFocus(data,callback){ //獲取哪些元素被選中了
    const focusData = computed(() => {
        let focus = [];
        let unfocused = [];
        data.value.blocks.forEach(block => (block.focus ? focus : unfocused).push(block))
        return {focus,unfocused}
    })
    return{
        blockMousedown,
        focusData
    }
}

此處,我們做一次選中判定,將選中的元件,和未被選中的元件,分開放,並返回

 

 

//useFocus.js

const blockMousedown = (e, block) => {
        //block上我們規劃一個屬性focus 獲取焦點後就將focus變為true
        e.preventDefault();
        e.stopPropagation();
        if (e.shiftKey) {
            block.focus = !block.focus
        } else {
            if (!block.focus) {
                clearBlockFocus();
                block.focus = true;//清空其他元件的focus屬性
            } else {
                block.focus = false;
            }
        }
        callback(e)
    }

判斷是否按下了shift鍵

 

 

3.點選觸發事件

//editor.jsx

<div class="editor-container-canvas__content"
                        style={containerStyles.value}
                        ref={containerRef}
                        onMousedown={containerMousedown}>
                        {
                            (data.value.blocks.map(block => (
                                <EditorBlock
                                    class={block.focus ? 'editor-block-focus' : ''}
                                    block={block}
                                    onMousedown={(e) => blockMousedown(e, block)}
                                ></EditorBlock>
                            )))
                        }
                    </div>
let { blockMousedown, focusData } = useFocus(data, (e) => {
            mousedown(e)
        });
        const mousemove = (e) => {
            let { clientX: moveX, clientY: moveY } = e;
            let endX = moveX - dragState.startX;
            let endY = moveY - dragState.startY;

            focusData.value.focus.forEach((block, idx) => {
                // console.log(dragState)
                block.top = dragState.startPos[idx].top + endY;
                block.left = dragState.startPos[idx].top + endX;
            })
        }
        const mouseup = (e) => {
            console.log(document)
            document.removeEventListener('mousemove', mousemove)
            document.removeEventListener('mouseup', mouseup)
        }
        const mousedown = (e) => {
            dragState = {
                startX: e.clientX,
                startY: e.clientY,
                startPos: focusData.value.focus.map(({ top, left }) => ({ top, left }))
            }
            console.log(dragState)
            document.addEventListener('mousemove', mousemove)
            document.addEventListener('mouseup', mouseup)
        }

 

//useFocus.js

const blockMousedown = (e, block) => {
        //block上我們規劃一個屬性focus 獲取焦點後就將focus變為true
        e.preventDefault();
        e.stopPropagation();
        if (e.shiftKey) {
            block.focus = !block.focus
        } else {
            if (!block.focus) {
                clearBlockFocus();
                block.focus = true;//清空其他元件的focus屬性
            } else {
                block.focus = false;
            }
        }
        callback(e)
    }

判斷是否按下了shift鍵

 

focusData.value.focus.forEach((block, idx) => {
                // console.log(dragState)
                      block.top = dragState.startPos[idx].top + endY;
                block.left = dragState.startPos[idx].top + endX;
            })

最後更改資料

搞定!