Create animation for all children - stylus

I'm attempting to create animations for all children of .flow where each one has an increasing delay. I expected the following code to work, but apparently interpolation is not support in property values.
for i in (1..6)
.flow a:nth-child({i})
animation 1s 0.{i}s fadeIn both
This code would work for the delay, but wouldn't work for the child selector.
for i in 0.1s 0.2s 0.3s 0.4s 0.5s 0.6s
animation 1s {i}s fadeIn both
Any Ideas?

You need to use () in this case.
for i in (1..6)
.flow a:nth-child({i})
animation 1s (i / 10)s fadeIn both

Related

Dynamically animate width of div when collapsed

What I have so far:
JSBIN
Try to double click an item, and It'll show a child item. I want to animate it like that. I set the width to 300px(static) just to show you how it works but, I want it to be width:auto (dynamic) but the animation is not working if I set it to auto.
How can I make it dynamic? for example the child div has more than 2 items inside it or no items at all.
It's a bit of a hack but you can use max-width instead of width and just set an upper bound for the resulting max-width.
http://jsbin.com/mibozupe/1/edit
.slides-child{
display: inline-block;
-webkit-transition:0.5s linear all;
transition:0.5s linear all;
opacity:1;
max-width: 500px;
}
.slides-child.ng-hide{
opacity: 0;
max-width: 0;
}

Fade out element completely before fading another in

As you can see from this jsfiddle:
http://jsfiddle.net/robcampo/pWGuS/
I'm trying to fade out an element and fade another in using Angular animations.
The fading (using opacity and transitions) works. However, as you'll see, it displays the previously hidden element before hiding the current element on display. That leaves you with both elements on display at once.
Question
Is there a way to wait until the first element has been completely hidden before showing the second element? Pretty sure I can do this with a custom directive but before going down that route I'd like to be sure there's no out-of-box way.
What I've tried
a) Put a transition-delay on the element being faded in:
.ng-hide-remove {
-webkit-transition: all 1s ease 1s;
transition: all 1s ease 1s;
opacity: 0;
}
b) Use a height property
This won't work for me because the divs that I'm hiding in my app are part of a grid system.
Note
If I was to implement this in jQuery, it'd be:
elementToFadeOut.fadeOut(1000, function() {
elementToFadeIn.fadeIn(1000);
});
Fixed:
http://jsfiddle.net/robcampo/pWGuS/10/
Used part of Zub's suggestion but also set the height of the container div dynamically so that it doesn't flicker when transitioning.
To achieve this, a directive was created and added to each of the corresponding fading elements (those with ng-show). This directive compares its element's height with that of the parent. If the parent has a lower height, it updates the parent (this prevents flickering):
if (height > parentHeight) {
$(element).parent().height(height);
}
To ensure not all ng-show/hides fade in/out, a the directive animateFade doubles as a CSS class that is applied to the fading animations:
.animate-fade.ng-hide-add {
-webkit-transition: all 1s ease;
transition: all 1s ease;
opacity: 1;
}

How to animate a div height change with AngularJS

I have a div which contains article titles from an RSS feed. This makes the div size dynamic depending on which feed is being looked at, length of article titles, etc. I would like to make the change in div height be a smooth animation like you see here, except using angularJS instead of jQuery.
The only animation I've done with Angular is just a fade-in fade-out text type stuff using
ng-enter{opacity:0;} ng-enter-active{opacity:1;}
Which was fairly simple, so hopefully this will be as well.
Simple example, based on ngAnimate innate monitoring of adding and removing classes. Define 3 css classes :
.transformable {
-webkit-transition: height 100ms linear;
-moz-transition: height 100ms linear;
-o-transition: height 100ms linear;
-ms-transition: height 100ms linear;
transition: height 100ms linear;
}
.small {
height:100px;
}
.big {
height:300px;
}
and declare your div :
<div class="transformable" ng-class="{'small':isSmall, 'big':!isSmall}" ng-click="isSmall = !isSmall"> </div>
This should give you size-changing div on click : angular detects addition/removal of small/big classes and activates animation based on transformable css class values.
You can do similar things with other animation-ready directives (e.g. ng-repeat) or create your custom behaviours. The article from jessegavin seems like a good primer on this.

Angularjs - animating children of repeated elements

Friends,
I'm banging my head about this issue, I was hoping you can help me. I'm trying to animate the child of a repeated element with angularjs 1.2rc1 (perhaps this has changed?), more or less like this:
<div ng-repeat="row in rows" class="animated-row>
<div class="animated-child">Row content</div>
</div>
What I want is to animate the child to move inside the repeated row on enter and leave. Therefore, I have tried, as per the documentation, a selector like this:
.animated-row {
overflow: hidden;
}
.animated-row .animated-child {
position: relative;
}
.animated-row.ng-enter > .animated-child,
.animated-row.ng-leave > .animated-child {
-webkit-transition: 1s linear all;
-moz-transition: 1s linear all;
-ms-transition: 1s linear all;
-o-transition: 1s linear all;
transition: 1s linear all;
}
.animated-row.ng-enter .animated-child,
.animated-row.ng-leave.ng-leave-active .animated-child {
opacity:0;
right:-25%;
}
.animated-row.ng-leave .animated-child,
.animated-row.ng-enter.ng-enter-active .animated-child {
opacity:1;
right:0%;
}
This doesn't work, and angular does not recognize the element as being animated. If I assign the transitions directly to the animated-row element (not its child), then I cannot animate the child with any combination of css selectors other than repeating the transitions both on parent AND child, but this doesn't appear to be working on FF.
Any ideas? Perhaps I'm missing something obvious, but I cannot seem to get the answer.
Thanks for any input!
Best regards,
Rafael PĆ³lit
You need to have your transitions directly on the element that you want to animate. In your case, it is checking to see if .animated-row .animated-child has transitions, which it does not. .animated-row.ng-enter > .animated-child and .animated-row.ng-leave > .animated-child have the animations. Remove the .ng-enter and .ng-leave from that selector to make it .animated-row .animated-child
.animated-row .animated-child{
-webkit-transition: 1s linear all;
-moz-transition: 1s linear all;
-ms-transition: 1s linear all;
-o-transition: 1s linear all;
transition: 1s linear all;
}
Fiddle: http://jsfiddle.net/TheSharpieOne/Y9tE6/1/
UPDATE
After further investigating, the reason why the enter works is more or less by accident, the animation classes ng-leave and ng-enter as well as ng-move are added to the parent class and removed once the animation/transition is done. Because there is no transition applied to the parent, that means it is more or less instant. Adding a transition (even if you don't change any properties) should trick ngAnimate to leave the classes on the parent giving the child enough time to do its thing.
With Add and Remove: http://jsfiddle.net/TheSharpieOne/XkQV7/1/
.animated-row, .animated-row .animated-child{
-webkit-transition: 1s linear all;
-moz-transition: 1s linear all;
-ms-transition: 1s linear all;
-o-transition: 1s linear all;
transition: 1s linear all;
}
The parent and the child now have the transition properties.

Angularjs and smooth page loading

I have an angular controller that loads 4-5 different resources from the server. Upon those resources being received the UI fills the necessary content for the page. The problem I'm having now is that the page load is not very smooth. The page's layout loads immediately, and then different elements pop into existence over the next 1-2 seconds. The load time isn't really the issue, it's just the abruptness of it. Is there a standard way to deal with this?
A trick I use is to default everything to opacity 0, then use CSS transforms to transform them to opacity 1 over about 250ms (quick fade). I apply a class when it's done loading by using the ng-class directive.
Give this code:
ng-class='{showme:hugeArray}' it should apply a class when hugeArray is done loading. Before hugeArray loads or exists, it will be undefined, therefore false and the class showme won't be applied. When hugeArray comes back from your resource, it exists.
Just combine that with this CSS:
.something {
opacity: 0;
text-align: center;
-webkit-transition: opacity 0.25s ease-in;
-moz-transition: opacity 0.25s ease-in;
-o-transition: opacity 0.25s ease-in;
-ms-transition: opacity 0.25s ease-in;
transition: opacity 0.25s ease-in;
}
.something .showme{
opacity: 1;
}
If you have to load the resources in your controller anyway, you should move this logic to the $routerProvider resolve property, so loaded resources get injected into controller once they are resolved. $route service won't make a routechange if a promise gets rejected, so everything is there when your view change happens.
There are a couple of different ways I can think of, here are a few. Here might be a simple one that you could change to fit your needs.
HTML
<body ng-show="object.length"> ...
Controller
$scope.object = Object.query();
Or you could use promise objects to know when they've finished loading. I don't know if you want to hide the body until they're loaded, display them all at the same time, or other.
I think the other answers here are good, but ngCloak is worth mentioning too. It would probably be best used in combination with the some of the other methods.
http://docs.angularjs.org/api/ng.directive:ngCloak

Resources