-
Notifications
You must be signed in to change notification settings - Fork 2
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
export type RectObserverCallback = (rect: DOMRectReadOnly) => void; | ||
|
||
const POLLING_RATE = 400; // ms | ||
|
||
export default class RectObserver { | ||
public elementTarget: HTMLElement; | ||
public callback: RectObserverCallback; | ||
public rect: DOMRectReadOnly; | ||
private poll: ReturnType<typeof setInterval>; | ||
|
||
constructor(callback: RectObserverCallback) { | ||
this.callback = callback; | ||
} | ||
|
||
public observe(element: HTMLElement): void { | ||
this.elementTarget = element; | ||
|
||
this.elementTarget.addEventListener("mouseenter", this.handleMouseEnter.bind(this), false); | ||
this.elementTarget.addEventListener("mouseleave", this.handleMouseLeave.bind(this), false); | ||
|
||
this.rect = this.elementTarget.getBoundingClientRect(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
} | ||
|
||
public disconnect(): void { | ||
clearInterval(this.poll); | ||
this.elementTarget.removeEventListener("mouseenter", this.handleMouseEnter.bind(this), false); | ||
this.elementTarget.removeEventListener("mouseleave", this.handleMouseLeave.bind(this), false); | ||
} | ||
|
||
private handleMouseEnter(): void { | ||
this.pollElement(); | ||
this.poll = setInterval(this.pollElement.bind(this), POLLING_RATE); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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! There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 :( There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
} | ||
|
||
private pollElement(): void { | ||
const rect = this.elementTarget.getBoundingClientRect(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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" There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. makes sense to me, let's revisit at some point though |
||
if(!this.rectEqual(this.rect, rect)) { | ||
this.rect = rect; | ||
this.callback(this.rect); | ||
} | ||
} | ||
|
||
private handleMouseLeave(): void { | ||
this.pollElement(); | ||
clearInterval(this.poll); | ||
} | ||
|
||
public rectEqual(prev: DOMRectReadOnly, curr: DOMRectReadOnly): boolean { | ||
return prev.width === curr.width && | ||
prev.height === curr.height && | ||
prev.top === curr.top && | ||
prev.left === curr.left; | ||
} | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?