UIコンポーネントにどうアニメーションをつけるか。transitionを使ってつける
ここのところ仕事でよくコンポーネントを作っている。可能ならばコンポーネントの状態変更が起こるときにアニメーションをつけて、変化が起きたことをわかりやすくしている。
ぼくがこういうことを最初にしようとしたとき、「アニメーション」という言葉でやり方を調べた。だから最初はCSSのanimationプロパティを使う方法になった。しかし今はtransitionプロパティを使う方法に書き直している。
なんで書き直しているかというと、animationプロパティを使うと初期描画時にもアニメーションが動いてしまうためだ。これを避けたければ、なんしか工夫を入れなければならない。
その工夫を考えたり入れるのが面倒だなーと調べていたらtransitionで解決できたので、その状況を順を追って書いておく。
まずanimationでアニメーションをつけてみる
MDNのCSSアニメーション記事を参考にする。
keyframesを定義してanimationプロパティに割り当てる。
keyframesにはfromとto(あるいは0~100%を使って細かく刻んでいくこともできる)でどんな状態になるかを定義する。fromを抜くと最初からtoに定義したプロパティ値が適用されるので、アニメーションとは言えないものになる。
要素の位置をコントロールするleftプロパティが変化するアニメーションを適用したクラスを定義してみる。
.block {
top: 2px;
position: absolute;
&[data-on=true] {
left: 2px;
animation: goes_on 0.2s;
}
&[data-on=false] {
left: 172px;
animation: goes_off 0.2s;
}
}
@keyframes goes_on {
0% {
left: 172px;
}
100% {
left: 2px;
}
}
@keyframes goes_off {
0% {
left: 2px;
}
100% {
left: 172px;
}
}
data-on属性の値を切り替える(要素をクリックすれば変わるようにコンポーネント定義側でやってある)することでアニメーションが動く。
先に書いた通り、このやリ方ではクラスがわりあてられたタイミングでアニメーションが動いてしまう。だから初期描画時に、クリックしていないのにアニメーションが動いてしまう。
transitionでアニメーションをつける
MDNの記事を参考にtransitionでアニメーションをつける。
どんなアニメーションをつけるかは、上でやったanimationプロパティと同様である。
transitionプロパティにいくつかの値を渡してやればいいが、今回は動かしたいプロパティであるleftと時間を渡す。さらにここでは、data-on属性に渡された値によってleftの値が変わるようにしておく。
.block {
position: absolute;
transition: left 0.2s;
&[data-on=true] {
left: 2px;
}
&[data-on=false] {
left: 172px;
}
}
animationプロパティを使った場合と違い、fromやtoのような値を定義していない。だから始点は状況次第で、前状況のない初期描画時にはアニメーションが動かずに初期位置に要素が表示される。あとはCSSで終点を定義しておく必要もないので、コンポーネントのstyleプロパティで適当にleftに値を渡してやればそこにアニメーションつきで動いていってくれる。
まとめ
コンポーネントの初期描画時にはアニメーションが動いてほしくない。なのでtransitionを使うことが個人的に多くなりそうである。
じゃあ一方でanimationを使うことはないかというとそんなこともない。遊びでトースターのスライドインにバウンドするようなアニメーションを入れた。このアニメーションを作った時にはkeyframesを使って「何%経過したら要素はどこまで移動する」みたいなものを定義しなければならなかった。トースターなので初期描画しておくものでもなく、任意のタイミングで呼ばれて出てきてくれればよかった。なのでanimationプロパティが適していた。
Discussion