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 ScreenSpaceEventHandler when Cesium does not take up the entire browser window #2417

Merged
merged 4 commits into from
Jan 28, 2015

Conversation

kring
Copy link
Member

@kring kring commented Jan 22, 2015

A bug was introduced in #2408 that breaks mouse events completely when the Cesium canvas is not in the upper-left of the browser window.

The problem is that clientX and clientY are relative to the client area of the overall browser window, not the DOM element, even for listeners attached to a specific element.
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.clientX

@pjcozzi
Copy link
Contributor

pjcozzi commented Jan 22, 2015

@bagnell can you review please?

@kring
Copy link
Member Author

kring commented Jan 23, 2015

I found a related bug in CameraEventAggregator. Fix coming soon.

@pjcozzi
Copy link
Contributor

pjcozzi commented Jan 23, 2015

@kring
Copy link
Member Author

kring commented Jan 23, 2015

The related bug I mentioned above is separate from the issue mentioned on the forum, and is now fixed in this pull request. CameraEventAggregator was receiving events from two different ScreenSpaceEventHandlers, and not accounting for the fact that they provide coordinates in two different coordinate systems (document versus canvas).

@mramato
Copy link
Contributor

mramato commented Jan 23, 2015

I know very little about the mouse handling code, but isn't canvas.getBoundingClientRect(); a performance bottleneck? I'm pretty sure some browsers reflow/recalculate it every time it's called. I think we cache results like this in other places and only compute it once at the beginning of the frame. In this case it might not be an issue, but I just wanted to bring it up.

@shunter any thoughts here?

@pjcozzi
Copy link
Contributor

pjcozzi commented Jan 26, 2015

Any update? We'll want to merge this this week so it makes 1.6.

@bagnell
Copy link
Contributor

bagnell commented Jan 27, 2015

This looks good to me. Just waiting on a response to @mramato's comment.

@emackey
Copy link
Contributor

emackey commented Jan 27, 2015

I found various references here and there that suggest a full layout is triggered by getBoundingClientRect. We're already getting the size in viewer.resize() every frame, is it reasonable to pass that size down into the handlers somehow?

@kring
Copy link
Member Author

kring commented Jan 28, 2015

We're already getting the size in viewer.resize() every frame

Size, yes, but we're not calling getBoundingClientRect every frame. That's good because we only need it on input, which happens less often than rendering.

is it reasonable to pass that size down into the handlers somehow?

Not really. The top of the call stack is an input event, so we can't pass it down from there. The best we could do is compute and cache the rectangle if it's undefined, and then reset it to undefined each frame. I started trying to do this but it's ugly and likely to lead to bugs. In particular, ScreenSpaceEventHandler has no notion of render frames and no dependence on Scene. The scene could potentially reset its ScreenSpaceEventHandler(s) each frame, but what if the user creates their own? I think that's somewhat common because a single ScreenSpaceEventHandler can only have a single handler per input event. The user would need to remember to reset it each frame (or at least anytime the size/location of the canvas changes). If they don't, they get weird bugs.

I just committed a change to reduce the number of calls to getBoundingClientRect a bit, so maybe that makes it more acceptable to everyone.

By the way, this pull request brings Cesium's input handling from "horribly broken" to "working but possibly not quite as optimal as it could be" so merge it already! 6 days, sheesh. :)

@emackey
Copy link
Contributor

emackey commented Jan 28, 2015

Agreed we should merge this before the release.

input, which happens less often than rendering.

With one important caveat: When you're moving the mouse, dozens of mousemove messages come in per frame. That's the reason for the CameraEventAggregator, is to gather up those messages and limit activity to once per frame. In theory we could make less calls by moving the logic there, but in practice I don't know if additional re-layouts are actually caused by multiple calls in the same frame.

Anyway, I did a little performance testing of this vs master, and I couldn't spot the difference. So @bagnell I think you should merge.

@mramato
Copy link
Contributor

mramato commented Jan 28, 2015

As @emackey stated, profiling doesn't show any performance issues (I tried IE, Firefox, and Chrome).

mramato added a commit that referenced this pull request Jan 28, 2015
…inates

Fix ScreenSpaceEventHandler when Cesium does not take up the entire browser window
@mramato mramato merged commit fb3df24 into master Jan 28, 2015
@mramato mramato deleted the correctMouseCoordinates branch January 28, 2015 14:56
bagnell added a commit that referenced this pull request Jan 29, 2015
…entHandler to listen on the document for pointer up and move events.
@bagnell bagnell mentioned this pull request Jan 29, 2015
bagnell added a commit that referenced this pull request Jan 29, 2015
…entHandler to listen on the document for pointer up and move events.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants