Jump to content

Confusion about pivot/toLocal for dragging interaction


Cristobal
 Share

Recommended Posts

I'm trying to build an infinite canvas. I want to be able to click-and-drag the objects on the canvas, as well as to be able to drag the canvas itself and make the objects move with them.

For interaction with the objects, I'm setting the pivot to the local coordinates of the click to allow for smooth moving, independently from where I click.

I did something similar with that stage. However, once I move the stage itself, interaction with the object becomes very bizarre. It seems that there are some side-effects with changing the stage's pivot, however I can't quite wrap my head around what's happening.

I'm hoping for an explanation of how toLocal/pivot works, or if someone could hack together a functioning version of this from my code below, and somehow infer what I got wrong from the solution.

Thanks!

 

<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.1.1/browser/pixi.js" integrity="sha512-wkspHfuKFlenpKsDAxLXR/NZQth/6vQNxVr4qYb/MJA3Y7jQRLBRBJeoo4fClxxUU2nZp7eI/PsBm48M8VQ9bg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<body>
</body>

<script>

    const rgb2hex = (r, g, b) => PIXI.utils.rgb2hex([r / 255, g / 255, b / 255]);

    const app = new PIXI.Application({
        width: 800,
        height: 600,
        antialias: true,
        resolution: 1
    })
    app.renderer.backgroundColor = rgb2hex(253, 246, 227);

    // Global interaction flag to avoid bubbling of events to parents
    // e.stopPropagation() does not seem to be working
    let handledInteraction = false;

    const interactiveObject = (x, y, w, h) => {
        const elem = new PIXI.Container();
        elem.x = x;
        elem.y = y;
        elem.width = w;
        elem.height = h;

        const bg = new PIXI.Sprite(PIXI.Texture.WHITE);
        bg.tint = rgb2hex(238, 232, 213);
        bg.width = w;
        bg.height = h;
        elem.addChild(bg);

        elem.interactive = true;
        elem.isDragging = false;

        elem.on("mousedown", e => {
            handledInteraction = true;
            elem.isDragging = true;
            const pos = e.data.global;
            const localPos = elem.toLocal(pos);
            elem.pivot.set(localPos.x, localPos.y);
            elem.position.set(pos.x, pos.y);
        })

        elem.on("mousemove", e => {
            if (elem.isDragging) {
                const pos = e.data.global;
                elem.position.set(pos.x, pos.y)
            }
        })

        elem.on("mouseup", e => {
            if (elem.isDragging) {
                elem.isDragging = false;
                handledInteraction = false;
            }
        })

        return elem;
    }

    const e1 = interactiveObject(0, 0, 100, 100);
    app.stage.addChild(e1);

    const e2 = interactiveObject(200, 200, 100, 100);
    app.stage.addChild(e2);

    app.renderer.plugins.interaction.on("mousedown", e => {
        if (!handledInteraction) {
            app.stage.isDragging = true;
            const pos = e.data.global;
            const localPos = app.stage.toLocal(pos);
            app.stage.pivot.set(localPos.x, localPos.y);
            app.stage.position.set(pos.x, pos.y);
        }
    })

    app.renderer.plugins.interaction.on("mousemove", e => {
        if (app.stage.isDragging) {
            const pos = e.data.global;
            app.stage.position.set(pos.x, pos.y)
        }
    })

    app.renderer.plugins.interaction.on("mouseup", e => {
        if (app.stage.isDragging) {
            app.stage.isDragging = false;
        }
    })

    document.body.appendChild(app.view);
</script>

 

Link to comment
Share on other sites

  • Cristobal changed the title to Confusion about pivot/toLocal for dragging interaction

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...