AngularJS Route-Based Animations - angularjs

I am using AngularJS for a mobile web application and would like to get some "mobile-like" animations to make it look really sharp. My ideal goal would be animations similar to the iPhone's Gmail application, which incorporates lots of animations, like pages sliding from left/right/bottom. And the menu bar fades in/out simultaneously.
I think applying multiple animations at once would require more than one ng-view, which isn't supported at the moment, so I'll hold off on that.
Right now, I just want to be able to make a simple slide-left and slide-right animation similar to how many mobile apps work when you go back and forth between pages. I'd want to have a Back button in my application and somehow be able to specify that this animation should be right-to-left. And a Forward button that I can say has an animation of left-to-right, etc.
This page has exactly what I want (the second demo where the pages slide both left AND right):
http://blog.revolunet.com/blog/2013/04/30/angularjs-animations-mobile-applications/
However, this demo is using the deprecated ng-animate command. I haven't been able to convert it.
I attempted to make this using the new AngularJS way of animating. I THINK the issue I'm running into is that when I change routes, I have two ng-view's at the same time and the "old" one still has the animation applied to it, so it looks weird.
Here is my attempt: http://plnkr.co/edit/Xa6Mvbfmux4BAISj9tJb?p=preview
Try pressing Run/Stop each time. I like how when you first run it and press B, both pages slide out together. But then the 2nd time when you press A, one page maintains the slide-right animation while the other does the slide-left, which I don't like. I also tried just removing the ng-leave CSS classes, but that adds some weird issues as well.
How can I update this code to make standard left-to-right and right-to-left sliding animations work?
Bonus: How can I structure the code to easily specify how I want each route/view change to animate? (Example: A-to-B = Left/Right, B-to-A = Right/Left)

Related

Don't show the Next or Done buttons in the Android VKB

How can I prevent the showing of the Next or Done buttons of the Android VKB in a Codename One app?
Currently, for my app, they are a mess: the next button of the VKB doesn't focus the next field, but the previous. After tons of trials, I didn't find a way to make them working correctly (but there are fine on iOS and on the Simulator). I also tried to override the Layout.overridesTabIndices(com.codename1.ui.Container) and Layout.getChildrenInTraversalOrder(com.codename1.ui.Container) methods in the Form, but nothing changed on Android.
I supposed two possible causes: the use of a Form inside a Form or, more probably, the fact that I replace all the TextFields and Pickers in the same Form (and other components). Maybe the fact that the inner Form is deeply changed results in a confusion for the Android mapping of the "next" button.
That's why my request: because I didn't find a way to make the "next" button useful, I'm asking how I can avoid that it's been shown.
Thank you
Nesting forms would probably mess with the focus traversal/tab order.
Normally you should be able to override public TabIterator getTabIterator(Component start) to return a blank iterator. I'd suggest doing the same for both the parent and child form to disable the "next" feature.

Can't properly force a component on-screen with scrollComponentToVisible

On a given form, we replace one component with another.
The original component is a series of TextFields, and the new form is some informational text and a button. We hide the first one, and show the second one (the UI designer has both Containers within the form).
I tried using scrollRectToVisible with various values but it didn't seem to make any difference with the scrolling.
continueButtonContainer.setHidden(false);
f.forceRevalidate();
Button continueButton =
(Button)StateMachine.GetInstance().findByName("ButtonContinue", f);
f.scrollComponentToVisible(continueButtonContainer);
f.scrollComponentToVisible(continueButton);
I'm expecting the continue button to be near the top of the screen.
If the screen was scrolled before displaying the continue button, the button ends up right at the bottom of the screen (it was below the bottom of the screen before I put in the scrollComponentToVisible line(s).
After the user scrolls the screen, the button goes up to where it needs to be, and stays there.
If the screen is not scrolled, the button appears where it should be.
I know I can probably add some invisible containers underneath the button and force them onto the screen, but I would rather have a slightly more robust solution.
There are a few issues with this. First you are using forceRevalidate which should be used in very rare cases.
Second it seems that you are invoking this on a Form, this is a bit misleading. While it seems that:
f.add(myCmp);
Adds a component to the form it is really a synonym to:
f.getContentPane().add(myCmp);
That's important because you need to invoke the scrollComponentToVisible on the scrollable container which will actually do the work and ideally be the direct parent of said component. I'm assuming it's the content pane in your case but it depends on layout etc.
The last part is letting the layout do its job. If you are invoking this before the form is showing this might not work. Notice that doing it after a call to show is meaningless as the form might take time with transitions. You can use a show listener or override the laidOut callback method to perform things like this.

Is there an event that is sure to fire when google maps is loaded, when using angular js?

I am using angularjs and ngmap (https://ngmap.github.io).
The map is initially hidden from view (using ng-show), and i want to be able to toggle between views without having to reload the whole map.
I also want to display a kml on the map.
The map is only initialized (using lazy initialization) when that part of the page is shown.
It seems to work fine, except that sometimes the map can't zoom into the kml (using fitBounds). I think I have established that this is because the height of the containing div is zero (due to the controller code firing before the view is actually rendered), and fitBounds needs that.
I am trying to wait until I am sure the map is good and ready. I have tried the following events:
bounds_changed
tilesloaded
but neither do what I want.
Currently I am using a $timeout, but I don't like it, as I don't know how long it takes to initialize the map, and whether or not my code will fire between that time.
My next idea is to repeatedly check for the height of the map, but I would prefer something more explicit.
Another idea is to always have the map in the background, and use absolute positioning to cover it with the other information when that part is visible, but that breaks my current design.
I've decided to avoid the issue.
The map is always going to be there, but I use some ng-class s to make it "visibility: hidden" and hide an unneeded scroll bar when the map tab is unselected.
As long as the visibility is hidden (instead of display: none) the initialization and positioning of the map goes okay.
It isn't perfect (I might need to scroll the other tabs one day), but it works for me for now.

Angular JS, how to have two seperate "main" displays that can both change frequently

I am using Angular with Node to create a Web-APP. The back-end will be building a standard JSON RESTful API, and that is going normally. As for the front end, I am running into a little bit of problems. So my website is designed in a way where there are essentially TWO main displays. Eg. Two windows inside the website that can change frequently. I have NO IDEA how I should implement this! So far I have split my website into directives, eg each "display window" is its own directive, and I was thinking maybe use $localStorage and just have a bunch of ng-ifs inside each HTML file for each directive, switching the view depending on some value in $localStorage. Eg. Person clicks a button, some value in local storage changes to 10, an ng-if inside the directive displays the correct "view" inside the display because the value 10 represents some view. The problem is that I will have to put ALL my HTML in one file, and Im not even sure if this will work! Any suggestions? Any help appreciated!
PS. The two "main displays" can change without the other one changing, hence why I didnt want to group them into 1 view. They are separate entities, and programatically it makes more sense to split them up! They are also physically seperated on the screen (bottom right and top right, seperated by a bar)
For displaying two separates views in the same page, you have to use AngularUI Router because the native ngView directive only supports one.

How to handle animations on divs with angularjs?

I've been reading up on animation with AngularJS and from my understanding, the ngAnimate module can be used out of the box with standard Angular directives. I also understand that css animation is encouraged as the first port of call.
In order to learn Angular, I created a dummy project and I wanted to have a panel fade in when a button is clicked and then have it fade out when clicked again. Since I come from a jquery background, my typical approach would be to use something along the lines of:
$('button').on('click', function() {
// If box is visible
$('.box').stop().fadeOut();
// If box is hidden
$('.box').stop().fadeIn();
});
However with Angular I'm not quite sure what the best way of accomplishing the same thing is. I've had a look at some tutorial vids and this demo is the approach I've come up with. The problem I'm having however is that if I rapidly click on the button it seems to glitch and the animations get screwed up. I suppose the questions I'm asking are a) Is my approach to fading in/out an element a wise one (since I really want to adopt an Angular mindset) and b) How do I replicate jquery's .stop() ie. how do I stop an animation to start another one instead?
I'm struggling a little in understanding how to do animations with Angular since it was so simple with jquery :-)
Thanks

Resources