Jump to content
Search Community

Draggable hitTest issue with OverFlow

Kieran_St test
Moderator Tag

Recommended Posts

Hi all!

 

First time posting here, been fiddling with GSAP on  and off for a month or two, and been playing with the draggables lately.

 

I'm trying to get a scrollable div which contains a number of 'slots' which can contain 'items', but where I can drag the items in it around the page (to other 'slots' or to areas outside of the scrollable div)

 

This means I've had to make a clone of the item attached to an 'external' div and make that draggable so that I can 'escape' the scrollable div.

I've also had to make a custom click event handling system as I want to be able to take different actions on click as well as drag

 

I've got two issues, one small, one big...

 

The small issue:

Dragging to the edge of the scrollable div doesn't scroll the div.

I've got some event preventDefaults on the mousedown and mousemove events but thats so that when dragging, it doesn't highlight all the text on the page you drag past.

 

The big issue:

Dragging the item over a slot hidden by overflow-y still registers as a hit using hitTest, even though the div is not visible on the page. (Try dragging the red box underneath the container div, and watch the hit result above (where it initially says "hi") )

 

----

 

I'm using Vue 3 with GSAP, the codepen is a de-vue-ified version of the drag script and click event handlers, and a super basic static example of the item/slot setup (in reality I've got them 4-5 per row for multiple rows, but not needed for the pen) and I've got it replicating the same issue.

 

Hopefully I've transcribed enough of my code to find the issue xD

 

Please let me know if anyone has any ideas for solutions, and if any more info is needed.

 

Thanks in advance ❤️

See the Pen yLoxxNo by kieran-s (@kieran-s) on CodePen

Link to comment
Share on other sites

Welcome the forums @Kieran_St

 

I made a demo several years ago that kind of does this, although it's not perfect and could definitely use some fine tuning, but maybe it can give you some ideas.

 

90c81d57a2d4f01a60a53b6bf5cc161d.gif

 

 

See the Pen XdQPvJ by osublake (@osublake) on CodePen

 

From this thread...

Quote

The hard part is figuring out if the user want the container to scroll, or are they trying to remove the item from the container as those are mutually exclusive actions.

 

  • Like 2
Link to comment
Share on other sites

7 hours ago, OSUblake said:

I made a demo several years ago that kind of does this, although it's not perfect and could definitely use some fine tuning, but maybe it can give you some ideas.

Oh nice, I'll have to scour the code more when I wake up to understand exactly how you're doing that :P ... but thanks for the pen, looks like it'll handle my small problem :)

 

Now I just have to figure out the big problem with the hittest xD
(although that might be a case of some convoluted system of checking the height of the scrollable div vs the location height of the hittest div... but I'm hoping there is a... cleaner... way of fixing it)

Link to comment
Share on other sites

I've managed to make a fix for the big issue by comparing bounding rects, although I'm not sure if it's the best way or not.

Basically it'll calculate the top and bottom of the bounding container (not the item direct parent, but the parents parent basically), then it'll figure out what the top and bottom of the dropzone is, and it'll make sure it's within the bounding container.

 

Needs a few minor tweaks for consistancy, but yea...

 

If anyone has a better solution (or if GSAP has a built-in fix for this), please let me know :D❤️

 

See the Pen mdMGYyR by kieran-s (@kieran-s) on CodePen

 

if (this.hitTest(els[i], '40%')){
    const zone = els[i].getBoundingClientRect();
    const area = document.getElementsByClassName('container')[0].getBoundingClientRect();

    // Dropzone is above the bottom of the inventory container
    if (zone.y < (area.y + area.height)) {
        // Dropzone is below the top of the inventory container
        if (zone.y > area.y) {
            validZone = els[i];
            break;
        }
    }
}

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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