自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Next-Admin最佳實(shí)踐!支持可視化拖拽模塊

開(kāi)發(fā) 前端
拖拽模塊我采用了 movable, 并研究了它的大量 API,最終實(shí)現(xiàn)了我想要的效果,當(dāng)然我還設(shè)計(jì)了一套數(shù)據(jù)結(jié)構(gòu),如果大家對(duì)可視化搭建感興趣,也可以擴(kuò)展成自己的拖拽搭建結(jié)構(gòu)。

模塊演示

圖片圖片

技術(shù)實(shí)現(xiàn)

拖拽模塊我采用了 movable, 并研究了它的大量 API,最終實(shí)現(xiàn)了我想要的效果,當(dāng)然我還設(shè)計(jì)了一套數(shù)據(jù)結(jié)構(gòu),如果大家對(duì)可視化搭建感興趣,也可以擴(kuò)展成自己的拖拽搭建結(jié)構(gòu)。

圖片圖片

元素多選我采用了 selecto 模塊,成組管理器我采用了 @moveable/helper, 當(dāng)然在使用這些庫(kù)的時(shí)候也踩了不少坑,好在已經(jīng)完美解決。

下面分享一個(gè)簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),以支持我們的元素自由搭建:

const schema = {
    "Button": {
        id: 'wep_001',
        name: 'Button',
        type: 'base', // 基礎(chǔ)類型組件
        base: {
            width: 120,
            height: 36,
            transform: 'translate(100px,100px)'
        }
    },
    "Image": {
        id: 'wep_002',
        name: 'Image',
        type: 'base', // 基礎(chǔ)類型組件
        base: {
            width: 120,
            height: 120,
            url: '',
            transform: 'translate(300px,160px)'
        }
    }
}

export default schema

工具條實(shí)現(xiàn)

圖片圖片

對(duì)于工具條的實(shí)現(xiàn),我做了統(tǒng)一的封裝,以便后期可能更低成本的維護(hù)和管理:

  • config 工具條配置
  • actions 工具條選項(xiàng)對(duì)應(yīng)的功能方法

接下來(lái)看看工具條的配置:

const toolbar = {
    base: [
        {
            key: 'group',
            icon: <GroupOutlined />,
            text: '成組',
        },
        {
            key: 'ungroup',
            icon: <UngroupOutlined />,
            text: '取消成組'
        },
        {
            key: 'left',
            icon: <AlignLeftOutlined />,
            text: '左對(duì)齊'
        },
        // ... 其他工具條配置
        {
            key: 'v-space',
            icon: <PicCenterOutlined />,
            text: '垂直分布空間'
        },
        {
            key: 'h-space',
            icon: <PicCenterOutlined style={{transform: 'rotate(-90deg)'}} />,
            text: '水平分布空間'
        },
        
    ]
}

工具條方法封裝:

const handleOperate = (key: string) => {
        // ... some function
        // 頂對(duì)齊實(shí)現(xiàn)
        if(key === 'top') {
            const rect = moveableRef.current!.getRect();
            // console.log(rect)
            const moveables = moveableRef.current!.getMoveables();

            if (moveables.length <= 1) {
                return;
            }
            moveables.forEach(child => {
                child.request<DraggableRequestParam>("draggable", {
                    y: rect.top,
                }, true);
            });

            moveableRef.current?.updateRect();
            return
        }
        // 底對(duì)齊
        if(key === 'bottom') {
            const rect = moveableRef.current!.getRect();
            const moveables = moveableRef.current!.getMoveables();
            if (moveables.length <= 1) {
                return;
            }
            moveables.forEach(child => {
                child.request<DraggableRequestParam>("draggable", {
                    y: rect.top + rect.height - (child.props?.target ? (child.props.target as any).offsetHeight : 0),
                }, true);
            });
            moveableRef.current?.updateRect();
            return
        }

        // ... 其他工具條方法
        // 水平分布
        if(key === 'h-space') {
            const groupRect = moveableRef.current!.getRect();
            const moveables = moveableRef.current!.getMoveables();
            let left = groupRect.left;

            if (moveables.length <= 1) {
                return;
            }
            const gap = (groupRect.width - groupRect.children!.reduce((prev, cur) => {
                return prev + cur.width;
            }, 0)) / (moveables.length - 1);

            moveables.sort((a, b) => {
                return a.state.left - b.state.left;
            });
            moveables.forEach(child => {
                const rect = child.getRect();

                child.request<DraggableRequestParam>("draggable", {
                    x: left,
                }, true);

                left += rect.width + gap;
            });

            moveableRef.current?.updateRect();
            return
        }

    }

通過(guò)以上的封裝方式我們就能輕松擴(kuò)展自己的工具條啦~

接下來(lái)我們看看工具條實(shí)現(xiàn)的效果:

圖片圖片

當(dāng)然代碼我已經(jīng)提交到 github 上了, 大家感興趣可以參考研究一下。

開(kāi)源地址:https://github.com/MrXujiang/next-admin

多選 & 成組實(shí)現(xiàn)

圖片圖片

下面直接上代碼:

<Selecto
    ref={selectoRef}
    // dragCnotallow={container.current}
    selectableTargets={[".wep-area .cube"]}
    hitRate={0}
    selectByClick={true}
    selectFromInside={false}
    toggleCnotallow={["shift"]}
    ratio={0}
    notallow={e => {
        const moveable = moveableRef.current!;
        const target = e.inputEvent.target;
        const flatted = deepFlat(targets);

        if (
            target.tagName === "BUTTON"
            || moveable.isMoveableElement(target)
            || flatted.some(t => t === target || t.contains(target))
        ) {
            e.stop();
        }
        e.data.startTargets = targets;
    }}
    notallow={e => {
        const {
            startAdded,
            startRemoved,
            isDragStartEnd,
        } = e;

        if (isDragStartEnd) {
            return;
        }
        const nextChilds = groupManager.selectSameDepthChilds(
            e.data.startTargets,
            startAdded,
            startRemoved,
        );

        setSelectedTargets(nextChilds.targets());
    }}
    notallow={e => {
        const {
            isDragStartEnd,
            isClick,
            added,
            removed,
            inputEvent,
        } = e;
        const moveable = moveableRef.current!;

        if (isDragStartEnd) {
            inputEvent.preventDefault();

            moveable.waitToChangeTarget().then(() => {
                moveable.dragStart(inputEvent);
            });
        }
        let nextChilds: TargetList;

        if (isDragStartEnd || isClick) {
            if (isCommand) {
                nextChilds = groupManager.selectSingleChilds(targets, added, removed);
            } else {
                nextChilds = groupManager.selectCompletedChilds(targets, added, removed, isShift);
            }

        } else {
            nextChilds = groupManager.selectSameDepthChilds(e.data.startTargets, added, removed);
        }
        e.currentTarget.setSelectedTargets(nextChilds.flatten());
        setSelectedTargets(nextChilds.targets());
    }}
></Selecto>

完整代碼都同步到 Next-Admin 了, 如果大家感興趣也可以研究一下。

責(zé)任編輯:武曉燕 來(lái)源: 趣談前端
相關(guān)推薦

2020-07-22 10:30:54

數(shù)據(jù)可視化分析平臺(tái)分析工具

2020-12-22 14:14:25

大數(shù)據(jù)數(shù)據(jù)可視化

2015-10-28 13:28:57

2015-09-21 09:21:07

2020-03-11 14:39:26

數(shù)據(jù)可視化地圖可視化地理信息

2024-03-06 19:57:56

探索商家可視化

2017-10-14 13:54:26

數(shù)據(jù)可視化數(shù)據(jù)信息可視化

2022-08-26 09:15:58

Python可視化plotly

2009-04-21 14:26:41

可視化監(jiān)控IT管理摩卡

2024-07-25 14:04:16

2023-11-30 09:34:14

數(shù)據(jù)可視化探索

2023-03-09 15:11:30

數(shù)據(jù)可視化工具matplotlib

2024-06-06 08:27:42

2017-10-25 13:04:10

數(shù)據(jù)可視化信息可視化數(shù)據(jù)圖表

2020-03-07 21:48:46

物聯(lián)網(wǎng)可視化技術(shù)設(shè)計(jì)

2018-07-11 12:30:51

編程語(yǔ)言Python數(shù)據(jù)可視化

2015-08-20 10:06:36

可視化

2021-01-09 09:48:10

可視化自然流布局 LowCode

2022-01-14 07:56:38

流布局設(shè)計(jì)拖拽
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)