Screen touch not fired in native VR mode - aframe

I have to detect screen touches in VR mode, as that's what the button on a Cardboard produces. (I have other code to detect controller buttons.)
This code:
// mobile and Cardboard controls
AFRAME.scenes[0].addEventListener('touchstart', function(evt) {
// console.log('scene touchstart:', evt);
if (evt.target.classList.contains('a-enter-vr-button')) {
return;
}
if (!state.isFlying) {
AFRAME.scenes[0].emit('launch', evt);
} else {
AFRAME.scenes[0].emit('hover', evt);
}
});
fires when the screen is tapped, in Android Firefox in normal and VR mode (but VR mode is polyfilled). In Android Chrome, it fires in normal mode, but not VR mode (which appears to be native).
The same behavior occurs when I listen for mousedown, or add the listener to window, for either touchstart or mousedown.
So, what event on what element should I listen for, in native VR mode?

Add the event listener to the window or to the canvas (AFRAME.scenes[0].canvas).
window.addEventListener('click', function () { // ... } or
window.addEventListener('touchstart', ...)

VR Mode in Chrome had a virtual controller. My eventual solution was to write a component that detected both screen taps and controller buttons:
https://www.npmjs.com/package/aframe-button-controls

Related

React-VR iFrame Fullscreen

Creating a React-VR app that I need to iFrame into an existing app. My question is regarding the fullscreen button. How can i either hide this button and manage within my other app or send a message to the parent that the button was clicked?
Couldn't find any official documentation for this but if you look at the implementation of VRInstance you'll notice a hideFullscreen option that hides that button.
// vr/client.js
const vr = new VRInstance(bundle, 'VRTEST', parent, {
hideFullscreen: true,
...options,
});
To toggle fullscreen mode for an iframe you can use a library like screenfull.js so you don't have to worry about the various cross-browser implementation details of the Fullscreen API.
Just render a button in your page and make it toggle fullscreen mode for a DOM element on click.
const vrIframe = document.getElementById('vrIframe');
document.getElementById('vrFullscreenButton').addEventListener('click', () => {
if (screenfull.enabled) {
screenfull.request(vrIframe);
}
});

Javascript - How to detect when user enters VR mode?

Is there any JavaScript event triggered when the user enters VR mode while viewing the VR scene on a webpage?
Or is there any function which returns whether the user is viewing the webpage in VR mode or not?
Use the enter-vr and exit-vr events:
https://aframe.io/docs/0.5.0/core/scene.html#events
document.querySelector('a-scene').addEventListener('enter-vr', function () {
console.log("ENTERED VR");
});

display:none hover trick on a touchscreen device

I am using a CSS hover trick to clean up my interface. Controls will only be shown when the cursor is hovering inside the element. I'm running into an issue when using the interface on a touch screen device. If the control button is not shown display:none and I touch where it should be, the event is still triggered for the button.
Try this fiddle both in your browser and on a touchscreen device to see what I mean...
http://jsfiddle.net/6PvCn/2/
On a touchscreen device, touch the red square and the alert should fire, without the button even showing up. I tested this on both the desktop Android Emulator and my real Android 2.3 phone.
The effect I'm going for is for the button to first be shown without firing, even if the user touches where the button "is".
I'd rather use a pure CSS solution before resorting to javascript.
Try pointer-events: none; along with display: none;
I just tested it on my real device, and it indeed executes the button's action.
You could maybe try to make the red box an image and change the image to a button by an onclick with Javascript. I would have provided you with some code if I wasn't short on time.
You can't do it with pure CSS, tapping the button will put the button into hover state and fire the click event. Instead you should fire the button off on active.
Here is the solution I came up with... http://jsfiddle.net/6PvCn/7/
On an Android touchscreen (don't know about IOS), the hover event for the hidden element is not fired if it is not shown. So basically I check to see if the element was hovered before it was clicked.
In a nutshell
$(".hidden").hover(function(e) {
if(e.type == "mouseenter") $(this).addClass("hovering");
else $(this).removeClass("hovering");
}).click(function(e) {
if(!$(this).hasClass("hovering") return false;
});
The fiddle explains the more complicated situation I had with form elements and dynamically added content. It provides a general solution as opposed to this element specific one.
I wrote a JS solution for you:
https://codepen.io/anon/pen/bmYROr
The trick is to prevent the button's click event getting fired for the first time the outer div is getting clicked because on touch devices click event has hover effect.
let isTouchDevice = true;
let isHovered = false;
document.getElementById('outer').addEventListener('click', (e) => {
if (isTouchDevice) {
if (!isHovered) {
e.stopPropagation();
}
isHovered = true;
}
}, true);
document.getElementById('outer').addEventListener('mouseleave', (e) => {
if (isTouchDevice) {
isHovered = false;
}
}, true);
document.getElementById('btn').addEventListener('click', () => {
alert("hi");
});

esc from fullscreen using video in full screen minimizes whole app in flex

I have an application intended to run in full screen mode. In order to prevent it from getting out of full screen I did:
protected function windowedapplication_preinitializeHandler(event:FlexEvent):void
{
nativeWindow.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
nativeWindow.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}
protected function onKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == 27)
{
event.preventDefault();
}
}
That prevents the app getting out of full screen but my app has a video player with an option to go full-screen with the video and at that point when i press esc the whole app and the video come to smaller size.
Thanks in advance!
You couldn't prevent ESC key to exit from full screen mode.
This is security issue.
You can listen for the FullScreenEvent and set the stage.displayState to return back to full screen when FullScreenEvent.FULL_SCREEN is dispatched.
This way, the app will change back to full screen even when the user clicks the full screen button to exit full screen mode in the video player.
private function onApplicationComplete(event:Event):void{
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
stage.addEventListener(FullScreenEvent.FULL_SCREEN, onFullScreenChange);
}
private function onFullScreenChange(event:FullScreenEvent):void{
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}

How to make UIsplitview's popover visible in portrait mode iPad

I would like to make popover view visible whenever user switches from landscape view to portrait view in UIsplitView of iPad. Although user can make it visible by clicking on bar button but I want this to be automated for portrait mode.
Inside " -(BOOL) shouldAutorotateToInterfaceOrientation" method, check for the device orientation.If it is portrait, then Present the popover as you do for making it visible when user clicks bar button.
All the best.
UISplitViewController sends messages to his delegate (UISplitViewControllerDelegate). You can implement this delegate methods to show the popover. You can do something like this in your "detail controller" code:
#pragma mark -
#pragma mark UISplitViewControllerDelegate implementation
- (void)splitViewController:(UISplitViewController*)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc
{
[barButtonItem setTitle:#"Your 'popover button' title"];
self.navigationItem.leftBarButtonItem = barButtonItem;
}
- (void)splitViewController:(UISplitViewController*)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
self.navigationItem.leftBarButtonItem = nil;
}
The accepted answer (using shouldAutorotateToInterfaceOrientation) doesn't work for me. It either has rotation artifacts (in the 4.2 and 5.0 iPad simulators) or only shows at startup and never again in subsequent rotations (the 4.3 simulator). What I did instead was to create a little helper function:
- (void)showPopoverInPortrait {
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait) {
[self.masterPopoverController presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItem
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
}
and call this within - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation and - (void)viewDidLoad to also handle on startup.

Resources