Android
MaterialDesign
AndroidIconAnimator

アニメーションアイコンが作れるAndroid Icon Animatorを触ってみる

More than 1 year has passed since last update.

AndroidIconAnimatorとは

GoogleのRoman Nurikにより神のようなツールが作られました。(まだPreview Releaseです)
https://romannurik.github.io/AndroidIconAnimator/

image

GUIでAndroidのAnimatedVectorDrawableを作れるツールです。

VectorDrawableのメリットなどはこちらをどうぞ。また最後の方にAnimated Vector Drawableについても紹介しています。
https://speakerdeck.com/takahirom/support-vector-drawable

これによりマテリアルデザインのicon animationが可能になります。
https://material.google.com/motion/creative-customization.html

これによりエンジニアいらずでデザイナがアニメーションするアイコンが作れてしまうかもしれません。

アニメーションを再生してみる

かんたんに試すにはまず、画面上部のexamplesをクリックしてダウンロードします。
image

zipファイルがダウンロードできるので、その中のファイルをページにドラッグアンドロップします。
すると読み込まれ、そして再生ボタンを押すと以下のように再生されます。
icon_animator.gif

また、この記事を公開した後に教えてもらったのですが、SVGファイルを画面にドラッグ・アンド・ドロップで要素を追加できるようです。

アニメーションを構成する要素

各要素を説明すると以下のようになります。

image

path

実際のSVGのパスのデータ(pathData)と色や大きさなどのデータがふくまれているものです。
この画像のデータはアニメーションしている矢印の上の部分です。
image

pathに対してのアニメーション要素

pathに対して、時計アイコンを押してアニメーションを追加できます。
image

以下の要素がアニメーション可能になります。
image

普通に大きさを変えたり、横にスライドさせるアニメーションの他にも特殊なアニメーションを利用できます。

あるパスからあるパスに滑らかに変更するアニメーション(path morphing)であるpathDataというものが利用できるのですが、これは現状ではAPI Level 21(Android 5.0以上でしか利用できないので注意してください。)

path_morphing.gif

今回の矢印を先頭から消すアニメーションのtrimPathStartなどはSupport Libraryという公式ライブラリを利用することで、低いAPIレベルでもアニメーション可能となります。
つまり、この矢印のアニメーションはpathDataのアニメーションが入っていないので、Android 4.xでもちゃんと動作するはずです。
(直接関係ないのですが、Material DesignのNatural easing curvesとして紹介されているアニメーションの加速度などの調整ができるInterpolatorも設定できますね。)
icon_animator.gif

layer group

layer groupは複数のpathをまとめるもので、このlayer groupに対してアニメーションを追加することができます。
例えばpage_1に対して、右の時計マークを押して、scaleアニメーションを追加すると以下のように全体の大きさをアニメーションします。
image
(右側のプロパティの設定でアニメーション秒数や最初の大きさと最後の大きさを指定してあげました。)
grop_scale.gif

layer groupに対してのアニメーション要素

ここにあるプロパティをアニメーションすることができます。
大きさを変えたり、横に移動したりできます。
image

clip path

アニメーション要素の追加から追加でき、これにより描画しない領域をアニメーションできたりするようなのですが、現状調べきれていません。

clip.gif

ExportしたAnimated Vector Drawable

以下のように吐き出されますのでdrawableフォルダに入れてください

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">

        <vector
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:width="24dp"
            android:height="24dp"
            android:viewportWidth="24"
            android:viewportHeight="24">

            <!-- ****layer group**** -->
            <group android:name="page_1">
                <group android:name="artboard">

                    <!-- ****path**** -->
                    <path
                        android:name="top_arrow"
                        android:pathData="M4,12 L12,4"
                        android:strokeColor="#ff979797"
                        android:strokeWidth="2"
                        android:trimPathEnd="0"
                        android:strokeLineCap="square"
                        android:strokeLineJoin="miter"
                        android:strokeMiterLimit="10"/>
                    <path
                        android:name="bottom_arrow"
                        android:pathData="M 4 12 L 12 20"
                        android:strokeColor="#ff979797"
                        android:strokeWidth="2"
                        android:trimPathEnd="0"
                        android:strokeLineCap="square"
                        android:strokeLineJoin="miter"
                        android:strokeMiterLimit="10"/>
                    <path
                        android:name="middle"
                        android:pathData="M4.5,12 L20,12"
                        android:strokeColor="#ff979797"
                        android:strokeWidth="2"
                        android:strokeLineCap="butt"
                        android:strokeLineJoin="miter"
                        android:strokeMiterLimit="10"/>
                </group>
            </group>
        </vector>
    </aapt:attr>

    <!-- ****top_arrowに対するアニメーション**** -->
    <target android:name="top_arrow">
        <aapt:attr name="android:animation">
            <objectAnimator
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:name="top_arrow"
                android:propertyName="trimPathEnd"
                android:startOffset="525"
                android:duration="731"
                android:valueFrom="0"
                android:valueTo="1"
                android:valueType="floatType"
                android:interpolator="@android:interpolator/fast_out_slow_in"/>
        </aapt:attr>
    </target>

    <!-- ****bottom_arrowに対するアニメーション**** -->
    <target android:name="bottom_arrow">
        <aapt:attr name="android:animation">
            <objectAnimator
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:name="bottom_arrow"
                android:propertyName="trimPathEnd"
                android:startOffset="525"
                android:duration="731"
                android:valueFrom="0"
                android:valueTo="1"
                android:valueType="floatType"
                android:interpolator="@android:interpolator/fast_out_slow_in"/>
        </aapt:attr>
    </target>

    <!-- ****middleに対するアニメーション**** -->
    <target android:name="middle">
        <aapt:attr name="android:animation">
            <objectAnimator
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:name="middle"
                android:propertyName="trimPathStart"
                android:duration="550"
                android:valueFrom="1"
                android:valueTo="0"
                android:valueType="floatType"
                android:interpolator="@android:interpolator/fast_out_slow_in"/>
        </aapt:attr>
    </target>
</animated-vector>

まとめ

結構完成度が高く、Animated Vector Drawableでできそうなところは一通りサポートしているようです。
現状だと、デザイナーが使うにはtrimPathStartやInterpolatorなどを理解しないといけないので大変ですが、
イケイケなアプリを作っていきましょう!