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

Fix node bound displacement #24

Merged
merged 4 commits into from
Jan 19, 2021
Merged

Fix node bound displacement #24

merged 4 commits into from
Jan 19, 2021

Conversation

mj3cheun
Copy link
Contributor

@mj3cheun mj3cheun commented Jan 8, 2021

Fixes #10
Replaces #9

@darionco
Copy link
Contributor

This one looks good, I'll run some local tests to make sure it fixes the issues we were seeing, @adamocarolli could you also test this branch on your system? Seems to me that this bug could be OS/Browser specific.

@darionco
Copy link
Contributor

Unfortunately, this doesn't fix the issue pointed out by the bug. As you can see in the video below, using the example file uploaded by @adamocarolli, the mouse coordinates shift after scrolling the page. #9 tries to solve the issue by always using a fresh rect rather than caching it, that solution works fine for clicking but it breaks hovering which leads me to believe that there's a logic mistake somewhere.

simplescreenrecorder-2021-01-11_11.10.27.mp4

@mj3cheun
Copy link
Contributor Author

Ok thanks for catching that. I think theres a bug in the logic of my code, lemme test something.

@adamocarolli
Copy link
Contributor

Recent changes resolve picking issue for me when testing locally on MacOS/Chrome!

@@ -271,7 +262,7 @@ export class MouseHandler extends EventEmitter.mixin(UXModule) {

this.newState.valid = Boolean(
canvas[0] >= rect.left && canvas[0] <= rect.right &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this also be normalized to local coordinates?

canvas[0] >= 0 && canvas[0] <= rect.width

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the tests I have run, it seems to work without also normalizing the x coordinates. (I only noticed the bug in the y direction) I get your point though, it seems weird that not normalizing the y coordinates would create a bug but not normalizing the x coordinates would be fine. I think its worth keeping an eye out for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you tested with horizontal scrolling?


private handleMouseEnter(): void {
this.pollElement();
this.poll = setInterval(this.pollElement.bind(this), POLLING_RATE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you looked into this, but are 100% sure there's no other way? polling seems horrible!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as my research has found there is no other way to reliably track changes to rect. I am not happy about polling either ya :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok this is good for now, we should revisit at some point with #30

this.elementTarget.addEventListener("mouseenter", this.handleMouseEnter.bind(this), false);
this.elementTarget.addEventListener("mouseleave", this.handleMouseLeave.bind(this), false);

this.rect = this.elementTarget.getBoundingClientRect();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we updating the rect on mouse enter/leave? what's the use case?

Copy link
Contributor Author

@mj3cheun mj3cheun Jan 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, there is no point in checking rect on mouseleave, so that can be removed with no effects.

As for mouse enter, I think its a good idea to check if rect needed to be updated when the cursor first enters the graph element to ensure that there are no visible errors as the user interacts with the graph. This is made necessary by the slow polling rate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool, that makes sense, made a note on #30 to track this change

}

private pollElement(): void {
const rect = this.elementTarget.getBoundingClientRect();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are updating the rect so often here that I wonder if it would be easier (and more performant) to calculate the rect in the mouse handler when the mouse moves, maybe have some other caching mechanism?

I feel like this approach is too "hot"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So theres a few things I am doing in order to make this solution as low impact as possible. First, note that the polling period is 400 ms. This is as slow as I can possibly make it I feel before its possible for the user to notice any trigger inaccuracy. Second, the class maintains a record of the previous rect value, and it compares the new rect values with the old. It will only call the callback function if there is any difference. Therefore the performance impact when the location and size of the element is constant should be very small, as the most expensive function in this case is getBoundingClientRect. In the case where the element is actually moving, I think that its possible for this polling strategy to be even more performant compared to a naive observer strategy where the callback could be called every frame.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense to me, let's revisit at some point though

@darionco
Copy link
Contributor

Opened #30 to keep track of unresolved comments

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

Successfully merging this pull request may close these issues.

Node picking mouse-in/mouse-out events triggered outside node bounds
3 participants