Click event not recognized on mobile browser Aframe-AR.js - mobile

I am working on an Augmented reality scene using Aframe and AR.js. I am currently rendering obj models when the marker is detected. My requirement is to be able to click on individual models upon rendering and also static objects (buttons) . For some reason click event is not triggered properly on aframe entities when I test it on mobile devices , very rarely it detects the touch but it works fine when I test it on a desktop using a webcam. This is my approach -
AFRAME.registerComponent('cursor-listener', {
init: function () {
this.el.addEventListener('click', function (evt) {
console.log('I was clicked at: ', evt.detail.intersection.point);
});
}
});
</script>
</head>
<body>
<a-scene embedded arjs='trackingMethod: best; debugUIEnabled: false;'>
<a-marker id="marker" preset='hiro' cursor="rayOrigin: mouse">
<a-entity material=" src: url(box.png) " class="collidable" cursor-listener position="0 -1 0"></a-entity>
</a-marker>
<a-camera-static>
//button a child of the camera.
<a-entity id="red" material="color: red" class="collidable" geometry="primitive: box" cursor-listener position="0 0 -4" scale="0.3 0.3 0.3"></a-entity>
</a-camera-static>
</a-scene>
</body>
</html>
I have tried this https://github.com/jeromeetienne/AR.js/issues/416#issuecomment-425078800
solution, it make it better, just not accurate enough, the click is detected when clicked outside the object.
Is there anything any way to fix this?
Thanks.

What you might be looking for is dropping the idea of handling the click with a gaze-like cursor and go for a plain mouse/touch click like explained here.

Related

Clicking twice material-ui icon does not change its color to default during tests with react-testing-library

I have a material-ui navbar with a couple of material-ui icons on it. One of them is a Bookmarks icon. When clicking the icon it becomes blue (rgb(25, 118, 210)) and when it is clicked again or somewhere in the page it should become white. This is achieved using a local variable.
<Popover
...
trigger={
<IconButton classes={{ root: classes.topBarIconButton }}>
<BookmarksIcon aria-label="bookmarks icon" className={classes.favoriteIcon} />
</IconButton>
}
onEnter={() => setBookmarksOpen(true)}
onClose={() => setBookmarksOpen(false)}
>
<BookmarksList pageTitle={pageTitle} />
</Popover>
I would like to test the behavior (clicking the button twice) now using react-testing-library.
I am able to test successfully that the icon becomes blue once clicked. But once clicked again I keep receiving the blue color and not the expected white or #fff or a color in rgb format.
test('clicking bookmarks icon once becomes blue, clicking twice becomes white', () => {
renderWithAllProviders(<Topbar {...props} />, reduxState);
const bookmarksIcon = screen.getByLabelText('bookmarks icon');
userEvent.click(bookmarksIcon);
// bookmarks icon color becomes blue on click
expect(bookmarksIcon).toHaveStyle({ color: 'rgb(25, 118, 210)' }); // this works as expected
userEvent.click(bookmarksIcon);
// bookmarks icon color becomes white on second click
expect(bookmarksIcon).toHaveStyle({ color: 'white' }); // this does not work as expected
// 2nd attempt
// await waitFor(async () => {
// // const asyncBookmarksIcon = await screen.findByLabelText('bookmarks icon');
// expect(asyncBookmarksIcon).toHaveStyle({ color: 'white' });
// });
});
I get the following error:
● clicking bookmarks icon once becomes blue, clicking twice becomes
white
expect(element).toHaveStyle()
- Expected
- color: white;
+ color: rgb(25, 118, 210);
I tried also using the waitFor method but the error becomes even larger in terms of the its output:
Can't perform a React state update on an unmounted component. This is
a no-op, but it indicates a memory leak in your application. To fix,
cancel all subscriptions and asynchronous tasks in a useEffect cleanup
function.
included the first error and a big output with printed material ui (probably) native css declarations.
Here is demo of the issue. (better download and run it locally cause it freezes for some reason although when run locally works fine).
Any thoughts or recommendations are welcome.
I ended up asking this question in the official react-testing-library git hub repository.
and I got the following answer from one of the contributors.
You run your tests in JSDOM which has not full CSS support
That means that only partial css behavior can be tested.
He mentioned that:
Anything .toHaveStyle has a low confidence depending on how these styles are applied. You should use visual regression tests for these types of assertions.
You can find the issue in this link for more information.

Facebook Video Embed API allowfullscreen=false doesn't work which makes .play() function throw error

I am trying to embed facebook video on my mobile site and used their Video API documented here to do it.
I have initialised the video player as described and created Play & Pause buttons to control the video but when I use the Play button I get the error Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.
I have tried making data-allowfullscreen="false"
but that doesn't seem to work as the iframe that is loaded contains allowfullscreen="true"
Look at the image below, my has it false but the loaded iframe has it as true
Loaded iframe has allowfullscree=true even though I gave false in
I am using React and made a simple component for this
import React, { Component } from 'react';
import { Container, Button } from 'react-bootstrap';
class Vidtest extends Component {
handlePlayVideo = () => {
window.my_video_player.play();
}
handlePauseVideo = () => {
window.my_video_player.pause();
}
render() {
return(
<React.Fragment>
<div style={{position:"relative", width:"100%"}}>
<div id="video_div"
className="fb-video"
data-href="https://www.facebook.com/facebook/videos/10153231379946729/"
data-width="500"
data-allowFullScreen="false"
>
</div>
<Button className="btn btn-primary" onClick={this.handlePlayVideo}>Play Video</Button>
<Button className="btn btn-primary" onClick={this.handlePauseVideo}>Pause Video</Button>
</div>
</React.Fragment>
);
}
}
export default Vidtest
and have initialized FB video player in my index.html
<div id="root"></div>
let my_video_player
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '{my-app-id}',
xfbml : false,
version : 'v7.0'
});
// Get Embedded Video Player API Instance
FB.Event.subscribe('xfbml.ready', function(msg) {
if (msg.type === 'video') {
my_video_player = msg.instance;
console.log(msg.id);
console.log('my_video_player created lfakjd');
}
});
};
</script>
<script
async
defer
crossorigin="anonymous"
src="https://connect.facebook.net/en_GB/sdk/debug.js#xfbml=1&version=v7.0&appId={my-app-id}&autoLogAppEvents=1">
</script>
Can someone please help me resolve the issue here.?
I want to play the video using my_video_player.play() and not allow it to play in fullscreen.
Facebook definitely seems to be doing something different based on the device type (you can test this by using chrome dev tools - device toolbar - and switching between Mobile (no touch) and Desktop device types. The embedded player looks different between the two versions, and the mobile one seems to call requestfullscreen no matter whether the data-allowfullscreen was on or off. As near as I can tell, the only thing that that data-allowfullscreen seems to influence is on desktop, where there is a fullscreen button on the bottom of the video that shows or hides based on that flag.
Facebook embedded videos has a very frustrating and buggy api. They need to catch up with Youtube and Vimeo players.

Animate Angular-flash Alerts

Using the package, Angular-flash and having issues adding custom animations to the showing and hiding of an alert.
From the docs
If you want to use animations, include ngAnimate module. You can then
use regular Angular animation technique for applying your own
transitions.
.alert {...}
.alert.ng-enter, .alert.ng-enter.ng-enter-active {...}
.alert.ng-leave, .alert.ng-leave.ng-leave-active {...}
I feel like I've tried all possible combinations but struggle to get the in . out effects.
My HTML
<flash-message>
<div>{{ flash.text }}</div>
</flash-message>
<button ng-click="showFlash()">PRESS ME</button>
Controller
$scope.showFlash = function() {
var message = '<strong>Hello!</strong> ';
var id = Flash.create('info', message, 4000, false);
};
Just to test my CSS animation is working I just added an animation to the alert class. This provides the show animation only.
.alert {
animation: 1.5s zoomIn ease;
}
I need to be able to attach it to the "Alert Show Event" and then attach a zoom out to the "Alert Hide Event", allowing a specific show and hide effect.
I've tried these in multiple combinations but struggle to find what class to associate with the show / hide animations.
.alertIn,
.alertOut
.alert.ng-hide-add-active
.alert.ng-hide-remove-active
Thanks
I developed a flash message package and uploaded it in npmjs.com, i think the package will help you,
Package Name: Flash-Text
author: VamshiDureddy

Angularjs/Bootstrap - how to create a stateless button

Using Bootstrap and Angularjs I'd like to create a button that doesn't ever appear to be "active". I'd like the button to darken slightly when the mouse is over it, and I'd like it to darken further when it's clicked. When the mouse leaves the button, however, I'd like it to return to its original appearance.
Semantically, I'm using the button to "reset" part of my app. I want to execute some code when it's clicked. After it's been pressed, though, it doesn't make sense for the button to remain in a "depressed" state.
Here's a live example.
Any ideas?
Alternatively you could use the ng-mouseenter and ng-mosueleave directives.
For example:
<div ng-app="ButtonApp">
<div ng-controller="MainCtrl">
<button ng-class="buttonClass"
ng-mouseenter="onMouseEnter()"
ng-mouseleave="onMouseLeave()"> Click Me!
</div>
</div>
And in your controller:
var app = angular.module('ButtonApp',[]);
app.controller('MainCtrl', ['$scope',function($scope){
var defaultButtonClass = ['btn','btn-foxtrot'];
$scope.buttonClass = defaultButtonClass;
$scope.onMouseEnter = function(){
$scope.buttonClass = ['btn','btn-bravo'];
};
$scope.onMouseLeave = function() {
$scope.buttonClass = defaultButtonClass;
}
}]);
You can see my JSFiddle.
To generate the button colors you could use something like Beautiful Buttons for
Twitter Bootstrappers.
I'd give it another class, say btn-reset and add the following CSS.
// the order of these two is also important
.btn-reset:hover{
background-color: Dark !important;
}
.btn-reset:active{
background-color: Darkest !important;
}
// you need this to reset it after it's been clicked and released
.btn-reset:focus{
background-color: Normal !important;
}
It's working here http://plnkr.co/edit/QVChtJ8w70HXmyAaVY4A?p=preview
The issue is that the :focus pseudo class has a darker colour than the standard button so after it's been clicked it still has focus so still has the darker colour, if you want to stick with the standard colours you can just add a new selector for the :focus pseudo class.

Cakephp add form inside modal window while in index view

New to cakephp here.. wondering how i could have a button whilst in my index view to open an add form ( for the same model ). once i submit this form i'd like the modal to disappear and the new record to be show in the index view. I was thinking of putting the add form in a cake element? but not sure how to put this in a modal window. any advice would be great thanks.
What #savedario says makes perfect sense. I blogged about this just before Christmas and have copied the relevant bits below:
View/Users/index.php:
<!-- overlayed element -->
<div id="dialogModal">
<!-- the external content is loaded inside this tag -->
<div class="contentWrap"></div>
</div>
...
<div class="actions">
<ul>
<li>
<?php echo $this->Html->link(__('Add user', true), array("controller"=>"users", "action"=>"add"), array("class"=>"overlay", "title"=>"Add User"));
</li>
</ul>
</div>
...
<script>
$(document).ready(function() {
//prepare the dialog
$( "#dialogModal" ).dialog({
autoOpen: false,
show: {
effect: "blind",
duration: 500
},
hide: {
effect: "blind",
duration: 500
},
modal: true
});
//respond to click event on anything with 'overlay' class
$(".overlay").click(function(event){
event.preventDefault();
$('#contentWrap').load($(this).attr("href")); //load content from href of link
$('#dialogModal').dialog('option', 'title', $(this).attr("title")); //make dialog title that of link
$('#dialogModal').dialog('open'); //open the dialog
});
});
</script>
Views/Users/add.ctp:
echo $this->Form->create('User');
echo $this->Form->input('name');
echo $this->Js->submit('Save', array( //create 'ajax' save button
'update' => '#contentWrap' //id of DOM element to update with selector
));
if (false != $saved){ //will only be true if saved OK in controller from ajax save above
echo "<script>
$('#dialogModal').dialog('close'); //close containing dialog
location.reload(); //if you want to reload parent page to show updated user
</script>";
}
echo $this->Form->end();
echo $this->Js->writeBuffer(); //assuming this view is rendered without the default layout, make sure you write out the JS buffer at the bottom of the page
Controllers/UsersController.php:
function add() {
...
$this->set('saved', false); //false by default - controls closure of overlay in which this is opened
if (!empty($this->request->data)) {
$this->User->create();
if ($this->User->save($this->request->data)){
$this->set('saved', true); //only set true if data saves OK
}
}
...
}
You'll need to have included JQuery 1.9+ and JQuery UI js files in the layout used by your index.ctp and add.ctp.
Actually I have now switched to Bootstrap modals in my own code because I think they look nicer but the approach is very similar.
CakePHP does not have a built-in functionality to do what you want.
Using Elements here does not necessarily help, unless you find yourself writing the same code in different places...
I could not find anything already written to handle this, so I wrote my own javascript functions that work but I doubt could be used as a plugin.
To explain the whole thing would be a bit too long here.
I suggest you start looking at Jquery UI Dialog.
Your index view will need an 'onclick' on the 'add' action button to open the dialog.
The content of the dialog itself could come from the same add() action you would normally use, loaded via an ajax call.
I used bootstrap 3 for my cakephp project which included modals, but that may be overkill for your project.
You have to use bootstrap or jquery to do this. CakePHP does not have a built-in functionality to do what you want.
Typo
<div class="contentWrap"></div>
must be
<div id="contentWrap"></div>
or
$('#contentWrap').load($(this).attr("href"));
must be
$('.contentWrap').load($(this).attr("href"));

Resources