Animate removal of list items with css - angularjs

I have made the animation of a showing/hiding a list of messages. See this plunk. But how can I adapt it to also make an animation when a message is removed from the list?
My css:
.messages-active.messages {
max-height: 50px;
}
.messages {
-webkit-transition: max-height 1s;
-moz-transition: max-height 1s;
-ms-transition: max-height 1s;
-o-transition: max-height 1s;
transition: max-height 1s;
background-color: AntiqueWhite;
overflow: hidden;
max-height: 0;
}
My index file (using Angular):
<body ng-app="app" ng-controller="TestCtrl as test">
<button ng-click="test.toggle = !test.toggle">Show messages</button>
(current: {{test.toggle}})
<div class="messages" ng-class="{ 'messages-active': test.toggle }" ng-repeat="message in test.messages">
{{message}} <a href ng-click="test.remove($index)">remove</a>
</div>
</body>

The idea is to set the height of container and add transition to the height.
$scope.styles.height = $scope.messages.length * 20 + 'px';
http://plnkr.co/edit/3dnGeVoQ1DbX55WQtJjk?p=preview

You can try following if it may help you.
On clicking remove instead removing element just add class messages-remove on it's parent div messages.
For e.g: It should become <div class="messages" to <div class="messages messages-remove".
Also add the following CSS in your style sheet.
.messages-active.messages-remove.messages,
.messages-remove.messages { max-height: 0px; }
Let me know if you have any question.

Related

When moving a div with ngAnimate, how can I move adjacent divs smoothly?

I have two divs side-by-side (inline block). Using Angular's ngAnimate, I want the left div to slide off the screen and the right div to slide over and take it's place.
Right now what happens is the left div slides away, and once that animation completes, the right div jumps over to take it's spot. How do I make it slide over smoothly at the same time?
Here's a Plunker which demonstrates it a lot better than I can explain it:
https://plnkr.co/edit/ZrtPPkXlttih15ISgEhk
Here's the css/html:
Css:
.well{
overflow-x: hidden;
overflow-y: hidden;
}
.column{
display: inline-block;
width: 100px;
vertical-align: top;
transition: all linear 1.0s;
left: 0px;
position: relative;
opacity: 1;
}
.column.ng-hide{
left: -200px;
opacity: 0;
}
Html:
<div>
<button ng-click="hide = !hide">Toggle</button>
</div>
<div class="well">
<div ng-hide="hide" class="column" style="background-color: lightblue; height: 150px;">
</div>
<div class="column">
This column does not move smothly as the column to the left slides offscreen.
</div>
</div>
Here's that Plunker again, in case you scrolled to the bottom looking for the Plunker link :)
https://plnkr.co/edit/ZrtPPkXlttih15ISgEhk
You simply need to change the width of the column in your transition:
PLUNKR
.well{
overflow-x: hidden;
overflow-y: hidden;
}
.column{
display: inline-block;
width: 100px;
vertical-align: top;
transition: all ease-in-out 1.0s;
left: 0px;
position: relative;
opacity: 1;
}
.column.ng-hide{
width: 0;
left: -200px;
opacity: 0;
}
The reason it wasn't working for you, is due to the fact that the width is remaining the same until the div becomes hidden. This prevents the right column from sliding over as the left column slides out of view. By setting the transition to adjust the width, you can give it that "sliding" effect along the right-edge.
I also changed the animation from linear to ease-in-out to give it a nicer transition

Delete item from ng-repeat which has a transition animation

I have an array of items in ng-repeat.
This parent element also has a background-transition animation with 1 second duration.
When ever I delete the element using splice, it takes 1 second to remove from the UI. (Based on what time I give for Transition duration)
I don't want to add another class to remove the transition first, and then delete. Or is that the only way?
<div class="MyTransitionClass" ng-repeat="d in myArray">
{{d.Value}}
<button type="button" class="CloseIcon" ng-click="DeleteItem($index)">DELETE</button>
</div>
.MyTransitionClass {
transition: background-color ease-in 1s;
-webkit-transition: background-color ease-in 1s;
}
Try it like this https://docs.angularjs.org/api/ngAnimate
.MyTransitionClass.ng-enter {
transition: background-color ease-in 1s;
-webkit-transition: background-color ease-in 1s;
}
Working jsfiddle http://jsfiddle.net/irhabi/3fgtqwgq/

AngularJS route change happens before ng-leave animation is finished

I am using the following css code, to animate my ui-view changes.
.fadein.ng-enter,
.fadeout.ng-leave {
-webkit-transition: all linear 1s;
-moz-transition: all linear 1s;
-o-transition: all linear 1s;
transition: all linear 1s;
display: block !important;
}
.fadein.ng-enter {
opacity: 0;
}
.fadeout.ng-leave {
opacity: 1;
}
.fadein.ng-enter.ng-enter-active {
transition-delay: 1s;
opacity: 1;
}
.fadeout.ng-leave-active {
opacity: 0;
}
and here it gets applied to the ngview:
<div ui-view class="fadein fadeout"></div>
However, the route change (initiated by $state.go("home.dashboard") for example) always happens, before my ng-leave animation even started (the fadeout animation).
I tried adding the
transition-delay: 1s;
attribute, but the animation still is not executed.
I have no idea why, but adding
position: absolute;
to my ui-view div solved the issue.

angularjs chained fade-in / fade-out transition

I have looked at the official show/hide transition example at the bottom of this page... http://docs.angularjs.org/api/ng.directive:ngShow
I have tried to modify it to get a seemless fade transition (transition: opacity 0.5s ease-in-out) from one div to the other, where both divs occupy the exact same position on the page, so that one div completely fades out before the other div begins to fade in.
In jquery, it would be as simple as:
$("#divA").fadeOut(function() { $("divB").fadeIn(); });
Does anyone have any advice on the best way to achieve this with angular, with respect to the linked example, which uses a single model "checked" to trigger the transition?
I used the example in ngShow to make the following jsfiddle based on angular1.2.0-rc.3.
The html code:
<div ng-app="App">
Click me: <input type="checkbox" ng-model="checked"><br/>
<div class="check-element animate-show" ng-show="checked">
<span class="icon-thumbs-up"></span> I show up when your checkbox is checked.
</div>
<div class="check-element animate-show" ng-hide="checked">
<span class="icon-thumbs-down"></span> I hide when your checkbox is checked.
</div>
</div>
The CSS styles
.animate-show.ng-hide-add,
.animate-show.ng-hide-remove {
-webkit-transition:all linear 0.5s;
-moz-transition:all linear 0.5s;
-o-transition:all linear 0.5s;
transition:all linear 0.5s;
display:block!important;
}
.animate-show.ng-hide-add.ng-hide-add-active,
.animate-show.ng-hide-remove {
line-height:0;
opacity:0;
padding:0 10px;
}
.animate-show.ng-hide-add,
.animate-show.ng-hide-remove.ng-hide-remove-active {
line-height:20px;
opacity:1;
padding:10px;
border:1px solid black;
background:white;
}
.check-element {
padding:10px;
border:1px solid black;
background:white;
}
And finally the JavaScript code, don't forget to include the libraries angular.js and angular-animate.js
angular.module('App', ['ngAnimate']);
I hope it helps you ;)
Using the ngAnimate module, you can do this in pure CSS with the -transition-delay directive:
Plunker
HTML
<body ng-app="ngAnimate">
Click me: <input type="checkbox" ng-model="checked">
<br/>
<img ng-show="checked" src="img1.jpg">
<img ng-hide="checked" src="img2.jpg">
</body>
CSS
img {
position: absolute;
}
.ng-hide-add-active {
display: block!important;
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
}
.ng-hide-remove-active {
display: block!important;
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
-webkit-transition-delay: 0.5s;
transition-delay: 0.5s;
}
.ng-hide {
opacity: 0;
}
You can use ng-animate in conjuction with ng-show (http://docs.angularjs.org/api/ngAnimate), available from Angular 1.1.4. Or alternatively simply apply a show class when the model is ticked and apply your show and animation to the class.
<label><input type="checkbox" ng-model="showElement" />Show div</label>
<div ng-class="{show: showElement}"></div>

Different transitions with AngularJS

How can I enable different transitions with AngularJS. Lets Say, I have a sidebar in my web application. I the user clicks a button X, the sidebar should disappear very fast, if the user clicks another button, the sidebar should disappear slow.
I think, this would work by setting a transition option value after one of that clicks and then changing the visibility state of the sidebar (watched by the transition directive).
But that seems a bit like bad style for me. Is there a common way to do this?
I would do something like this. Set a default transition for the sidebar, and then apply a class with a different transition speed.
Here is a jsFiddle of what I mean:
http://jsfiddle.net/rd13/eTTZj/149/
HTML:
<div ng-controller="myCtrl">
<div class="sidebar" ng-class="{'slide-out':boolChangeClass}">
Sidebar
</div>
<button ng-click="click()">Toggle Sidebar</button>
</div>
Angular:
function myCtrl($scope) {
$scope.click = function() {
$scope.boolChangeClass = !$scope.boolChangeClass;
$scope.$apply();
}
}
CSS:
.sidebar {
-moz-transition: left .1s;
-webkit-transition: left .1s;
-o-transition: left .1s;
transition: left .1s;
width: 100px;
background-color: blue;
position: absolute;
top: 0px;
bottom: 0px;
left: -100px;
}
.slide-out {
-moz-transition: left 1s;
-webkit-transition: left 1s;
-o-transition: left 1s;
transition: left 1s;
left: 0px;
}

Resources