Help us understand the problem. What is going on with this article?

Angular 2でCSSアニメーションを書く

More than 3 years have passed since last update.

どうも、らこです。 Angular 2の勉強会で出た質問でアニメーションのことがあったので、試してみたら問題なく動いたので使い方を紹介します。

はじめに

Angular 2のメインパッケージに含まれているのはangular2/animateモジュールです。これはもう実用段階のAPIです。
それとは別に、ngAnimateというプロジェクトも動いており、これはアノテーションベースでアニメーションを宣言的に記述できるようにしようというものです。まだ全然出来てないのでいまは使えませんがデザインドキュメントはみることができます。

Animations for Angular 2 Beta - Google ドキュメント

今回紹介するのは前者の今使える方です。

完成形

マウスオーバーで背景を指定された色に変更するアニメーションが動くディレクティブを書きました。

いろいろごちゃ混ぜですが動くサンプルはここにあります

import {Directive, Input, HostListener, AfterViewInit} from "angular2/core";
import {AnimationBuilder} from "angular2/animate";

@Directive({
  selector: "[egAnimate]"
})
export class AnimateDirective implements AfterViewInit {
  @Input() color: string;
  private originalColor: string;

  constructor(private animate: AnimationBuilder) {
  }

  ngAfterViewInit(): any {
    this.color = this.color || "red";
  }

  @HostListener("mouseover", ["$event.target"])
  onMouseOver(el: HTMLElement) {
    this.originalColor = el.style.color;
    return this.animate.css()
      .setFromStyles({
        "background-color": this.originalColor,
      })
      .setToStyles({
        "background-color": this.color,
      })
      .setDuration(1000)
      .start(el);
  }

  @HostListener("mouseleave", ["$event.target"])
  onMouseLeave(el: HTMLElement) {
    return this.animate.css()
      .setFromStyles({
        "background-color": this.color
      })
      .setToStyles({
        "background-color": this.originalColor
      })
      .setDuration(1000)
      .start(el);
  }
}

本稿では@Input@HostListenerAfterViewInitについては省略します。

準備

angular2/animateはAngular 2本体に同梱されているので、単純にimportするだけでいいです。

import {AnimationBuilder} from "angular2/animate";

AnimationBuilderは特にproviderを書かなくてもComponentかDirectiveのコンストラクタなら最初からDIできるようになっています。

    constructor(private animate: AnimationBuilder) {
    }

AnimationBuilderの使い方

AnimationBuilderは、アニメーションを手続き的に組み立てるためのAPIです。
アニメーションを組み立てるには、まず初めにcss()関数を呼び出し、CSSアニメーションの組み立てを始めます。
(おそらく将来的にはCSS以外にもなんかサポートするのかもしれません)

this.animate.css()

css()関数の戻り値はCssAnimationBuilderです。CssAnimationBuilderは以下のような機能でアニメーションを組み立てられます。

  • クラスを追加する
  • クラスを除去する
  • スタイルをセットする
  • アニメーションの時間を設定する
  • アニメーションが始まるまでの遅延時間を設定する
  • アニメーションが終わった時にコールバックを受け取る

クラスを追加する・削除する

動的にクラスを追加するにはaddClass関数、またはaddAnimationClass関数を使います。
addClass関数はアニメーションの開始時にクラスを追加するだけです。addAnimationClass関数はそれに加えてアニメーションが終了した時に自動でそのクラスを除去します。

animate.css()
    .addClass("some-class")
    .addAnimationClass("some-temporary-class")

スタイルをセットする

動的にCSSのスタイルを変更するにはsetStylessetFromStylessetToStylesの3つの関数を使います。

setStylesはアニメーション開始時にセットする初期のスタイルと、終了時にセットするスタイルを一度に設定できます。

animate.css()
    .setStyles({
        "background-color": "white",
    },{
        "background-color": "red",
    })

setFromStylessetToStylesは初期スタイルと終了スタイルを個別に設定できるAPIです。

animate.css()
    .setFromStyles({
        "background-color": "white",
    })
    .setToStyles({
        "background-color": "red",
    })

アニメーションの時間を設定する

setDuration関数でアニメーションの開始から終了までの時間を設定します。具体的にはCSSのtransition-durationが設定されます。

animate.css()
    .setDuration(1000)

アニメーションの開始までの遅延時間を設定する

setDelay関数でアニメーションの開始までの時間を設定します。具体的にはCSSのtransition-delayが設定されます。

animate.css()
    .setDelay(1000)

アニメーションを開始する

CssAnimationBuilderでアニメーションを組み立て終わったら、start()関数でアニメーションを開始します。start()関数にはHTMLElement型のオブジェクトを渡します。

this.animate.css()
    .setFromStyles({
        "background-color": this.originalColor,
    })
    .setToStyles({
        "background-color": this.color,
    })
    .setDuration(1000)
    .start(el)

start()関数が実行された瞬間からアニメーションが開始します。

アニメーションの終了でコールバックを受け取る

start()関数の戻り値はAnimation型ですが、Animationは内部でPromiseを持っているので、終了時に処理を実行できます。onComplete()関数にコールバック関数を渡せばアニメーション終了時に一度だけ呼びだされます

this.animate.css()
    .setFromStyles({
        "background-color": this.originalColor,
    })  
    .setToStyles({
        "background-color": this.color,
    })
    .setDuration(1000)
    .start(el)
    .onComplete(()=> {
        console.log("animated!")
    });

まとめ

angular2/animateめっちゃ良いので使いましょう。setTimeoutRendererで頑張るのやめよう!

lacolaco
I play Angular and pray for Angular. No Breaking Changes, No Life.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした