[Xamarin.Forms] Easing Functionを自作する

はじめに

こんにちは。モバイルアプリサービス部の加藤潤です。
前回の記事では、Easingクラスに標準で用意されているEasing Functionsを試してみました。
今回はEasing Functionを自作する方法をご紹介します。

検証環境

以下の環境で動作を確認しています。

  • Xamarin Studio Community バージョン 6.2(build 1829)
  • Xamarin.Forms バージョン 2.3.3.193
  • iPhone 7 iOS 10.2(シミュレーター)

3通りの書き方

Easing Functionを自作するには以下の3通りの書き方があります。

  • double型を引数に取り、double型を返すメソッドを定義する方法
  • Func<double, double>を定義する方法
  • Easingのコンストラクターの引数にEasing Functionを指定する方法

それぞれの書き方でLinear Easing Functionを自作してみます。

double型を引数に取り、double型を返すメソッドを定義する方法

以下のようなdouble型を引数に取り、double型を返すメソッドを定義します。
引数に経過時間が0から1の範囲で渡ってくるので、その時間に対するプロパティの変化量を返します。

private double CustomLinear(double t)
{
    return t; // Linearなのでプロパティの変化量と経過時間は等しい
}

使う側でメソッド名を指定します。

await boxView.TranslateTo(250, 0, 1000, CustomLinear);

Func<double, double>を定義する方法

以下のようにFunc<double, double>を定義し、アニメーションメソッド実行時に指定します。

Func<double, double> CustomLinear = t => t;
await boxView.TranslateTo(250, 0, 1000, CustomLinear);

Easingのコンストラクターの引数にEasing Functionを指定する方法

以下のようにEasingクラスのコンストラクターの引数に直接Easing Functionを指定することも可能です。

await boxView.TranslateTo(250, 0, 1000, new Easing(t => t));

上記のどの書き方でも結果は同じです。以下のように等速のアニメーションになります。 custom_linear

BounceOutを自作してみる

より複雑なEasing FunctionとしてBounceOutを自作してみました。 こちらの式を使用させていただきました。

private double CustomBounceOut(double t)
{
    if (t < 4 / 11.0)
    {
        return (121 * t * t) / 16.0;
    }
    else if (t < 8 / 11.0)
    {
        return (363 / 40.0 * t * t) - (99 / 10.0 * t) + 17 / 5.0;
    }
    else if (t < 9 / 10.0)
    {
        return (4356 / 361.0 * t * t) - (35442 / 1805.0 * t) + 16061 / 1805.0;
    }
    else
    {
        return (54 / 5.0 * t * t) - (513 / 25.0 * t) + 268 / 25.0;
    }
}
await boxView.TranslateTo(250, 0, 1000, CustomBounceOut);

custom_bounce_out

おわりに

今回はEasing Functionを自作してみました。返す値次第で様々なEasing Functionが作れそうです。
書き方が3通りありますが、Easing Functionの処理を色々な箇所で再利用する場合はメソッドとして切り出した方が良いと思いますし、逆に使い回さず、処理も複雑でなければラムダ式で書いてしまって良いかと思います。

参考記事