Mouse.position and requestPointerLock

242 views
Skip to first unread message

wighawag

unread,
Feb 9, 2015, 11:17:47 AM2/9/15
to elm-d...@googlegroups.com
Hi,

for a game, I would like to hide and lock the mouse pointer. This can be achieved with the html5 method "requestPointerLock"

After such request is approved by the player, the mousemove event still trigger but event.clientX, event.clientY is not changed. Instead we need use event.movementX and event.movementY to track where the player is going.

Currently Mouse.position relies on event.clientX/clientY.
This means that when requestPointerLock is accepted, the Mouse.position signal trigger a constant stream.

What would the best way to go arround this problem.
Should Elm provide a Mouse.movement signal ?
Any other thoughts ?

Thanks

wighawag

wighawag

unread,
Feb 11, 2015, 10:50:08 AM2/11/15
to elm-d...@googlegroups.com
Anybody?

Not sure if it was clear enough so I ll try to reformulate the problem :

Html elements have the following method : "requestPointerLock" see https://developer.mozilla.org/en-US/docs/Web/API/Element.requestPointerLock
this is used for example in first person shooter so you can do a full rotation of the player without being blocked by the mouse pointer reaching your screen border (where it cannot move further anymore).

The way to get this behaviour it is to call canvas.requestPointerLock upon a player action, like clicking on the canvas
Upon the player agreeing with locking its pointer,  an event is triggered and from that point in time, all mousemove event contain a fixed clientX,clientY value (the one representing the current mouse position) and a movementX, movementY values which represent how much the "locked" pointer virtually moved from the last time

For Elm, this means for the duration on which the lock is active that while the Mouse.position signal get triggered, its value is always constant.
It also mean that there is no way to access the information of movement (which is provided by event.movementX, event.movementY)

For now I could use port to create my own Mouse.movement Signal but I suppose Elm would like to support such feature. Also if I implement it myself I would duplicate some of the stuff being done by elm regarding the mouse.
It is also likely that Mouse.position Signal should not be triggered if its position is not changed.

Any though on this?

I am not to sure yet but this also relate to a bigger story : should elm runtime be separated from the native signal implementation ?
could such native signal be provided as libraries, or maybe should they be provided as port ? This way we could easily try different implementation.

Not sure if that last observation make sense.

Thanks for reading

Hassan Hayat

unread,
Feb 11, 2015, 3:15:13 PM2/11/15
to elm-d...@googlegroups.com
I've looked around for a bit and it seems that the best bet currently is to do it in Javascript. The best way would be to do it via a port (or sneakily in the JS if you're the hacker type). I can't figure out a good design for a native library function yet.

That said, given the upcoming promises feature that seems to be around the corner, you'll be able to do the following:

requestPointerLock : Html -> Promise error ()

This function'll do what you think and request to lock the pointer around a given Html element. If it succeeds great, if it fails it'll return some error.

Given how useful this thing is for games, I'll personally add this function myself and publish it to the package manager. Mainly cuz I really want it.

As for the mouse stuff, if you can work around the problem for the moment that would be great. That said, I think that an interesting project would be to fully wrap all of the html5 input apis, including the Gamepad API. That would be done almost entirely via Signals.


About your last observation about the bigger story, I see it as follows:

- Stuff that I consider to be continuously part of my app (like, mouse clicks, keyboard presses, time deltas, etc...) should be Signals. They're basically streams of continuous (or near-continuous) input. This is the stuff that is instantly responsive. This can be implemented via native modules.

- Stuff that I call once in a while and have a feel of like "go do this and return whenever you can... someday..." those I see as Promises. The sort of stuff here is like, "fetch this data from the cache", "send this via http", "ask the gps about my current position", etc... These things take time and run asynchronously. This too can be implemented via native modules. (I admit that certain things fall in the middle: are they Signals or are they Promises... but most things are clear cut)

- Anything else, ports (There's not much left to be honest). I see ports as mostly used to interact with other code in your codebase.
 This would be especially useful if you intend to sprinkle just a tiny bit of Elm into a mostly JS codebase and I believe that this was the goal of the design (although Evan should confirm this).
That said, while we're talking about games, ports have another big use : interface with JS code that came from C++/Fortran. You're probably familiar with this, but if you arent, basically there's this thing called Emscripten which allows you to compile C++/Fortran (or anything that can target LLVM) to Javascript. Why do such a thing? Well, game engines and physics engines are mostly written in C++ and super intensive Math for scientific computing is mostly written in Fortran. But these codebases are not at all written with functional programming in mind. This is code written that is really highly optimized, like every bit and cycle is carefully optimized. So it's super imperative. It would be way too much of a headache (trust me, I tried) to wrap these libraries in Elm. Your best bet is simply to communicate with them via ports. 


I hope this has answered a bit your question.

wighawag

unread,
Feb 12, 2015, 9:39:12 AM2/12/15
to elm-d...@googlegroups.com
Hi Hassan

Thanks for your reply,

I was not too worried about calling requestPointerLock itself except maybe that it require to be called from a user interaction listener (mouse click, key press...) but I think this should work if we trigger once through one of Elm Signal.

the bit I was concerned that you addressed to some extent is what the best way to handle the "Mouse being locked" functionality
 Elm Mouse module cannot handle it right now (as it does not expose movementX, movementY)  and while I could write a Native signal to support it it would duplicate some of the stuff done under the hood for Mouse.position.
it seems best that Elm Mouse module handle all the basic stuff related to mouse.

This bring to the bigger story I was alluding to ( which I should probably write another thread) : Elm does not seem to be easily customisable/extensible.
One way to address it would be to break the actual runtime (that deal with Signal in a generic way) and the Native modules. There are currently both under elm-runtime.
I think we should even go further and make these native module separate libraries (whether they are included by default is another matter)

When I was thinking about port is that we could implement our native signal via port. not sure if that make sense but to me from what I gathered it would make things more consistent : we do not use Native module, only ports.
the mouse stuff would be a port and the html would include 2 js (might be combined in the end) : 1 for the elm-runtime and one for the mouse stuff.

This way if I wanted to implement my own mouse signal, I just could create a library that work with port.

I am not too use if that make sense.

let me know if it is worth another thread

Thanks again,

Ronan






--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

wighawag

unread,
Feb 12, 2015, 9:41:37 AM2/12/15
to elm-d...@googlegroups.com
oh and when I said "duplicate some of the stuff done under the hood for Mouse.position." I mean 2 sort of duplication : code and runtime (the native Mouse module will still exist listening for mousemove event while my own one would do a similar thing at the same time)
Reply all
Reply to author
Forward
0 new messages