Angular Animation For Dynamically Changing Height
I've written a component that smoothly animates the height of projected content if that content changes.
It's used like this:
<smooth-height [trigger]="content">
{{content}}
</smooth-height>
Here's a stackblitz: https://stackblitz.com/edit/angular4-kugxw7
This is the component:
import {ElementRef, HostBinding, Component, Input, OnChanges} from '@angular/core';
import {animate, style, transition, trigger} from "@angular/animations";
@Component({
selector: 'smooth-height',
template: `
<ng-content></ng-content>
`,
styles: [`
:host {
display: block;
overflow: hidden;
}
`],
animations: [
trigger('grow', [
transition('void <=> *', []),
transition('* <=> *', [
style({height: '{{startHeight}}px', opacity: 0}),
animate('.5s ease'),
], {params: {startHeight: 0}})
])
]
})
export class SmoothHeightComponent implements OnChanges {
@Input()
trigger: any;
startHeight: number;
@HostBinding('@grow') grow: any;
constructor(private element: ElementRef) {}
ngOnChanges(){
this.startHeight = this.element.nativeElement.clientHeight;
this.grow = {
value: this.trigger,
params: {startHeight: this.startHeight}
};
}
}
Angular 2/4 Animation on div height
You don't have any states defined in your trigger()
function.
trigger creates a named animation trigger, containing a list of state()
and transition()
entries to be evaluated when the expression bound to the trigger changes (the expression being [@slideInOut]="helpMenu"
in example below).
@Component({
...
animations: [
trigger('slideInOut', [
state('in', style({
overflow: 'hidden',
height: '*',
width: '300px'
})),
state('out', style({
opacity: '0',
overflow: 'hidden',
height: '0px',
width: '0px'
})),
transition('in => out', animate('400ms ease-in-out')),
transition('out => in', animate('400ms ease-in-out'))
])
]
})
export class AComponent implements OnInit {
helpMenu: string;
constructor() { }
ngOnInit() {
this.helpMenu = 'out';
}
toggleHelpMenu(): void {
this.helpMenu = this.helpMenu === 'out' ? 'in' : 'out';
}
}
Then use it in your view like this:
<div [@slideInOut]="helpMenu">
<h1>My Title</h1>
<p>My paragraph</p>
</div>
<button (click)="toggleHelpMenu()">help</button>
How to animate :enter & :leave transitions conditionally in Angular?
According to Angular IO:
When true, the special animation control binding @.disabled binding prevents all animations from rendering. Place the @.disabled binding on an element to disable animations on the element itself, as well as any inner animation triggers within the element.
The following example shows how to use this feature:
@Component({
selector: 'my-component',
template: `
<div [@.disabled]="isDisabled">
<div [@childAnimation]="exp"></div>
</div>
`,
animations: [
trigger("childAnimation", [
// ...
])
]
})
class MyComponent {
isDisabled = true;
exp = '...';
}
When @.disabled is true, it prevents the @childAnimation trigger from animating, along with any inner animations.
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">
Angular2. Animating left to right movement
The solution I came up with: instead of right
use calculated left
value:
state('true', style({
left: 'calc(100% - 200px - 10px)',
})),
state('false', style({
left: '10px',
})),
plunker
Get height of an element in Angular 2
This should work AFAIK.
height: '*'
Just checked. It works !
You can read more here : https://angular.io/docs/ts/latest/guide/animations.html#!#automatic-property-calculation
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.
Related Topics
@Font-Face Doesn't Work in Firefox (But Exact Same Code Works on Another Site)
Flying-Saucer/Itext PDF in Servlet Not Finding CSS File
CSS Layout Help - Stretch Div to Bottom of Page
Brightness Filter in Firefox and Opera Without Svg File
Vertical-Align: Middle with Bootstrap 2
Eliminate Ghost Margin Below HTML5 Canvas Element
How to Overlay a Div Over a Canvas CSS
@Media Query to Target Hi-Res Windows Phone 8+
Overlapping CSS in React, Webpack Application
Images Not Showing in Phonegap Build Application
Safari Bug Using CSS Transition-Delay and CSS Filters
Using @Font-Face CSS Stylewith an Arabic Font
Avoid an Image to Go Outside a Div
Styling Part of The Text in The Placeholder