Saltar al contenido

Animación angular para altura dinámicamente cambiante

Este escrito fue analizado por expertos así garantizamos la exactitud de nuestro post.

Solución:

He escrito un componente que anima suavemente la altura del contenido proyectado si ese contenido cambia. Se usa así:


  content

Aquí hay un stackblitz: https://stackblitz.com/edit/angular4-kugxw7

Este es el componente:

import ElementRef, HostBinding, Component, Input, OnChanges from '@angular/core';
import animate, style, transition, trigger from "@angular/animations";

@Component(
  selector: 'smooth-height',
  template: `
    
  `,
  styles: [`
    :host 
      display: block;
      overflow: hidden;
    
  `],
  animations: [
    trigger('grow', [
      transition('void <=> *', []),
      transition('* <=> *', [
        style(height: 'startHeightpx', 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
    ;
  

Hice una directiva basada en la respuesta de @MartinCremer. Creo que usar una directiva tiene más sentido ya que al hacerlo, también debe agregar la animación a su componente principal (y es una forma estándar de agregar animaciones).

Así que dentro de mi animations.ts expediente. He añadido la animación:

export const smoothHeight = trigger('grow', [
  transition('void <=> *', []),
  transition('* <=> *', [style( height: 'startHeightpx', opacity: 0 ), animate('.5s ease')], 
    params:  startHeight: 0 
  )
]);

entonces debe agregar esta animación a su componente principal (el componente en el que desea usar la animación):

import  smoothHeight  from '@app/animations';
@Component(
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
  animations: [smoothHeight]
)

Y aquí está la directiva que está muy cerca del componente de @MartinCremer:

import  Directive, OnChanges, Input, HostBinding, ElementRef  from '@angular/core';

@Directive(
  selector: '[smoothHeight]',
  host:  '[style.display]': '"block"', '[style.overflow]': '"hidden"' 
)
export class SmoothHeightAnimDirective implements OnChanges 
  @Input()
  smoothHeight;
  pulse: boolean;
  startHeight: number;

  constructor(private element: ElementRef) 

  @HostBinding('@grow')
  get grow() 
    return  value: this.pulse, params:  startHeight: this.startHeight  ;
  

  setStartHeight() 
    this.startHeight = this.element.nativeElement.clientHeight;
  

  ngOnChanges(changes) 
    this.setStartHeight();
    this.pulse = !this.pulse;
  

finalmente adentro parent.component.html usar la directiva:

// any html content goes here

solo reemplaza yourAnimationIndicator con la variable que la animación debe desencadenar al cambiar su valor.

Puedes lograr algo similar con un poco de css y js:

Solución:

componente.ts

import  Component, OnChanges, ViewChild, Input  from '@angular/core';

@Component(
  selector: 'app-exandable',
  templateUrl: './exandable.component.html',
  styleUrls: ['./exandable.component.css']
)
export class ExandableComponent implements OnChanges 

  @Input()
  src;

  @ViewChild('expandable')
  expandable;

  ngOnChanges() 
    this.updateHeight();
  

  updateHeight(delay = 0) 
    const el = this.expandable.nativeElement;

    setTimeout(() => 

      const prevHeight = el.style.height;
      el.style.height = 'auto';
      const newHeight = el.scrollHeight + 'px';
      el.style.height = prevHeight;

      setTimeout(() => 
        el.style.height = newHeight;
      , 50);
    , delay);
  

CSS

.expandable 
  transition: height 0.2s ease-in-out;
  overflow: auto;

Código:

Si eres capaz, puedes dejar un post acerca de qué te ha impresionado de este ensayo.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *