LoginSignup
12
3

More than 3 years have passed since last update.

#PowerApps における数学 (アニメーション)

Last updated at Posted at 2019-10-04

はじめに

PowerAppsで作成するアプリのUIを、ネイティブアプリまたは通常のWebアプリに近づける1つの方法として、アニメーションの効果を工夫するということがあります。
例えば、サイドメニューを表示する際、単純に考えれば、タイマーの時間に比例したX座標をサイドメニューに設定するでしょう。

Object.X : -1*Object.Width + Object.Width*Timer1.Value/Timer1.Duration

もちろんこれでもタイマーコントロール(Timer1)の時間がTimer1.Durationになったときに、メニューが表示されます。ですが、メニューは、単調な速度で移動して急に静止するので、非常に不自然な動きになります。
これを解消し、メニューの動きをより自然にするために、私はしばしばHyperbolic Tangent関数で挙動を制御しています。※Hyperbolic Tangent関数の概形は下図を参照してください。
Screen Shot 2019-10-04 at 11.03.07 PM.png

Hyperbolic Tangent関数は、おおよそ、x=-3のときTanh(x)≒-1になり,x=3のときTanh(x)≒+1の値をとります。また、最初(xが小さい時)はxの増加に対して急激に値が大きくなるのに対して、x=2付近からサチュレートし、1に漸近することが見て取れます。
本投稿では、このHyperbolic Tangent関数を利用して、PowerAppsにおけるアニメーション効果をいかに実現するか、改善するかを説明します。

サイドメニューの例

先ほどのサイドメニューの改善例を示します。まずはタイマーの時間に比例した場合の動作と、Hyperbolic Tangentを導入した場合の動作を見てみましょう。

右側がHyperbolic Tangent関数を利用した場合です。
動作の開始からすぐに早いスピードで動かしたい場合には、単純に以下のようにXを設定します。

Object.X : -1*Object.Width + Object.Width*(( Exp(2*3*Timer1.Value/Timer1.Duration) -1 )/( Exp(2*3*Timer1.Value/Timer1.Duration) +1 ))

ちょうど、以下の置き換えをおこなったようになっています。

Timer1.Value/Timer1.Duration → (( Exp(2*3*Timer1.Value/Timer1.Duration) -1 )/( Exp(2*3*Timer1.Value/Timer1.Duration) +1 ))

この置き換えがほとんど全てです。右側の関数は 0->1に変化するので、これを利用することによって、あらゆる動作(移動、回転、色の濃淡の変更)を、タイマーの時刻に比例した動作よりも自然に表現することができます。

より一般的には以下のようにかけます。

Object.X : [target x position]-1*[move distance] + [move distance]*(( Exp(2*3*Timer1.Value/Timer1.Duration) -1 )/( Exp(2*3*Timer1.Value/Timer1.Duration) +1 ))

ここで"[target x position]"は、最終的にオブジェクトを配置したいX座標で、"[move distance]"は動く幅になります。即ち、初期位置は"[target x position] - [move distance]"で与えられます。

ちなみに戻す場合には

Object.X : [target x position]-1*[move distance]*(( Exp(2*3*Timer1.Value/Timer1.Duration) -1 )/( Exp(2*3*Timer1.Value/Timer1.Duration) +1 ))

と記述します。
出る/戻るのステート管理はなんらかの変数で行ってください。

円運動の例

あまり利用シーンはありませんが、ローディングサークルのようなアニメーションでも、Hyperbolic Tangentは有効です。

この場合には、最初に動き出す円と、あとから動き出す円の角度成分(極座標におけるθ)にHyperbolic Tangentを適用しています。サイドメニューの例との違いは、円が最初はゆっくり動き出し、加速し、最後に静止するということです。
これを実現するためには、以下のような置き換えを行います。

Timer1.Value/Timer1.Duration → (( Exp(4*3*(Timer1.Value/Timer1.Duration-0.5)) -1 )/( Exp(4*3*(Timer1.Value/Timer1.Duration-0.5)) +1 ) +1)/2

先ほどとの違いは何かというと、"(....+1)/2"の部分です。Hyperbolic Tangentは、xが負の場合に-1になります。これを0->1の変化に直すために、1を足して2で割っています。
また、Exp()の中身も、タイマーの時刻が0の場合に、負の値を取るようにずらしています。

このような置き換えを円運動の角度部分に施すことによって、通常見るようなWebのローディングサークルと同様のアニメーション効果を実現できます。

おわりに

今回のアニメーションを含むサンプルアプリは以下のURLで公開されています。実際に数式をみてみて、自分のアプリに適用してみてください!
すごくそれっぽくなります!

12
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
3