2015年7月27日月曜日

2Dアニメ機能のライブラリを試作(全体設計編)

iOSのAPIには、かなり簡単に使えるアニメーション機能が含まれています。おかげで、いろいろな箇所へアニメーションを付加することが可能です。

それだけにライブラリ化したい重要な候補なのですが、アニメーションが使われる機能や場面が様々で、汎用的なライブラリ化が難しい対象でもあります。

仕方がないので、特定の用途では十分に使えるアニメーション機能として、ライブラリ化してみました。いつものように、UIViewのサブクラスという形でのライブラリ化です。UIViewの中で、指定したアニメーションが動くというわけです。

UIViewであれば、既存のViewに重ねる方法でアニメーションを加えられます。上へ重ねるだけでなく、下に敷いておけば、アニメーションの背景も簡単に実現できるでしょう。

とりあえず、2Dアニメーションの部分だけ試作してみました。どんな形でライブラリ化したのか、どこまでの機能を付けたのか、どれぐらい使いやすいのか、当初期待したほどは良くないのか、いつものように紹介します。

 

まず最初は、大まかな機能を決めます。基本的には、ある程度まで複雑なアニメーションを作れないと、実用にはならないでしょう。そのためには、複数のアニメ部品がそれぞれ独立して動き、全体のアニメーションを構成する形が必須です。

個々のアニメ部品は、それぞれ別々に動きを設定します。使える動きとしては、移動、拡大縮小、回転、透明度変更は必要でしょう。加えて、等速で動くだけでなく、ゆっくり止まるような動きも使いたいはずです。これは、iOSのAPIに含まれるTiming Functionsという指定で可能です。

個々のアニメ部品の動作では、遅延再生や繰り返し再生も必須でしょう。また、再生前と再生後のそれぞれで、部品表示の有無を選べる機能も大事です。これが使えると、いろいろと応用ができますから(この辺の話は使用例で)。

アニメ部品の動きを組み合わせた全体の動作でも、繰り返し再生は必要です。また、一時停止と再生ができると、ユーザーとの対話に役立ちそうです。さらに、キャンセルも必要でしょう。

アニメーションは、動きの指定だけでは実現できません。動かすアニメ部品を用意する必要があります。部品としては、文字列、画像、UIViewの3つを考えました。文字列は、文字列のまま渡すと、文字列の画像が作られて動かせる形です。画像は、画像そのものを動かす形しかないでしょう。UIViewは自由な部品を作れるので、利用範囲を広げるために必須だと考えました。これらをアプリ側が用意して、アニメ機能のライブラリに渡します。

動作の指定は、いつものように定義データとして用意します。その定義データとアニメ部品(文字列、画像、UIView)を組み合わせて、自由なアニメーションを作れるというライブラリを目指しました。

近い将来、3Dアニメーション機能も追加する予定です。そのとき、2Dと3Dを混在させても動くことが必須です。ですから、3D機能を追加しやすいように、また混在しても動くような内部構造で作る必要があります。

 

以上の話をまとめると、次のようになります。

2Dアニメーション機能に求める機能
・UIViewのサブクラスとして作る
・アニメーションの動作は、定義データとして用意する(簡単に使えること)
・定義データ以外には、文字列、画像、UIViewもアニメ部品として使える
・複数の要素を動かせ、それぞれが独立した動きを指定できる
・個々の要素の動きは単純でも構わないが、それを組み合わせて複雑な動きも作れる
・個々の要素の動作として、移動、拡大縮小、回転、透明度を指定できる
・個々の要素の動作として、Timing Functionsを指定できる
・個々の要素の動作として、遅延再生、繰り返しも可能
・個々の要素の動作として、再生前と動作後に、それぞれ非表示も可能
・組み合わせた全体の動作として、繰り返しも可能
・組み合わせた全体の動作として、一時停止と再開、キャンセルも可能
・内部構造では、3D要素を追加しやすく、また2Dと3Dの要素が混在して動くように最初から配慮する

個々のアニメ部品の動きは単純なものばかりですが、それらを組み合わせて使うと、意外に多くのアニメーションを実現できそうです。実際、凝った動きのアニメーションを使う機会はほとんどないですから、これぐらいの機能でも十分だと思います。

 

機能の整理がまとまったので、実現方法の検討に入ります。iOSのAPIに含まれるアニメーション機能は、いろいろな形で用意されているため、どれを使うのか選択しなければなりません。

改めて、いろいろと調べてみたところ、大事な点が分かりました。UIViewから呼び出せるアニメーション機能は、途中でキャンセルできないと判明したのです(もしかしたら間違っているかもしれません。その場合は、お知らせください)。これで、UIViewのアニメーション機能の採用は不可能になりました。

残った候補の中で、一番使いやすいのがCABasicAnimationでした。簡単に使えるものの、機能が意外に多いのが特長です。API上の位置付けとしては、Core Animationを使いやすくするために用意したAPIという感じでしょうか。

UIViewから呼び出せるアニメーション機能よりも、多くの機能があります。将来的な拡張も容易なので、その点でも安心して採用できます。当然ですが、途中のキャンセルも出来ますし、再生の一時停止や再開も簡単です。

 

以上の話をもとに、これから作るクラスの内部構成を作ってみたら、次のようになりました。

2Dアニメーション機能を持つViewクラスの内部構成
・UIViewのサブクラス
・内部データ:定義データ+表示部品、状態保持(再生中、一時停止中)
・初期化(Viewのサイズ、定義データ+表示部品)
・メソッド:
 ・再生開始(繰り返し回数)
 ・一時停止および再開
 ・再生キャンセル
 ・状態問い合わせ(再生中、一時停止中)
・透明ボタン:一時停止と再開
 ・初期状態ではオフ
 ・メソッド:透明ボタンのオンオフ

見て分かるように、機能としては単純です。アニメーション部分だけ作れれば、そのまま完了する感じですね。

アニメーションの再生では、複数の要素が含まれ、それぞれが異なる動作なので、そこさえキッチリと作れれば大丈夫そうです。また、一時停止や再開も、複数の要素を一緒に扱わなければなりません。

実際に作ってみたら、ソースコードは予想外に長くなりました。クラスの本体部分よりも、データ定義のソースが長くなったからです。使い勝手を良くしようと、いろいろな初期化を用意したためです。

 

とりあえず試作したのは、2Dアニメーションだけです。作り終わって一番苦労したと思った点は、アニメーションの処理ではありませんでした。アニメーションの動きを定義する、データ定義の設計に一番苦労したのです。何度か修正を繰り返しながら、やっと落ち着いたという感じでした。

具体的なソースコードは、次回からの投稿で紹介します。

0 件のコメント:

コメントを投稿