Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Don't ng-show element until ng-hide CSS transition is complete?

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):

Gif

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) {         }     }; }]); 
  • What is className? Is it the class I want to apply while fading in/out? The class I'm expecting?
  • What is doneFn meant to be? I assume it's a function that's run once the animation is complete? What goes in there?
  • What do I do in the addClass and removeClass function then, if I already have a doneFn?

The Goal

I'd like to generate a working animation directly using Angular's ngAnimate module, with either CSS or JS. How can I achieve this?

like image 276
marked-down Avatar asked Oct 25 '15 23:10

marked-down


1 Answers

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 !!!

like image 89
Abhilash Augustine Avatar answered Oct 11 '22 06:10

Abhilash Augustine