how to use animation with ng-repeat in angularjs - javascript

I have a list which I iterate over by using ng-repeat: and the user can interact with thte list items by using up-arrow and down-arrow icons and on click of them i simply change the order of the element in the "list" this is what angular suggests change the model and the changes automatically reflect in the view.
<div ng-repeat="item in list">
{{item.name}}
<div class="icon-up-arrow" ng-click="moveUp($index);"></div>
<div class="icon-down-arrow" ng-click="moveDown($index);"></div>
</div>
Logic in moveUp:-
$scope.moveUp= function(position){
var temp=list[position-1];
list[position-1]=list[position];
list[position=temp];
};
the above code works completely fine and similar is the logic for shifting the item down. But the problem that i want to resolve is how do i put animation? I know angular takes care of binding view and model on its own but is there any way to put in animation as the view is updated on pressing up an down arrow icons?

Following on from Marcel's comment: in AngularJS 1.2 you don't need to use the ng-animate directive. Instead:
Includeangular-animate[-min].js.
Make your module depend on ngAnimate.
Define your transitions in CSS using classes like .ng-enter and .ng-enter-active.
Use ng-repeat as you normally would.
HTML:
<div ng-app="foo">
<!-- Set up controllers etc, and then: -->
<ul>
<li ng-repeat="item in items">{{item}}</li>
</ul>
JavaScript:
angular.module('foo', ['ngAnimate']);
// controllers not shown
CSS:
li {
opacity: 1;
}
li.ng-enter {
-webkit-transition: 1s;
transition: 1s;
opacity: 0;
}
li.ng-enter-active {
opacity: 1;
}
Demo in (someone else's) Plunker.
See the docs for $animate for details on the progression through the various CSS classes.

Check this link http://www.nganimate.org/
You need to declare the ng-animate attribute to an element that have another directive that changes the DOM
div ng-repeat="item in itens" ng-animate="{enter: 'animate-enter', leave: 'animate-leave'}"
You need to add css transitions or animation.
.animate-enter {
-webkit-transition: 1s linear all; /* Chrome */
transition: 1s linear all;
opacity: 0;
}
.animate-enter.animate-enter-active {
opacity: 1;
}
You can check plnkr example here: http://plnkr.co/edit/VfWsyg9d7xROoiW9HHRM

Complementing the last answer, there is the ng-move class for animations when order is changed:
li {
opacity: 1;
}
li.ng-move {
-webkit-transition: 1s;
transition: 1s;
opacity: 0;
}
li.ng-move-active {
opacity: 1;
}
Last documentation here.

If you don’t wish to use ‘ngAnimate’ module because of reduce the plugins count, you can archive the simple transition effect by using ng-init and custom directives.
<li ng-repeat="item in items" class="item" item-init>{{item.name}}</li>
.item{
opacity:0;
-webkit-transition: all linear 300ms;
transition: all linear 300ms;
}
.item.visible{
opacity:1;
}
myApp.directive('itemInit', function ($compile) {
return function (scope, element, attrs) {
scope.initItem(element);
};
});
In you controller
$scope.initItem = function(el){
$timeout(function(){
angular.element(el).addClass('visible');
},0);
}

Related

AngularJS Animation Tabs Won't Fade In

I've been trying to get AngularJS to fade in a tab pane when you select. I have it on jsfiddle
I have the following CSS to animate it with:
.tab-pane.active-add {
transition: opacity 10s;
opacity: 0
}
.tab-pane.active-add.active-add-active {
opacity: 1;
}
As you can see when you go to the fiddle it does not fade in when you change a tab.
use a .css like this:
.tab-pane.active:not(.show) {
opacity: 0;
}
.tab-pane.active{
opacity:1;
transition: opacity 2s;
}
Then declare a new variable
$scope.active_show=0;
Now use ng-class to add the two classes
<div class="tab-pane" ng-class="{active: active === $index,
show: active_show === $index}"
ng-repeat="tab in tabs">
{{tab.content}}
</div>
And change your function like
$scope.setActive = function(index) {
$scope.active = index;
setTimeout(()=>{
$scope.active_show=index;
$scope.$apply();
})
}
The idea is that your div, when active has first a class .active and in a new cycle -it's the function of setTimeOut- the class is .active.show
your fork jsfiddle
NOTE: I use the use of .show/not(.show) because it's the way, e.g. bootstrap, use
NOTE2: I imagine you're work in an old project, AngularJs is a bit old and soon you Sooner rather than later should change to Angular

Vuejs Loop trough all children and execute a function for each iteration

I recently started to work with Vue.js, I'm trying to make something super simple tho on vue everything seems super complicated when doing simple things, especially when you don't have 5 years of vue behind you.
So basically, Imagine I have this component:
<template>
<section class="stuff">
<div class="hello pop1">div content</div>
<ul>
<li class="hello pop2"> stuff </li>
...
</ul>
</section>
</template>
I want to loop trough all childs of stuff so I can add remove one of their class with a timeout between each iteration.
I used to do it like that with jQuery:
$(".stuff").find("*").each(function(i){
setTimeout ( function(){
$("stuff").find(".pop" + i ).removeClass("hello");
},i * 100);
});
(This is an example so the fact that I manually typed is normal)
What's the easiest way to reproduce that in Vue?
Thanks.
If you're attempting a staggered animation by removing classes, you might find Vue's TransitionGroup helpful! Here's a general example:
HTML:
<div id="app">
<transition-group tag="ul" name="slide-in" :style="{ '--total': list.length }">
<li v-for="l,i in list" key="i" :style="{'--i': i}" v-if="showItems && i < 10">Item {{ l }}</li>
</transition-group>
</div>
CSS (fancy-dancy slide-in animation)
.slide-in {
&-move {
transition: opacity .5s linear, transform .5s ease-in-out;
}
&-leave-active {
transition: opacity .4s linear, transform .4s cubic-bezier(.5,0,.7,.4); //cubic-bezier(.7,0,.7,1);
transition-delay: calc( 0.1s * (var(--total) - var(--i)) );
}
&-enter-active {
transition: opacity .5s linear, transform .5s cubic-bezier(.2,.5,.1,1);
transition-delay: calc( 0.1s * var(--i) );
}
&-enter,
&-leave-to {
opacity: 0;
}
&-enter { transform: translateX(-1em); }
&-leave-to { transform: translateX(1em); }
}
JS
new Vue({
el: '#app',
data() {
return {
showItems: false,
list: [0,1,2,3,4,5,6,7,8,9],
}
},
mounted(){
this.$nextTick(()=>{ this.showItems=true });
}
});
Here's a codepen of all that.

Transition on Stretching Div

I have a div with some content in it, and I am showing a button with jQuery. I want to fade it in thus I used:
setTimeout(function() {
jQuery('#button').css('opacity', 1);
}, 100);
First, on html, I have set the button's html to display:none; opacity: 0 I have achieved showing/hiding button, however when it shows, it's making the div stretch instantly. Instead, I want the parent div to expand with transition.
I have created a Fiddle: https://jsfiddle.net/atg5m6ym/7450/ . In this example, when I press the trigger button, I want the button to fade in as well as applying transition on the parent div.
For optimal performance, when using transitions and animations in CSS, you should stick to opacity and transform instead of display: none; and width/height.
Will quote the comment I stated above:
The way you designed this is not ideal, you should not be using
display: none; in transitions or animations. This will cause redrawing
in your browser, and you cannot transition properties with binary
settings, display just switches between states (ex: none/block), not
between values like opacity does.
What you could do is separate your content, sharing the same background color to simulate it is the same container.
Then use transform and the scale() function.
Code Snippet:
jQuery('#trigger').click(function() {
jQuery('.bottom-content').addClass('open');
})
.top-content,
.bottom-content {
background-color: lightblue;
}
.bottom-content {
transform: scaleY(0);
transition: transform 250ms ease-in;
transform-origin: top;
}
.bottom-content.open {
transform: scaleY(1);
}
.bottom-content.open #otherButton {
opacity: 1;
}
#otherButton {
margin-top: 20px;
opacity: 0;
transition: opacity 10s;
transition-delay: 250ms;
/* Separated for clarity purposes, wait for parent transition to end before starting this one*/
}
<script src="https://www.addressfinder.co.nz/assets/v2/widget.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="content">
<section class="top-content">
<button id="trigger">
Trigger
</button>
<br />Lalala La
<br />Lalala La
<br />Lalala La
<br />
</section>
<section class="bottom-content">
<button id="otherButton">
Test Btn
</button>
</section>
</div>
</div>
The accepted answer is overkill. Just use .fadeIn() and forget the opacity and transition settings completely. If you want to have the div expand separate from the button, just apply the effect to the div and then trigger the button effect at the end of the div effect. This snippet does the same thing as the accepted answer without any of the CSS troubles:
$(function(){
jQuery('#otherButton').hide();
jQuery('#two').hide();
});
$('#trigger').click(function() {
$('#two').slideDown(2000, function(){
$('#otherButton').fadeIn();
});
})
#container, #two {
background-color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="container">
<div id="content">
<button id="trigger">Trigger</button>
<br>
Lalala La<br>
Lalala La<br>
Lalala La<br>
<div id="two">
<button id="otherButton">Test Btn</button>
</div>
</div>
</div>
You can combine the jquery:
jQuery('#trigger').click(function() {
jQuery('#otherButton').slideDown(300).css('opacity', 1);
})
Note that I used the slideDown() function rather than show(). Using a transition function allows you to set an execution time. show() simply toggles the css display property, but you can not transition the display property.
Updated Fiddle
Instead of adding CSS with jQuery, you can simply add a class instead.
Set this class to whatever properties you want on it, us as:
.is-visible {
opacity: 1;
}
Example Fiddle: https://jsfiddle.net/atg5m6ym/7456/
Now, CSS doesn't like to transition when switching display: none; so instead I have simply set the height: 0; and only applied necessary styling on the .is-visible class.

Angular show / hide with animation

I'm trying to fade out a div and then show a new div but my code is broken. How can I fix? The fade-out animation works but the showManagement div does not appear.
HTML
<div ng-hide="hidden" ng-class="{fade: startFade}">
<p>this is start content that should be faded</p>
</div>
<div class="showManagement" ng-show="showManagement">
<p>this is the new content to be displayed once the fade is complete.</p>
</div>
JS
$scope.getManagement = function () {
$scope.startFade = true;
$timeout(function(){
$scope.hidden = true;
}, 2000);
// this is the part that doesn't display
$scope.showManagement = true;
};
CSS
.fade{
transition: opacity 3s;
opacity: 0;
}
Since you didn't provide your controller and didn't show where you call the function getManagement(), I'll assume that you want all the fade-out fade-in events show within 2 seconds after angular loaded.
Here's an example on CodePen for how you can achieve your goal with your approach.
And here's the code:
HTML
<body ng-app="myApp">
<div class="wrapper" ng-controller="MainCtrl">
<div ng-class="{fade: startFade}">
<p>this is start content that should be faded</p>
</div>
<div ng-class="{hideManagement: hideManagement, showManagement: showManagement}">
<p>this is the new content to be displayed once the fade is complete.</p>
</div>
</div>
</body>
CSS
.fade{
transition: opacity 3s;
opacity: 0;
}
.hideManagement {
opacity: 0;
}
.showManagement {
transition: opacity 3s 3s;
opacity: 1;
}
JS
angular
.module('myApp', [])
.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout) {
$scope.startFade = false;
$scope.showManagement = false;
$scope.hideManagement = true;
$timeout(function(){
$scope.startFade = true;
$scope.showManagement = true;
$scope.hideManagement = false;
}, 2000);
}]);
A few things you have to keep in mind:
You cannot animate your display: none; and display: block; with CSS3 transition. This is the reason why ng-hide in your .showManagement is not showing with transition effect. You should keep using opacity to achieve this goal, just like you did in ng-class="{fade: startFade}"
Initialize your state at the beginning of your Angular controller. In the example your provide, it's a little bit confusing how you set your $scope.showManagement, $scope.hidden, and $scope.startFade. Once you setup your initial state like the example I provide, it would be more clear that what kind of states change you should make in the function, whether it's in a $timeout callback or some other functions trigger by other events
To make .showManagement fade-in right after the first <div> finishing it's fade-out effect, you may set the delay in css transition.
If you are doing more complex animation, you should try leveraging on ngAnimate service. With ngAnimate, you can get rid of those ng-class in this example, and simply binding your animation rules with .ng-enter, .ng-enter-active, .ng-hide, .ng-hide-active, which are automatically bind to your elements by Angular. Here's the official documentation for ngAnimate.

AngularJS - Animate ng-view transitions

I have 2 html pages, welcome.html and login.html both of which are "inserted" into index.html dependending on the URL via an ngview attribute and router provider, as part of my AngularJS app.
An example of this can be found on the AngularJS home page under Wire up a Backend.
My question: Is there a way to animate the transition between welcome.html and login.html?
Angularjs 1.1.4 has now introduced the ng-animate directive to help animating different elements, in particular ng-view.
You can also watch the video about this new featue
UPDATE as of angularjs 1.2, the way animations work has changed drastically, most of it is now controlled with CSS, without having to setup javascript callbacks, etc.. You can check the updated tutorial on Year Of Moo. #dfsq pointed out in the comments a nice set of examples.
Check this code:
Javascript:
app.config( ["$routeProvider"], function($routeProvider){
$routeProvider.when("/part1", {"templateUrl" : "part1"});
$routeProvider.when("/part2", {"templateUrl" : "part2"});
$routeProvider.otherwise({"redirectTo":"/part1"});
}]
);
function HomeFragmentController($scope) {
$scope.$on("$routeChangeSuccess", function (scope, next, current) {
$scope.transitionState = "active"
});
}
CSS:
.fragmentWrapper {
overflow: hidden;
}
.fragment {
position: relative;
-moz-transition-property: left;
-o-transition-property: left;
-webkit-transition-property: left;
transition-property: left;
-moz-transition-duration: 0.1s;
-o-transition-duration: 0.1s;
-webkit-transition-duration: 0.1s;
transition-duration: 0.1s
}
.fragment:not(.active) {
left: 540px;
}
.fragment.active {
left: 0px;
}
Main page HTML:
<div class="fragmentWrapper" data-ng-view data-ng-controller="HomeFragmentController">
</div>
Partials HTML example:
<div id="part1" class="fragment {{transitionState}}">
</div>
I'm not sure about a way to do it directly with AngularJS but you could set the display to none for both welcome and login and animate the opacity with an directive once they are loaded.
I would do it some way like so. 2 Directives for fading in the content and fading it out when a link is clicked. The directive for fadeouts could simply animate a element with an unique ID or call a service which broadcasts the fadeout
Template:
<div class="tmplWrapper" onLoadFadeIn>
<a href="somewhere/else" fadeOut>
</div>
Directives:
angular
.directive('onLoadFadeIn', ['Fading', function('Fading') {
return function(scope, element, attrs) {
$(element).animate(...);
scope.$on('fading', function() {
$(element).animate(...);
});
}
}])
.directive('fadeOut', function() {
return function(scope, element, attrs) {
element.bind('fadeOut', function(e) {
Fading.fadeOut(e.target);
});
}
});
Service:
angular.factory('Fading', function() {
var news;
news.setActiveUnit = function() {
$rootScope.$broadcast('fadeOut');
};
return news;
})
I just have put together this code quickly so there may be some bugs :)
Try checking his post. It shows how to implement transitions between web pages using AngularJS's ngRoute and ngAnimate: How to Make iPhone-Style Web Page Transitions Using AngularJS & CSS
1.Install angular-animate
2.Add the animation effect to the class ng-enter for page entering animation and the class ng-leave for page exiting animation
for reference: this page has a free resource on angular view transition https://e21code.herokuapp.com/angularjs-page-transition/

Categories

Resources