用于动态改变高度的角动画

时间:2017-11-15 18:59:35

标签: angular animation

我成功获得了一个面板,可以在进入和离开DOM时动画扩展和关闭。问题是我现在在显示详细信息之前在面板内有一个忙碌指示器,并且仅在打开忙指示符时发生动画,并在显示详细内容时捕捉。

如何让Angular动画在任何高度变化时设置动画?

我在这里有一个例子:https://plnkr.co/edit/Bs0rwp4ElidR75zN3ulR

trigger('expandCollapseDetails', [
    state('void', style({
        'height': '0px',
        overflow: 'hidden'
    })),
    //element being added into DOM.
    transition(':enter', [
        animate('500ms ease-in-out', style({
            'height': '*',
            overflow: 'hidden'
        }))
    ]),
    //element being removed from DOM.
    transition(':leave', [
        animate('500ms ease-in-out', style({
            'height': '0px',
            overflow: 'hidden'
        }))
    ])
])

4 个答案:

答案 0 :(得分:13)

如果内容发生变化,我已经编写了一个可以平滑地动画投影内容高度的组件。 它的使用方式如下:

<smooth-height [trigger]="content">
  {{content}}
</smooth-height>

这是一个stackblitz:https://stackblitz.com/edit/angular4-kugxw7

这是组件:

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: string;

  startHeight: number;

  constructor(private element: ElementRef) {}  

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

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

  ngOnChanges(){
    this.setStartHeight();
  }
}

答案 1 :(得分:6)

我根据@MartinCremer答案做出了指令。我认为使用指令更有意义,因为这样做,您还应该将动画添加到父组件中(这与添加动画的标准方法很接近)。

因此,在我的animations.ts文件中。我添加了动画:

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

然后,您应该将此动画添加到父组件(要在其中使用动画的组件):

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

这是与@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;
  }
}

最后在parent.component.html中使用指令:

<div [smoothHeight]="yourAnimationIndicator">
  // any html content goes here
</div>

只需将yourAnimationIndicator替换为动画在其值更改时应触发的变量。

答案 2 :(得分:2)

转换和不确定的大小(适合内容,最大内容等)不能很好地沟通。

以下是此情况下的 hack 示例:

animations: [
    trigger('openCloseAnimation', [
      state('open', style({ maxHeight: '100px', overflow: 'auto' })),
      state('closed', style({ maxHeight: '60px' })),
      transition('* => closed', animate('0.2s')),
      transition('* => open', animate('0.5s')),
    ]),
  ],

使用MaxHeight,您的div /容器不会超过“最大内容”,但会表现为“适合内容”。

答案 3 :(得分:1)

你可以通过一些css和js实现类似的东西:

解决方案:

component.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;
}

代码:

softmax_cross_entropy function