I'm building a 360 panorama viewer with A-Frame 1.0.4 and I'm having some trouble with older devices that I don't know how to solve. I'm testing in a WebView inside an Android application.
On most recent devices, the gyroscope and accelerometer work great, but on older devices (for example ASUS X008D), it's all shaky, the view can't stay still when I put the phone on the table or when I hold it. I thought it could be due to polyfills but I can't figure how. I added some logs to check for DeviceMotionEvent and DeviceOrientationEvent and both are recognized but it seems like it's not enough.
How could I be sure that the events are handled correctly and eventually disable the hmd in look-controls manually when it's not stable enough? There would still be the dragging and I would be fine with that.
Thanks for your help :)
After further investigations I found out where the issue came from. It was because the Sensor API was not available on some devices and the Gyroscope wasn't read correctly. If I understood correctly there was a fallback on DeviceMotion but it was probably not good on older devices, I don't know...
What I did to "fix" this was writing this little snippet to check that the Gyroscope class was available. If it was not I disabled all movements from look-controls component to allow only manual movements. I hope it can help anyone who meets this issue. It's kinda quick'n'dirty but it did the job so I'm okay with this.
var gyroscope = null;
try {
gyroscope = new Gyroscope();
gyroscope.addEventListener('error', event => {
document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
});
gyroscope.start();
// Stop the gyroscope after trying so it does not run in background.
setTimeout(function() { gyroscope.stop(); }, 500);
} catch (error) {
document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
}
There's also an open issue about it on A-Frame github page.
Related
How can I detect if the screen is inverted on at least iOS in Cordova? More specifically I’m looking to support the iOS 11 “smart invert” feature, however it doesn’t matter if this “invert detection” is also triggered by the “classic invert.”
I’ve seen the phonegap accessibility plugin, but I don’t see how to utilize it for this case without simply setting an interval to check it over and over again, which seems like too much of a hack to me. I’m looking for an event-based approach if possible.
Reading further, I missed the fact that the phonegap-mobile-accessibility plugin has events that you can listen to, including for invert colors. As such, using this plugin, you can bind an event as shown below:
window.addEventListener(
MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED,
info => { // info.isInvertColorsEnabled });
As well, you can check the status at any time (e.g. on page load) like so:
MobileAccessibility.isInvertColorsEnabled(
b => { // typeof b == “boolean” });
I have a kiosk in train station public place and in airport.
Random people needs to use the touch screen application which is running on Google chrome. When the user apply unpinch or pinch action on Google chrome
then Google chrome makes abnormal zoomed in screen and leaves the screen zoomed in forever, and then i get call that my application do not work.
Using chrome://flags/#enable-pinch in past Google chrome was able to kill the pinch but now in new version they removed that feature also following options none of them works anymore like it used to work in past with``chrome://flags/#enable-pinch`
chrome://flags/#touch-events - if i disable this it disable whole touch inputs on Google chrome
<meta name="viewport" content="width=device-width, user-scalable=no"> - if i apply this it has no effect on Google chrome, still pinch/unpinch attacks occure
Therefore, i kept trying all other possible way to resolve it
I am pulling all my hair out because all options are failing.
Can anyone please advise how to resolve it? How do i absolutely disable the pinch/unpinch on Google chrome or on whole operating system? I also tried control panel but none of the control panel showing an option where it says disable pinch/unpinch attacks.
// Dear God, please give me a Pinch disable option for, Google chrome. Its a nightmare, nothing stops pinch zoom actions.
window.addEventListener("touchstart", touchHandler, false);
function touchHandler(event){
if(event.touches.length > 1){
console.log("pinch "); // detected
window.location.reload();// detected
try {
event.preventDefault(); // FAIL FAIL FAIL FAILLLLLLLL ???????????
return false;
}catch(eee) {
}
}
else {
console.log("pinch not");//detected
}
}
ANSWER: 2018
I've been trying to solve the same issue with a kiosk application. I've tried meta tags and touch events but nothing on the application side would work for me.
In the end the solution I found was disabling pinch from the command line when booting up Chrome in kiosk mode
Here's an example:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --start-fullscreen --kiosk
--disable-pinch http://127.0.0.1:1000
I am guessing that I am a bit late for you, but for the next people who find this via google, the solution is actually pretty simple, by just using pure CSS.
The property you are looking for is touch-action and as explained by MDN:
The touch-action CSS property specifies whether, and in what ways, a
given region can be manipulated by the user via a touchscreen (for
instance, by panning or zooming features built into the browser)
A basic solution of disabling all pinch to zoom would be the following code snippet placed in your CSS.
body {
touch-action: none;
}
There are other options souch as pan-x, pan-left, pan-right, pan-y, pan-up, pan-down, pinch-zoom.
Check the full docs # https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
** See Edit 2 for the current solution to this issue. **
I have a somewhat obscure issue that Google and searching through StackOverflow hasn't solved yet. Paper.js isn't working through iOS.
Currently I'm building a whiteboard drawing web-app that utilizes paper.js for the drawing functionality. It's working just fine on the desktop in Chrome, FireFox, and Safari. On Android devices it works fine, but is quite laggy. The problem crops up when using the app on iOS devices.
For some reason it is not possible for my app to create paths when using it on iOS through mobile Safari or mobile Chrome. The behavior on iOS is just a non-responsive canvas.
I currently don't have access to a device that I can use for remote debugging, so I am not able to gather any useful debugging data.
Web app link for testing.
http://alexpersian.github.io/html/whiteboard.html
Code snippet of paperscript involved in drawing.
var myPath;
function onMouseDown(event) {
myPath = new Path();
myPath.add(event.point);
myPath.strokeColor = WBAPP.penColor; // WBAPP is from main Javascript
myPath.strokeWidth = WBAPP.penStroke;
myPath.strokeCap = 'round';
}
function onMouseDrag(event) {
myPath.add(event.point);
}
function onMouseUp(event) {
myPath.simplify();
}
Edit: I've completed some further testing and found that it works on devices running iOS 7, but not iOS 8. I'm curious if there was a change to iOS 8 that limited touchEvents web interaction.
Edit 2: I was able to solve this issue by adding this snippet of code.
document.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
This prevents the default touch action on iOS 8, which seems to be a scroll/pan action, because it interferes with the onMouseDrag event from paper.js.
Jürg Lehni, paper.js co-creator, is looking into whether this should be included in the library itself. Until then, this snippet should help.
Hey probably you will need to implement touch events you can use
http://labs.rampinteractive.co.uk/touchSwipe/demos/ to do that
or
http://www.homeandlearn.co.uk/JS/html5_canvas_touch_events.html
Can I use Javascript in a cross-platform way to get the compass heading in iOS and Android (with Chrome), without using something like PhoneGap? I know iOS has DeviceOrientationEvent, but I can't find any equivalent on Chrome for Android.
As a primer you should review this previous related StackOverflow answer and be familiar with the general practical considerations for using DeviceOrientation Events in web applications.
The simple solution I provided in my previous related StackOverflow answer only applies to browsers that implement absolute deviceorientation events (i.e. browsers where the deviceorientation alpha property is compass-oriented). That means the solution provided there currently only works in Android browsers and not iOS-based browsers or any other browser that does not provide absolute-based deviceorientation event data.
To reliably obtain the current compass heading across both Android and iOS browsers today you need to handle both absolute and non-absolute implementations that provide the additional webkitCompassHeading property and make sure to account for any current screen orientation changes as part of that. AFAIK the only library that currently does this is Full Tilt JS (disclaimer: I am the author of this library).
The following code will give you the same correct compass heading across both iOS and Android browsers, taking account of the differences in device orientation implementations and applying any necessary runtime screen orientation transforms too:
<!-- Include the Full Tilt JS library from https://github.com/richtr/Full-Tilt-JS -->
<script src="fulltilt-min.js"></script>
<script>
// Obtain a new *world-oriented* Full Tilt JS DeviceOrientation Promise
var promise = FULLTILT.getDeviceOrientation({ 'type': 'world' });
// Wait for Promise result
promise.then(function(deviceOrientation) { // Device Orientation Events are supported
// Register a callback to run every time a new
// deviceorientation event is fired by the browser.
deviceOrientation.listen(function() {
// Get the current *screen-adjusted* device orientation angles
var currentOrientation = deviceOrientation.getScreenAdjustedEuler();
// Calculate the current compass heading that the user is 'looking at' (in degrees)
var compassHeading = 360 - currentOrientation.alpha;
// Do something with `compassHeading` here...
});
}).catch(function(errorMessage) { // Device Orientation Events are not supported
console.log(errorMessage);
// Implement some fallback controls here...
});
</script>
Here is a demo that demonstrates this technique to obtain the compass heading the user is facing. It should work well on both iOS and Android browsers.
The implementation of the code in that demo is as shown above and can be viewed on Github at ./scripts/compass.js:L268-L272.
Yes you can! Unfortunately the alpha doesn't work on iPhones/iPads. With Mobile Safari, alpha is based on the direction the device was pointing when device orientation was first requested. The included webkit offers you the compass heading. To make it work for all other browsers (which all supports alpha as compassheading) you can use the following Javascript code:
if (window.DeviceOrientationEvent) {
// Listen for the deviceorientation event and handle the raw data
window.addEventListener('deviceorientation', function(eventData) {
var compassdir;
if(event.webkitCompassHeading) {
// Apple works only with this, alpha doesn't work
compassdir = event.webkitCompassHeading;
}
else compassdir = event.alpha;
});
}
Android also supports Webkit, so would also use event.webkitCompassHeading, but that's OK.
BTW: "oncompassneedscalibration" is also not supported for iPhones and iPads.
I believe you can use the "heading" field of the location object, from navigator.geolocation, please see here:
https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation
I know no other way.
Hope it helps,
A.
I am developing a web-app utilizing Application Cache, and everything is working great on desktop browsers and on Android (even very old & slow android handsets). However downloading the appcache is taking much much much longer on iOS 6 in both Safari and Chrome.
My application cache total size is a mere 2.1Mb, and I have a pretty solid 70Mbps (download) internet connection. I would expect caching to be pretty rapid.
Here are my times so far:
Desktop Chrome: <1s (similar times for Safari & Firefox)
Android 2.3.3 Stock Browser: ~4s (similar times for Chrome & Dolphin)
Android 4.2.2 (Emulated): ~7s (running inside a PhoneGap app)
iPhone 4S 6.0 Safari: 8 minutes!!! (around the same in iOS Chrome too!!)
iPad 2 6.0 Safari: as above!!!
All of these devices are using the same wifi and internet connection, and my iPhone/iPad are otherwise functioning fine (no native apps exhibiting internet speed issues, and regular websites load just fine). There just seems to be something absolutely decimating AppCache download speed under iOS.
The window.applicationCache.status throughout this time is appCache.DOWNLOADING, and I have a progress event running counting the files as they are downloaded, so I'm certain that it is not stuck elsewhere. This just appears to be the time it takes to download. What gives?
Addendum : The iPhone also runs ridiculously hot, and the battery ticks down very quickly during this operation. It seems that something is causing the CPU to run flat-out during this download.
(Note: I can't publish a link to the web-app here as we're still in private beta, but if you would need to see it before you think you'd be able to help diagnose it, email me at the address in my profile and I'll send a link to the app).
Okay, I figured it out with the help of the iOS Emulator, and Xcode Instruments to profile it. (I'm not sure if I should add my solution into the main question, or as an answer, but I thought I'd do it this way as my question is already a little cluttered).
As it turns out, it was actually some erroneous javascript causing the issue, but apparently only on iOS.
The web-app is intended to only be a single page high (no vertical scrolling, except within specific DIVs), so in addition to the usual standard JS code for hiding the address bar...
window.addEventListener("load",function() {
// Set a timeout...
setTimeout(function(){
// Hide the address bar!
window.scrollTo(0, 1);
}, 0);
});
...I had also added in the following:
$(document).scroll(
function(e){
window.scrollTo(0, 1);
});
From looking at the profile results, I was able to see that a lot of time was being spent in scrollTo, so it immediately pointed to this as the cause. Why the scroll event was being triggered so much, I have no idea (this was occurring with no touching of the screen whatsoever).
My initial fix is to throttle that code, but I am now evaluating whether or not I even need it at all. Here is the code I have that fixes it for now (using jquery-debounce, which I was already using for something else):
$(document).scroll(
$.throttle(function(e){
window.scrollTo(0, 1);
})
, 10);
The download time of the application cache is now in line with the Android times. Phew!
The code is getting itself into an infinite loop, as the initial scrollTo function call triggers the scroll event handler, which then repeatedly re-triggers itself! My best guess is that the iOS JavaScript engine handles this infinite loop differently to the other browsers' JavaScript engines.