Angular 2 Animation VS CSS Animation - When to Use What

angular 2 animation vs css animation - when to use what?

The question is actually more javascript animation vs css animation (because angular2's animations are based on javascript-animation).

The answer is that when you can - use CSS animation.

Modern browsers uses different thread for CSS animation, so the javascript-thread is not affected by the CSS animations.

You can use the HTML5 Animation Speed Test to check the preformance of different frameworks (javscript-based) VS CSS animation in your browser.

In general:

Browsers are able to optimize rendering flows. In summary, we should always try to create our animations using CSS transitions/animations where possible. If your animations are really complex, you can may have to rely on JavaScript-based animations instead.

If you want to know specifically regarding the Angular2 animations - just inspect the element in your browser and check if the animation there is a CSS(transition/animationFrame based or javascript (you will be able to see values in the style attribute change during the animation).

What is the purpose of Angular animations?

So I did some research and although I didn't find any argument for nor against Angular animations performance-wise (as already stated in the question above), there are very good arguments to use Angular animations feature-wise which should be good enough for purists who want to have CSS only in sheets, at least in certain cases.

Let me list some useful features where each alone makes a convincing case for Angular animations. Most of them can be found in Angular animations documentation:

  1. Transition styles - these styles are only applied during transition from one state to another - only while an element is being animated, and one uses them like this:

    transition('stateA => stateB', [style({...}), animate(100)])

    Trying to do the same with CSS only might not be as expressive in terms of which previous state led to the next. And it can be outright clunky if the animation has to differ based on the initial state but the end state is the same.

  2. The void state together with :enter and :leave aliases (void documentation, :leave and :enter documentation) - Let you animate elements being added or removed from the DOM.

    transition('stateA => void', animate(...))

    This is very cool because previously, although it was easy enough to animate the addition, the removal was more complicated and required to trigger animation, wait till its end and only after that remove the element from the DOM, all with JS.

  3. Automatic property calculation '*' (documentation) - Allows for performing traditionally difficult animations like height transitions for elements with dynamic height. This problem required either to set fixed height on element (inflexible), use max-height with tuned transition function (not perfect) or query element's height with JS (potentially causing unnecessary reflows). But now with Angular it is as easy as this:

    trigger('collapsible', [
    state('expanded', style({ height: '*' })),
    state('collapsed', style({ height: '0' })),
    transition('expanded <=> collapsed', animate(100))
    ])

    And the animation is smooth and "complete" because the actual height of the element is used for the transition.

  4. Animation callbacks (documentation) - this is something that wasn't possible with CSS animations (if not maybe emulated with setTimeout) and is handy eg. for debugging.

  5. Unlike stated in the question, it is actually possible to use instance fields as params in Angular animations, see this question. I find it much easier to use than manipulating CSS variables through DOM API as shown here on MDN, not mentioning the limited support in some browsers.

If you need any of the features listed above, Angular can be a better tool for the task. Also when there is many animations to manage in a component, and this is just my personal opinion, I find it easier to organize animations the Angular way than have them in sheets, where it is harder too see the relationships between them and various element states.

Angular Animation Performance State/Transition vs Query

Angular uses the web animations api, so it's not changing style properties through JavaScript and is therefore quite performant. You can check the performance of different animation frameworks (javascript-based) vs CSS with the HTML 5 Animation Speed Test.

The performance in different browsers is therefore dependent on the browser compatibility of the web animations api (unfortunately the section is not being maintained yet). But, according to the comment here, it is not fully supported yet across common browsers and is being polyfilled for Edge/Safari.

Change style class with Angular animation or similar

Css animations & binding to a class

Using grid is cool but there's not a nice way to achieve what you want with it

Try this on for size

https://stackblitz.com/edit/angular-jeamzb?file=src/app/app.component.ts

It's not your exact solution but I whipped it up to show you how you could do something like this

angular 2 ngIf and CSS transition/animation

update 4.1.0

Plunker

See also https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24

update 2.1.0

Plunker

For more details see Animations at angular.io

import { trigger, style, animate, transition } from '@angular/animations';

@Component({
selector: 'my-app',
animations: [
trigger(
'enterAnimation', [
transition(':enter', [
style({transform: 'translateX(100%)', opacity: 0}),
animate('500ms', style({transform: 'translateX(0)', opacity: 1}))
]),
transition(':leave', [
style({transform: 'translateX(0)', opacity: 1}),
animate('500ms', style({transform: 'translateX(100%)', opacity: 0}))
])
]
)
],
template: `
<button (click)="show = !show">toggle show ({{show}})</button>

<div *ngIf="show" [@enterAnimation]>xxx</div>
`
})
export class App {
show:boolean = false;
}

original

*ngIf removes the element from the DOM when the expression becomes false. You can't have a transition on a non-existing element.

Use instead hidden:

<div class="note" [ngClass]="{'transition':show}" [hidden]="!show">

Apply animations on array length change

Here's an example:

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('simpleFadeAnimation', [
state('in', style({ opacity: 1, height: 100 + 'vh' })),
transition(':enter', [
style({ opacity: 0, height: 0 + 'vh' }),
animate(200),
]),
transition(
':leave',
animate(400, style({ opacity: 0, height: 0 + 'vh' }))
),
]),
],
})
export class AppComponent {
name = 'Angular';
data = ['A', 'B', 'C'];

add() {
const random = Math.floor(Math.random() * 10);
this.data.push(random.toString());
}

remove() {
this.data.pop();
}

removeThis(index) {
this.data.splice(index, 1);
}
}

Working example: https://stackblitz.com/edit/angular-animation-when-removing-jfle8g?file=src%2Fapp%2Fapp.component.ts

Animation in Angular 2 with pure CSS

It can be done easily with Angular animations. Here is your example updated: https://stackblitz.com/edit/angular-ivy-aw3zs3?file=src/app/card/card.component.ts

You just need to provied a state function to handle the transtion trigger.

transition((fromState: string, toState: string) => toState != fromState, [
// animations
])

And you need to link the animation with the target variable

<div class="card" [style]="style" [@cardChange]="card.card">
</div>


Related Topics



Leave a reply



Submit