Click here to see for yourself.
While looking to do some experiments with device motion data in HTML5, I found that there were no existing demos that would work on iOS 14. So, having spent a few hours figuring it out, I decided to write a tutorial with an up-to-date demo.
Conditions and caveats
Accelerometer and gyroscope are represented by DeviceMotionEvent and DeviceOrientationEvent accordingly;
- Devices without API support have window.DeviceMotionEvent as undefined.
- For some environments, listening to devicemotion is enough.
- For environments closely following the
updated specification
(such as iOS 13+),
the page must request a permission first by calling DeviceMotionEvent.requestPermission().
The permission dialog can only be brought up from a user gesture (tap/click)!
If the user had already granted the permission, you may call requestPermission without an interaction. - For other environments (such as all[?] Android devices as of writing this), DeviceMotionEvent.requestPermission is undefined and you may register a devicemotion listener right away.
- Environments that can never provide accelerometer data (such as desktop computers) may dispatch devicemotion events with either acceleration, accelerationIncludingGravity, and rotationRate set to null (per-spec) or their components (XYZ/rotation) individually set to null (not per-spec but Chromium 87 does this).
- As per security considerations, iOS will auto-decline the requestPermission call if the page is not loaded over HTTPS.
Code
So, with all of above in mind, a universal function to request accelerometer events would look as following:
/** * @param callback function(error) * @author YellowAfterlife **/ function requestDeviceMotion(callback) { if (window.DeviceMotionEvent == null) { callback(new Error("DeviceMotion is not supported.")); } else if (DeviceMotionEvent.requestPermission) { DeviceMotionEvent.requestPermission().then(function(state) { if (state == "granted") { callback(null); } else callback(new Error("Permission denied by user")); }, function(err) { callback(err); }); } else { // no need for permission callback(null); } }
And subsequently could be called like
function firstClick() { requestDeviceMotion(function(err) { if (err == null) { window.removeEventListener("click", firstClick); window.removeEventListener("touchend", firstClick); window.addEventListener("devicemotion", function(e) { // access e.acceleration, etc. }); } else { // failed; a JS error object is stored in `err` } }); } window.addEventListener("click", firstClick); window.addEventListener("touchend", firstClick);
(P.S.: Safari does not consider touchstart to be a user gesture event, but touchend is fine)
And for orientation, you can use the same logic, but with "orientation" instead:
/** * @param callback function(error) * @author YellowAfterlife **/ function requestDeviceOrientation(callback) { if (window.DeviceOrientationEvent == null) { callback(new Error("DeviceOrientation is not supported.")); } else if (DeviceOrientationEvent.requestPermission) { DeviceOrientationEvent.requestPermission().then(function(state) { if (state == "granted") { callback(null); } else callback(new Error("Permission denied by user")); }, function(err) { callback(err); }); } else { // no need for permission callback(null); } }
(note: so far Safari combines the two so you don't have to request them independently)
Conclusion
Although the HTTPS requirement is a slight inconvenience for local tests, you can still use accelerometer and gyroscope in a reasonable way.
Thanks for this, indeed a lot of demo’s were outdated.
As for the ssl requirement, I uses mkcert for those situations, very handy.
https://github.com/FiloSottile/mkcert
Hello
I like it a lot.
I also have some extension of yours and it works perfectly.
I wonder if you could make an extension to publish an official app on KaiOS phones using only Game Maker. Something simple; that you can use the phone keypad, save / load a file, play sounds and little else.
If you want you can answer me by mail.
Thanks.
If the phone does not run a GameMaker HTML5 game as-is, and JS console shows errors that aren’t just about missing browser features, it is likely a very expensive goal to pursue that would require writing a custom compiler and a runtime for it from scratch.
You are surely right.
… Yes, it works for me to upload a game programmed in GML (html5) to my personal website and convert it into an application from there … but little else.
Thank you very much for your answer; it is very useful to me.
wow, so cool!