Jump to content
Search Community

Draggable.hitTest in a scrolled window

andycamp00

Go to solution Solved by GreenSock,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Posted

While doing hit test while the window is scrolled, I don't seem to get the correct results.  This occurs if I am trying to compare the pointer event of the mouse.  The code pen example demonstrates it: the top 2 boxes will work correctly, but if you scroll the demo window down and try with the bottom 2 boxes the hittest will still return false.

 

My initial thought is that this has something to do with some confusion or misuse somewhere between clientx/pagex, but I'm just beginning to investigate.  Any ideas or pointers?

See the Pen zGbLBp by acamp (@acamp) on CodePen.

Posted

Hi Andy,
 
What jumps right out is the fact that you're passing an event object as the second parameter of the hitTest() method. The second parameter is normally the overlapping amount (in pixels or percentage) between the two elements and that's either a value or a string. In this case you're passing either a mouse or touch event object. Second you're trying to use the static version of the hitTest(), why not use the regular one:

hitTest = this.hitTest("#drop1", e);

That actually works with the setup you have in place.

 

It seems that Draggable is not updating the new position of the hitTest target after a scroll when using the static hitTest method, perhaps Carl or Jack could explain this. Meanwhile hopefully the code above helps.

  • Like 1
Posted

Draggable uses pageX/Y for events, but you can create your own point like this.

var x = e.clientX;
var y = e.clientY;
var point = {      
  left: x,
  right: x + 1,
  top: y,
  bottom: y + 1
};
var hit = Draggable.hitTest(element, point);

So here's your example with that...

See the Pen zGbLja by osublake (@osublake) on CodePen.

 

And here's a demo I made that demonstrates why hit testing a event might not be what you expect.

See the Pen JoQbya by osublake (@osublake) on CodePen.

  • Like 3
Posted

Thanks Rodrigo - thanks for the reply.  My example is a bit contrived.  I agree that if I compare the 2 boxes with the non static version, things work well, but for my actual application I'm looking to do a hittest with the pointer event - the dragging example was a convenient way to show this.  But the hitTest docs (http://greensock.com/docs/#/HTML5/Drag/Draggable/hitTest/) state that a pointer event is a supported object...

Posted

Thanks Blake.  I was just finding my way to this, that's a sweet codepen Demo :).  Thanks for the tip on using clientX/Y, that does seem to solve my problem... (although getting clientX/Y on touch events is my next complication).

 

I'm curious why hitTest uses PageX/Y for pointer events... it appears that for DOM elements it uses getBoundingClientRect(), which is a clientX/Y based result.  So it would make sense to use clientX/Y for everything when doing hit tests...

Posted

Thanks! I thought it was a pretty cool demo, but you're the only person who has acknowledged it.

 

I don't know why it uses pageX/Y, but I ran into the same problem and I saw in the source code that it just creates a 1x1 rectangle to test.

 

What touch problems are you having? I would just look at how Draggable handles them because they are spot on. 

  • Like 1
Posted

Thanks! I thought it was a pretty cool demo, but you're the only person who has acknowledged it.

 

I had never seen it before, but I'll acknowledge it now - that's cool!   8-)

  • Like 1
Posted (edited)

Thanks Greensock, that version doesn't seem to solve the problem, although I did a diff and there were no differences in the parseRect() or hitTest() functions between the version 1.14.1 you linked and version 1.14.0 (of my current draggable file) that I am using.  There were some changes from self to this, and some changes in the _cache function.

 

Edit: I updated my codepen at 

See the Pen zGbLBp by acamp (@acamp) on CodePen.

to point the latest-beta link above.

Edited by andycamp00
Posted

For blake:

 

What touch problems are you having? I would just look at how Draggable handles them because they are spot on.

 
No problems, but for touch events, the events store data differently - and I can see several examples of this in the Draggable code with comments like:

 

if (e.changedTouches) { //touch events store the data slightly differently

 

The event object from a touch doesn't have a clientX or clientY prop, but they have a changedTouches property that is an array of points with clientX (and, on iOS at least, also a touches property that is an array of points..)

 

Anyway, I'll look through Draggable and see how it works, it seems to be using changedTouches all the time.  Not too bad; I wasn't looking forward to figuring out all the compatibility issues for different touch platforms... but it doesn't look too bad.

Posted

so my current workaround code modifies blakes slightly:  

var x, y;

if (e.changedTouches) {
  x = e.changedTouches[0].clientX;
  y = e.changedTouches[0].clientY;
} else {
  x = e.clientX;
  y = e.clientY;
}

var point = {      
  left: x,
  right: x + 1,
  top: y,
  bottom: y + 1
};
var hit = Draggable.hitTest(element, point);

This works on iOS at least, for a normal touch-drag scenario.  I need to learn more about changedTouches prop to find out if it is universal and if using the first element in the array is always OK...

Posted

Hi andycamp00  :)

 

Pls add something like ' ?20 ' at the end of js address to prevent browser using old/cashed one .

 

pls check this out : 

See the Pen JdzqrW by MAW (@MAW) on CodePen.

Posted

Ah, of course... that works.  Thanks!  I'll mark the original link from to the fix as solved.

  • Like 1
  • 2 weeks later...
Posted

Hi Jack,

Thank you for the fix in the Draggable-latest-beta.js. It works great.
However there is a an exception being thrown in IE8 when I call this line:
 

if( Draggable.hitTest(this, e) ){
}

 
 
File: Draggable-latest-beta.js
Line: 2127 
 
Unable to get property 'getBoundingClientRect' of undefined or null reference
 
This is the faulty line:

var r = (e.pageX !== undefined) ? {left:e.pageX - _getDocScrollLeft(), top:e.pageY - _getDocScrollTop(), right:e.pageX - _getDocScrollLeft() + 1, bottom:e.pageY - _getDocScrollTop() + 1} : (!e.nodeType && e.left !== undefined && e.top !== undefined) ? e : _unwrapElement(e).getBoundingClientRect();

 
Do you have an idea what is causing the error?
 
Thanks!
 
Simon

Posted

Technically hitTest() isn't supported in IE8 and earlier (those browser have zero support for getBoundingClientRect() as you discovered which is rather important. However, I did update the preview so that at least it shouldn't throw errors now: https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/Draggable-latest-beta.js (you may need to clear your cache). Does that work better for you? 

  • Like 2
Posted
Oh I see. Yeah, the new latest-beta doesn't throw the error anymore.

Thanks for clarifying this so quickly. 

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...