Up / down slide with ng-show and ng-animate

I am trying to use ng-animate to get behavior similar to jQuery slideUp() and slideDown() . Only I would prefer to use ng-show

I look here the ng-animate tutorial - http://www.yearofmoo.com/2013/04/animation-in-angularjs.html ,

and I can reproduce the fade in / out effect in the presented example.

How can I change css to get slide up / down? In addition, if possible, it is better that css is not aware of the height of the component in pixels. That way I can reuse CSS for different elements.

+72
angularjs css css3
May 21 '13 at 18:46
source share
8 answers

I wrote an Angular directive that does slideToggle() without jQuery.

https://github.com/EricWVGG/AngularSlideables

+82
Nov 01
source share

This is actually pretty easy to do. All you have to do is change the css.

Here's a script with a very simple fade animation: http://jsfiddle.net/elthrasher/sNpjH/

To turn it into a rolling animation, I first had to put my element in a field (this is a slide container), then I added another element to replace the one that was leaving, just because I thought it would look beautiful. Take it , and the example will work.

I changed the css animation from "fade" to "slide", but note that these are the names I gave them. I could write a css slide animation called "fade" or anything else for that matter.

The important part is what is in css. Here's the original "fade" css:

 .fade-hide, .fade-show { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; } .fade-hide { opacity:1; } .fade-hide.fade-hide-active { opacity:0; } .fade-show { opacity:0; } .fade-show.fade-show-active { opacity:1; } 

This code changes the opacity of an element from 0 (completely transparent) to 1 (completely opaque) and vice versa. The solution is to leave the opacity alone and instead change the top (or left if you want to move left-right).

 .slide-hide, .slide-show { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; } .slide-hide { position: relative; top: 0; } .slide-hide.slide-hide-active { position: absolute; top: -100px; } .slide-show { position: absolute; top: 100px; } .slide-show.slide-show-active { position: relative; top: 0px; } 

I also move from relative to absolute positioning, so only one of the elements takes up space in the container at a time.

Here's the finished product: http://jsfiddle.net/elthrasher/Uz2Dk/ . Hope this helps!

+40
Jun 03 '13 at 12:41
source share

update for Angular 1.2 + (v1.2.6 at the time of publication):

 .stuff-to-show { position: relative; height: 100px; -webkit-transition: top linear 1.5s; transition: top linear 1.5s; top: 0; } .stuff-to-show.ng-hide { top: -100px; } .stuff-to-show.ng-hide-add, .stuff-to-show.ng-hide-remove { display: block!important; } 

( plunker )

+15
Dec 21 '13 at 17:14
source share

This can really be done in CSS and very minimal JS by simply adding a CSS class (don't set styles directly in JS!), For example. a ng-click . The principle is that you cannot envelop height: 0; in height: auto; , but this can be tricked by animating the max-height . The container will expand to the value "auto-height" when .foo-open is installed - no need for a fixed height or positioning.

 .foo { max-height: 0; } .foo--open { max-height: 1000px; /* some arbitrary big value */ transition: ... } 

see this violin superb Lee Vero

In connection with the remark made in the comments, please note that although this animation works fine with linear attenuation, any exponential attenuation will lead to a behavior different from what could be expected - due to the fact that the animated max-height rather than height itself; in particular, only the height fraction of the attenuation curve max-height will be displayed.

+15
Mar 11 '15 at 18:15
source share

In the end, I discarded the code for my other answer to this question and went with this answer.

I believe the best way to do this is to not use ng-show and ng-animate at all.

 /* Executes jQuery slideDown and slideUp based on value of toggle-slidedown attribute. Set duration using slidedown-duration attribute. Add the toggle-required attribute to all contained form controls which are input, select, or textarea. Defaults to hidden (up) if not specified in slidedown-init attribute. */ fboApp.directive('toggleSlidedown', function(){ return { restrict: 'A', link: function (scope, elem, attrs, ctrl) { if ('down' == attrs.slidedownInit){ elem.css('display', ''); } else { elem.css('display', 'none'); } scope.$watch(attrs.toggleSlidedown, function (val) { var duration = _.isUndefined(attrs.slidedownDuration) ? 150 : attrs.slidedownDuration; if (val) { elem.slideDown(duration); } else { elem.slideUp(duration); } }); } } }); 
+7
Aug 20 '15 at 19:05
source share

This class-based javascript animation works in AngularJS 1.2 (and verified 1.4)

Change I ended up abandoning this code and going in a completely different direction. I like my other answer much better . This answer will give you some problems in certain situations.

 myApp.animation('.ng-show-toggle-slidedown', function(){ return { beforeAddClass : function(element, className, done){ if (className == 'ng-hide'){ $(element).slideUp({duration: 400}, done); } else {done();} }, beforeRemoveClass : function(element, className, done){ if (className == 'ng-hide'){ $(element).css({display:'none'}); $(element).slideDown({duration: 400}, done); } else {done();} } } 

});

Just add the .ng-hide-toggle-slidedown to the container element, and the jQuery slide behavior will be implemented based on the ng-hide class.

You must specify the line $(element).css({display:'none'}) in the beforeRemoveClass method because jQuery will not execute slownDown if the element is not in display: none state before the jQuery animation starts. AngularJS uses CSS

 .ng-hide:not(.ng-hide-animate) { display: none !important; } 

to hide the item. jQuery does not know about this state, and jQuery will need display:none until the first animation down.

Animation AngularJS will add the .ng-hide-animate and .ng-animate during the animation.

+5
Jul 20 '15 at 18:52
source share

You must use Javascript animation to do this - this is not possible in pure CSS because you cannot know the height of any element. Follow the instructions that you have about implementing javascript animation and copy slideUp and slideDown from jQuery source.

+4
May 21 '13 at 19:28
source share

What happened with using ng-animate for ng-show , as you mentioned?

 <script src="lib/angulr.js"></script> <script src="lib/angulr_animate.js"></script> <script> var app=angular.module('ang_app', ['ngAnimate']); app.controller('ang_control01_main', function($scope) { }); </script> <style> #myDiv { transition: .5s; background-color: lightblue; height: 100px; } #myDiv.ng-hide { height: 0; } </style> <body ng-app="ang_app" ng-controller="ang_control01_main"> <input type="checkbox" ng-model="myCheck"> <div id="myDiv" ng-show="myCheck"></div> </body> 
0
Apr 01 '16 at 15:38
source share



All Articles