Simple question, but I'm having implementation troubles. If I have the following DOM setup:
<h1 class="fade" ng-repeat="child in parent.children" ng-show="parent.activeChild== child ">@{{ child.title }}</h1>
When the activeChild
property of the parent
model changes, how can I fade out the currently active child, before the model changes, and then fade in the newly active child post-change.
I have it working roughly, with just CSS transitions using this:
.fade.ng-hide-add { transition:opacity 1s ease; } .fade.ng-hide-remove { transition:opacity 1s ease 1s; } .fade.ng-hide-add { opacity:1; &.ng-hide-add-active { opacity:0; } } .fade.ng-hide-remove { opacity:0; &.ng-hide-remove-active { opacity:1; } }
But, this ends up producing this problem (Plunkr):
Essentially, I want to chain my animation. I've tried reading the ng-animate docs, but I'm having trouble the syntax necessary to deliver the effect I want.
I've seen the Angular docs have something like this:
app.animation('.fade', [function() { return { addClass: function(element, className, doneFn) { }, removeClass: function(element, className, doneFn) { } }; }]);
className
? Is it the class I want to apply while fading in/out? The class I'm expecting? doneFn
meant to be? I assume it's a function that's run once the animation is complete? What goes in there?addClass
and removeClass
function then, if I already have a doneFn
?I'd like to generate a working animation directly using Angular's ngAnimate module, with either CSS or JS. How can I achieve this?
Why do you use a separate <h1>
for each heading. You can use a single <h1>
tag to show your heading.
I have created a demo for your problem and I have successfully done your requirement.
Updated
Note, codes are edited to use ngAnimate
module. When you use ngAnimate
module, it will create a class .ng-hide
when you hide an element,
Here is the controller for your app,
app2.controller("testController", ["$scope", "$timeout", function ($scope, $timeout) { $scope.heading = {}; $scope.heading.show = true; $scope.parent = {}; $scope.parent.children = ["A", "B", "C", "D"]; $scope.parent.activeChild = "A"; $scope.changeHeading = function (child) { $timeout(function () { $scope.parent.activeChild = child; $scope.heading.show = true; }, 1000); } }]);
And your html page should be look like this,
<div ng-controller="testController"> <h1 class="myAnimateClass" ng-show="heading.show" ng-class="{fadeIn : heading.fadeInModel==true, fadeOut : heading.fadeOutModel}"> {{parent.activeChild}} </h1> <p ng-repeat="child in parent.children" ng-click="heading.show = false;changeHeading(child)">{{child}}</p> </div>
And I have used CSS3 to implement the fade in and fade out animation,
.myAnimateClass { -webkit-transition: opacity 1s ease-in-out; -moz-transition: opacity 1s ease-in-out; -o-transition: opacity 1s ease-in-out; -ms-transition: opacity 1s ease-in-out; transition: opacity 1s ease-in-out; opacity:1; } .myAnimateClass.ng-hide { opacity: 0; }
Explanation
To achieve your requirement, I have used ng-class
and $timeout
in angularJS.
You can see that, I have only one <h1>
tag to display your heading. When I change the heading I just change it's binding property $scope.parent.activeChild
.
And I have used two scope variables $scope.heading.fadeOutModel
and $scope.heading.fadeInModel
to add and remove classes fadeIn
and fadeOut
dynamically.
When user clicks to change the heading, I have added the class fadeOut
to your heading. So, this will show an animation of fade out. And also I have fired a function in app.js, changeHeading()
.
You can see that, I forced the angular to wait for 1000
milliseconds to finish fade out animation. After this time, it will replace the selected heading to new one and add a class fadeIn
. So, it will start animation for fade in.
Hope this will help you !!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With