I want to add animations to the opening and closing of a dropdown in my angular app. So far I can get open animations working on the dropdown, but nothing for close animations.
I took the navbar code straight from the bootstrap example and added it to my page with some minor modifications. The relevant part of the navbar is this:
<ul class="nav navbar-nav navbar-right">
<li ng-if="isAuthenticated()" class="dropdown">
{{ authenticatedUser.displayName }} <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li ng-if="menuItem.show()" ng-repeat="menuItem in menuItems" ng-class="{active: menuItem.active, disabled: menuItem.disabled}">
<a ui-sref="{{ menuItem.state }}({{ menuItem.stateParams }})">{{ menuItem.heading }}</a>
</li>
</ul>
</li>
</ul>
I'm also using angular bootstrap so the line:
<li ng-if="isAuthenticated()" class="dropdown">
triggers angular's own Dropdown directive.
I noticed by simply adding a class to the inner <ul class="dropdown-menu" ...> element I could get a nice open animation.
<ul class="dropdown-menu my-cool-opening-animation" role="menu">
2 questions:
Is this the correct 'angular' way to add the animation?
The animation works when the dropdown opens, but I can't get any animation when the dropdown closes, how do you do this?
This issue looks very similar to what I'm seeing and the fix for the issue seem to be very closely related to what I want. But I don't really understand how to apply it to get animations on the dropdown close.
As a side note, but possibly relevant is I'd like to use/am using the animate.css package as a base for my css animations.
Just faced out with the same issue and spent weeks trying to make two-way fade animation I came up with tricky CSS-solution. Almost done, I've took a look at Fade animation in Angular-UI Modal and what I have found:
<div class="modal fade in" ng-class="{in: animate}">modal content</div>
After checked out the issue #1465 and made a deeper look at Angular Docs (addClass/removeClass methods) I transferred this to Angular-UI Dropdown and what I've got so far:
http://plnkr.co/edit/KO41KkAFnCog3Vfl08Uf?p=preview
Here is the last version of my CSS:
.dropdown.ng-animate-start {
border-spacing: 0;
}
.open-add > .dropdown-menu,
.open-remove > .dropdown-menu {
display: block !important;
}
.open-add > .dropdown-menu {
opacity: 0;
-webkit-transition: opacity .3s ease-in;
-moz-transition: opacity .3s ease-in;
-ms-transition: opacity .3s ease-in;
-o-transition: opacity .3s ease-in;
transition: opacity .3s ease-in;
}
.open-add.open-add-active > .dropdown-menu {
opacity: 1;
}
.open-remove > .dropdown-menu {
opacity: 1;
-webkit-transition: opacity .3s ease-out;
-moz-transition: opacity .3s ease-out;
-ms-transition: opacity .3s ease-out;
-o-transition: opacity .3s ease-out;
transition: opacity .3s ease-out;
}
.open-remove.open-remove-active > .dropdown-menu {
opacity: 0;
}
Hope it helps to save your time.
Related
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/
I want to simulate the horizontal parallax effect on page transition, using the classes ng-enter and ng-leave added by ngAnimate.
The idea is to use different speed for the elements in the page, to have a "3d deep effect" when the elements slide to the left. This is my not-working code
<style>
#keyframes slideOutLeft {
to { transform: translateX(-100%); }
}
#container.ng-enter .layer-one
{animation: slideOutLeft 1s both ease-in-out; }
#container.ng-enter .layer-two
{ animation: slideOutLeft 2s both ease-in-out; }
#container.ng-enter .layer-three
{ animation: slideOutLeft 3s both ease-in-out; }
</style>
<div ng-view id="container">
<ul id="photography-scene">
<li class="layer-one"
<img src="back.jpg" />
</li>
<li class="layer-two"
<img src="mid.jpg" />
</li>
<li class="layer-three"
<img src="front.jpg" />
</li>
</ul>
</div>
this is a JSFIDDLE of my code. In CSS, I defined different animations for elements .one and .two . If I remove these two classes, and leave the animation for the whole ngView, everything works
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.
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>
How do I highlight the newest item added to a list that is displayed with ng-repeat? I've tried using jquery effect() in my addItem() function but that didn't work. I've also tried using the highlight filter from angular-ui without success.
//controller
$scope.addItem = function() {
$scope.items.unshift($scope.item);
};
//html
<ul class="media-list">
<li class="media" ng-repeat="item in items | highlight:item">
Angular has been supporting animations since version 1.1.4.
Just add ng-animate to you lis, with an animation name:
<li ng-animate="'highlight'" ng-repeat="item in items">{{ item }}</li>
and supply the proper animation CSS for that animation name:
li {
-webkit-transition: all 2s 1.5s ease-out;
-moz-transition: all 1.5s ease-out;
transition: all 1.5s ease-out;
}
.highlight-enter-setup {
background: yellow;
}
.highlight-enter-start {
background: white;
}
Here's the fiddle: http://jsfiddle.net/u4Tnw/
You are not limited to just highlighting. You can do all sorts of crazy animations.
Here's a crazier example: http://jsfiddle.net/u4Tnw/3/