やりたいこと
romannurik氏の神ツール、AndroidIconAnimator を使って、
下向き矢印 expand more を
上向き矢印 expand less に変形させたい。
こんな感じに。
材料
-
AndroidIconAnimator
- ツールの使い方についてはtakahiromさんの記事を参考に -> アニメーションアイコンが作れるAndroid Icon Animatorを触ってみる
-
Material Iconsのアイコン
- 下向き矢印
expand more
- 上向き矢印
expand less
- 下向き矢印
ハマる
初めは単純に以下のことをやりました。
- SVG形式でダウンロードしてきた
expand more
を AndroidIconAnimator に D&D でインポート - pathData アニメーションを追加
- toValue に
expand less
のSVGのパスデータをコピペ
これで、 開始時点では expand more
、終了時点では expand less
のアニメーション が出来上がるはず。
( ゚д゚) 何かが違う…
ハマりどころと回避方法
(前提として)パスデータのコマンド数を合わせる
こにふぁーさんのスライドでも言われている通り、パスデータのコマンドの数が、 fromValue と toValue で一致している必要があります。
Material Iconsの expand more
と expand less
の場合はコマンド数が一致していたので無問題でした。
コマンドの順番を合わせる
できたアニメーションをよく観察すると、 expand more
で右上にある点が expand less
の矢印の頂点になっていることがわかります。
両方のSVGのパスデータも見てみましょう。
コマンドごとに改行を入れています。
<!-- expand more -->
M16.59 8.59
L12 13.17
7.41 8.59
6 10
l6 6
6-6
z
<!-- expand less -->
M12 8
l-6 6
1.41 1.41
L12 10.83
l4.59 4.58
L18 14
z
始めの M
コマンドの座標が、 expand more
では 16.59 8.59
(右上)、 expand less
では 12 8
(中央一番上)。
どうやら、 パスデータに出現するコマンドの順によって fromValue と toValue で対応する点を決定している ようです。
とすれば、 expand more
のコマンドの順番と expand less
の各コマンドが指定する座標がわかれば、 expand more
の各頂点と期待通りに対応する expand less
を描画する事ができそうです。
expand more
の座標を指定するコマンドの順は以下の通りでした。
また、 expand less
の各頂点の座標は以下の通り。
完成イメージ通りに動かしたい場合は、 18 14
から逆時計回りに描画していけば良さそうだということがわかります。
さて、これでアニメーションしてみると
なんだか太ましい…
期待通りにモーフィングしなかったら中割りを入れる
中割りについてはニコニコ大百科が詳しいのでそちらを御覧ください。
今回のアニメーションでは一度棒状になって欲しいので、タイムラインの中間地点でアニメーションを区切ることにしました。
全体では以下のようなアニメーションなので、
- 時間 ... 0.6秒
- Interpolator ... Accelerate/Decelerate
以下のように分割しました。
0.0s 0.3s 0.6s
[expand more] ---> [棒] ---> [expand less]
Accelerate Decelerate
できた! さあ実機で動かそう!
android.view.InflateException: Can't morph from ... to ...
( ゚д゚)
AnimatedVectorDrawableのパスデータではコマンド表記を省略できない
SVGですと、線描画 L
を続けて書きたい場合は、2つ目以降の座標ではコマンドを省略して書くことができます。
<!-- SVGなら大丈夫だがAVDではだめ -->
L10 10
15 20
30 12
...
AndroidのAnimatedVectorDrawableではコマンドが省略できないらしく、各座標にコマンドを明記する必要があるようです。
<!-- AVDでも大丈夫 -->
L10 10
L15 20
L30 12
...
省略されていたコマンドを明記してやることで、無事に動作させることができました。
AndroidIconAnimatorではアニメーションの描画にcanvasを使っており、パスデータはブラウザが解釈できるものであればエラーなど出さずに動いてしまうようです。
SVGを D&D してインポートした際にはAVDで解釈できる形式にコンバートしてくれるようですが、人手でパスデータを操作する際には注意が必要そうです。