How to handle animations on divs with angularjs? - 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

Related

Capture event when md-sidenav is toggled (using md-is-locked-open)

I'm using the Angular Material component framework.
I've defined a page with a md-sidenav called sidebar that is automatically shown (on the left of the screen) if resized to a certain width. This is possible thanks to the directive md-is-locked-open="$mdMedia('gt-sm')".
What I try to achieve seems quite straightforward: I just want to know (have an event triggered) when the sidenav is being shown / hidden (by user, or automatically). I've tried several different solutions, but nothing seem to be working.
I have a plunker that has the same behaviour as what I'm are trying to achieve. In the activate function, I try to capture the events (or what I thought would be events, doesn't seem so because it's not working).
I tried almost all the solutions that were given here and here, but no luck (specially when automatically showing / hiding the sidenav).
Any ideas here?
Thank you very much!
You could use the $mdMedia service in the controller instead of in the view. From the documentation
The media query will be re-evaluated on resize, allowing you to register a watch.
So you can register a watcher for your desired media query size, then call a function when the watcher fires:
$scope.$watch(function(){return $mdMedia('gt-sm');}, function(){
$scope.showSideNav = !$scope.showSideNav;
console.log("SideNav State Change");
});
Then I'd setup the sideNav like this:
md-is-locked-open="showSideNav"
Here is a working example, forked from your Plunker

AngularJS Route-Based Animations

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)

AngularJS animation with increment "left"

I want to implement the following feature: when click a button, another div under the same controller move to right a little bit (left+=50). However, when I searched for ngAnimate and find that it is mostly about "start" and "end" state in CSS, not increment manipulation. (I am new to Angular).
I now have to use jquery animate to move.
I get $($element) from the controller
find the div I want to move, say var toMove = $($element).find(".tomove")
toMove.animate({left:"+=50}, 200);
I want to know if there is an elegant way in Angular to achieve this?
Angular doesn't really provide a lot in the way of DOM manipulation, if you can't achieve the desired effect using CSS3 animations then using jQuery is probably your best bet. Any time your doing DOM manipulation it should be encapsulated in a directive but aside from that there's nothing special in Angular for working with the DOM it's just whatever the browser/jQuery provides.
If you don't need to have access to a 'done' callback, and only need to support supporting browsers, then just CSS3 transitions should work. So
.my-el {transition: left 0.5s ...
And then in the directive set the left value dynamically on click. CSS will animate to the value from the current one.
If you want Angular to calculate when the transition finishes, and give you the ability to use a 'done' callback, then the only way I have found is to add a dynamically generated style sheet to the page, that contains a unique class with the target left value, and use $animate.addClass to add it. It feels like a bit of a long-winded faff though, so I can't quite recommend it, and would love a nicer way!

Angular.js // ng-leave state before url/ng-view change

Getting into ngAnimations; I was wondering how page transition could completely be controlled.
I mean by this : being able to control the same way an ng-leave as it is done for the ng-enter while having a change in the url in the process. New to angular but I'd described it as trying to get some ng-leave control before an ng-view change.
As far as I've searched, the ng-leave state only has a meaning with ng-switch (there is another ng but you got the idea); which for the moment means for me that all the elements have to be already in the page and that no url change are involved in the process.
If any help, highly appreciated. I've found the ng-animations really cool but thinking that this point is quite missing.
Assuming there might be another pattern to follow probably though.
Have you read:
Animation in AngularJS
http://www.yearofmoo.com/2013/04/animation-in-angularjs.html
Enhanced Animation in AngularJS
http://www.yearofmoo.com/2013/05/enhanced-animations-in-angularjs.html
Remastered Animation in AngularJS 1.2
http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html
I have found these useful.

"angular way" for dynamically adding directives

I’m very impressed with Josh's answer about ‘angular way’ and declarative style in client-side.
But can you help me to understand, how to do that:
I have a single-page app with the menubar in the left side, and div container on the right-side.
When user clicking the menu item in the left menubar, on the right side I must to open the new tab with some grid,like this:
In angular I realized the <grid> directive.
When user click menuitem, I must add dynamically this grid directive with params on the right side.
What is the angular way for doing this functionality?
Update:
I found article about dynamic tabs, and this is example how I use it in my case
Since you asked a general question, let me give you a general answer. It should be helpful :)
AngularJS is model/data driven, and if you want to make any change to the UI, the first thing you may think is how to achieve it by changing data. Given this idea, we can implement it like this:
Define a ng-repeater, which should render tabs for a list of Tab objects called MyTabs, for instance.
When you want to add a new tab, then create a tab object and add/push it to MyTabs.
AngularJS will magically render it on the UI, thanks to the 2-way data binding.

Resources