web-dev-qa-db-ja.com

スライドダウンアニメーションAngular 4

ページをアニメーション化しようとしていますが、次の問題があります。
ページにコンテンツdivがあり、コンテンツの上に別のdivを開くボタンがあります。そのdivをフェードインしてスライドインさせ、divのベローも同様に上下にスライドさせたいです。クリックして開く上記のdivに必要なアニメーションを作成しましたが、コンテンツdivの処理方法がわからないため、以下のコード例を参照してください。

<div class="wrapper">
  <button (click)="animated = !animated"></button>
  <div *ngIf="animated" [@slideInOutAnimation] class="animated-div">
  THIS DIV IS ANIMATED</div>

  <div class="content">THIS IS CONTENT DIV</div>

</div>

TypeScript:
animations: [
trigger('slideInOutAnimation', [

  state('*', style({

  })),
  transition(':enter', [
    style({
      transform: 'translateY(-10%)',
      opacity: 0
    }),
    animate('.5s ease-in-out', style({
      transform: 'translateY(0)',
      opacity: 1
    }))
  ]),
  transition(':leave', [
    animate('.5s ease-in-out', style({
      transform: 'translateY(-10%)',
      opacity: 0
    }))
  ])
])
]

コンテンツdivをアニメートされたdivとともに移動するトリガーを他に作成する必要がありますか?

13

最初に、アニメーションを定義してエクスポートするファイルを作成します。 app.component.tsでより明確にするためだけに

次の例では、0px(非表示の場合)から500pxに達するdivのmax-heightを使用しましたが、必要に応じて変更します。

このアニメーションは状態(インとアウト)を使用し、ボタンをクリックするとトグルされ、アニメーションが実行されます。

animations.ts

import { trigger, state, style, transition,
    animate, group, query, stagger, keyframes
} from '@angular/animations';

export const SlideInOutAnimation = [
    trigger('slideInOut', [
        state('in', style({
            'max-height': '500px', 'opacity': '1', 'visibility': 'visible'
        })),
        state('out', style({
            'max-height': '0px', 'opacity': '0', 'visibility': 'hidden'
        })),
        transition('in => out', [group([
            animate('400ms ease-in-out', style({
                'opacity': '0'
            })),
            animate('600ms ease-in-out', style({
                'max-height': '0px'
            })),
            animate('700ms ease-in-out', style({
                'visibility': 'hidden'
            }))
        ]
        )]),
        transition('out => in', [group([
            animate('1ms ease-in-out', style({
                'visibility': 'visible'
            })),
            animate('600ms ease-in-out', style({
                'max-height': '500px'
            })),
            animate('800ms ease-in-out', style({
                'opacity': '1'
            }))
        ]
        )])
    ]),
]

次に、app.componentでアニメーションをインポートし、アニメーションの状態を切り替えるメソッドを作成します。

app.component.ts

import { SlideInOutAnimation } from './animations';

@Component({
  ...
  animations: [SlideInOutAnimation]
})
export class AppComponent  {
  animationState = 'in';

  ...

  toggleShowDiv(divName: string) {
    if (divName === 'divA') {
      console.log(this.animationState);
      this.animationState = this.animationState === 'out' ? 'in' : 'out';
      console.log(this.animationState);
    }
  }
}

そして、あなたのapp.component.htmlは次のようになります:

<div class="wrapper">
  <button (click)="toggleShowDiv('divA')">TOGGLE DIV</button>
  <div [@slideInOut]="animationState" style="height: 100px; background-color: red;">
  THIS DIV IS ANIMATED</div>
  <div class="content">THIS IS CONTENT DIV</div>
</div>

slideInOutは、animationstsで定義されたアニメーショントリガーを指します。

これが私が作成したStackBlitzの例です: https://stackblitz.com/edit/angular-muvaq

サイドノート:エラーが発生し、BrowserAnimationsModuleの追加を求められた場合は、app.module.tsにインポートしてください:

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  imports: [ ..., BrowserAnimationsModule ],
  ...
})
34
br.julien

動的な高さコンテンツを許可するために、高さの遷移を処理する場合、ワイルドカード演算子を非常に好みます。

// Bind to true/false states via 0 and 1 values

trigger('slideUpDown', [
  state('0', style({ 'max-height': '*', opacity: 1 })),
  state('1', style({ 'max-height': '0px', opacity: 0 })),
  transition(':enter', animate('400ms ease-in-out')),
  transition('* => *', animate('400ms ease-in-out')),
])

使用法:

<div #someDiv [@slideUpDown]="someDiv.state"></div>

他の場所またはテンプレートで状態を切り替えることができます。

<button (click)="someDiv.state = !someDiv.state"></button>
14
Mustafa Samar