Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

怎么限制对象移动的范围 #110

Closed
3400442579 opened this issue Apr 2, 2024 · 6 comments
Closed

怎么限制对象移动的范围 #110

3400442579 opened this issue Apr 2, 2024 · 6 comments

Comments

@3400442579
Copy link

如题

@leaferjs
Copy link
Owner

leaferjs commented Apr 2, 2024

目前需要自己结合拖拽事件判断下,或者你录屏展示一下具体使用场景(一般是需要用到哪个坐标系进行限制),我看看能不能支持一下,好像提这个问题的人挺多

@3400442579
Copy link
Author

image

 const { Leafer, Rect, Text, Box, Ellipse, Image, PointerEvent, ImageEvent } = LeaferUI
            const app = new LeaferUI.App({ view: "canvas", editor: { lockRatio: false } });

            app.tree = app.addLeafer()
            app.sky = app.addLeafer({ type: 'draw', usePartRender: false })
            app.sky.add(app.editor)

            const box = new Box({
                zIndex: 1,
                x: 30,
                y: 30,
                width: 200,
                height: 200,
                fill: '#FF4B4B',
                cornerRadius: 10,
                editable: false,
                overflow: 'hide',
            })
            const ellipse = new Ellipse({
                x: 0,
                y: 0,
                width: 350,
                height: 350,
                fill: '#FEB027',
                draggable: false,
                id: "ellipse1",
                zIndex: 1
            });
            box.add(ellipse);
            app.tree.add(box);

            var node_id;
            var down = false;

            ellipse.on(PointerEvent.DOWN, e => {
                down = true;
                app.editor.hittable = false;
                e.current.parent.overflow = 'show'
                e.current.opacity = 0.5;
                node_id = e.current.id;
            })
            app.on(PointerEvent.UP, e => {
                if (node_id && down) {
                    app.editor.hittable = true;
                    var node = app.findOne("#" + node_id);
                    node.parent.overflow = 'hide'
                    node.opacity = 1;
                    down = false;
                }
            })
            app.on(PointerEvent.MOVE, e => {
                if (down) {
                    var node = app.findOne("#" + node_id);
                    let x = node.x + e.origin.movementX;
                    let y = node.y + e.origin.movementY

                    let pbox = node.parent.getBounds('box', 'local');
                    let bo = node.getBounds('box', 'local');
                    if (x < 0 && x + bo.width > pbox.width)
                        node.x = x


                    if (y < 0 && y + bo.height > pbox.height)
                        node.y = y
                }

            });


@3400442579
Copy link
Author

上面 如果加了 变换 如: rotation:-90, around:'center', 就不能正常了

@leaferjs
Copy link
Owner

leaferjs commented Apr 3, 2024

你这种情况需要两个元素都用worldBoxBounds来对比才准确,有现成的检测是否包含的方法:

https://leaferjs.com/ui/guide/math/Bounds.html#includes-bounds-iboundsdata-boundsmatrix-imatrixdata-boolean

等于你的需求是让Ellipse 限制在 Box内拖动对吧?

@3400442579
Copy link
Author

用 worldToLocal 更新坐标 ,传入传数据发生变化了,界面没有变化

<html lang="zh">

<head>
    <meta charset="utf-8" />
</head>

<body>

    <div>限制区域 移动</div>
    <div id="image-editor">
        <div id="canvas" style=" height: 600px;"></div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/leafer-ui@1.0.0-rc.19/dist/web.min.js"></script>
    <script src="https://unpkg.com/@leafer-in/view@1.0.0-rc.19/dist/view.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@leafer-in/editor@1.0.0-rc.19/dist/editor.min.js"></script>
    <script>
        const { Leafer, Rect, Text, Box, Ellipse, PointerEvent, ImageEvent } = LeaferUI
        const app = new LeaferUI.App({
            view: "canvas",
            editor: { lockRatio: false },
            tree: {
                type: 'draw'
            }
        });

        const background = new Rect({ x: 0, y: 0, width: 800, height: 600, fill: 'gray' })
        const rect = new Rect({ x: 100, y: 100, fill: '#32cd79', draggable: true })
  
        app.tree.add(background)
        app.tree.add(rect)
     
        const box = new Box({
            zIndex: 1,
            x: 130,
            y: 130,
            width: 200,
            height: 200,
            fill: '#FF4B4B',
            cornerRadius: 10,
            editable: false,
            overflow: 'hide',
        })
        const ellipse = new Rect({
            x: 100,
            y: 100,
            width: 300,
            height: 200,
            fill: '#FEB027',
            draggable: false,
            id: "ellipse1",
            zIndex: 1,
            rotation: -90,
            around: 'center',
            //scale :2,
            //stroke:'green'
        });
        box.add(ellipse);
        app.tree.add(box);

        var node_id;
        var down = false;

        ellipse.on(PointerEvent.DOWN, e => {
            down = true;
            app.editor.hittable = false;
            e.current.parent.overflow = 'show'
            e.current.opacity = 0.5;
            node_id = e.current.id;
        })
        app.on(PointerEvent.UP, e => {
            if (node_id && down) {
                app.editor.hittable = true;
                var node = app.findOne("#" + node_id);
                node.parent.overflow = 'hide'
                node.opacity = 1;
                down = false;
            }
        })
        app.on(PointerEvent.MOVE, e => {
            if (down) {
                var node = app.findOne("#" + node_id);
                let set = false;
                let boundParent = node.parent.getBounds('box', 'world');
                let boundSelf = node.getBounds('box', 'world');
                console.info(boundParent)
                console.info(boundSelf)
                console.info("----")
                x = boundSelf.x + e.origin.movementX;
                y = boundSelf.y + e.origin.movementY

                if (x < boundParent.x && x + boundSelf.width > boundParent.x + boundParent.width)
                    set = true;
                if (y < boundParent.y && y + boundSelf.height > boundParent.y + boundParent.height)
                    set = true;

                if (set) {
                    var pos = { x: x, y: y };
                    console.info(pos)
                    node.worldToLocal(pos);
                    console.info(pos)
                    //pos = node.getLocalPoint(pos);
                    //node.x = pos.x;
                    //node.y = pos.y;
                }
            }
        });
    </script>


</body>

</html>

@leaferjs
Copy link
Owner

已经支持通过dragBounds限制拖动范围:

https://leaferjs.com/ui/guide/property/draggable.html#dragbounds-iboundsdata-parent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants