前回,
今回は減速移動の式を考える.
n
次関数でイージングを表現し,加速(+)の場合は完成した.f(c) = (x1 - x0) * c ^ n + x0
しかし,この式をそのまま減速の式として使用することはできなかった.今回は減速移動の式を考える.
まずはこのグラフを見てほしい.これは左が加速のグラフ,右が減速のグラフである.
分かるとおり,赤い線で書かれた式の軌跡は右と左で相似(というか合同)であることが分かる.
つまり,式を回転したり平行移動するだけで,左の式を右の式に変換することができる.
図を示さないで言葉だけで説明するが,勘弁して欲しい.軌跡を想像して読め!
まず,左の式(軌跡)を
前回のものとまとめる.
これをプログラムで書くと
設定する変数が2個(
値をいろいろ変えることが出来るサンプルはこちら
ちなみに
あきらかに今回のほうが加速・減速の程度が顕著になっていることが分かる.
以上,これでイージング移動の
ここまで読んでくれた方が何人いるか分からないけど,ありがとうございました.
と言いつつ,もう一つ,気になる人は気になる,気付く人は気付く,ほとんどの人はどうでもいい濃い話があるが,できるかも分からないので,出来たらまた書きます.
関連:
・イージングの考え方
・【数学・DHTML】 イージング [Easing] (1)
・【数学・DHTML】 イージング [Easing] (2)
・【数学】 イージングロジックメモ
・【数学・DHTML】 イージング [Easing] (3)
・【DHTML】 加速・減速を考慮したアニメーションプログラム
・【数学・DHTML】 イージング [Easing] (4)
・【数学・DHTML】 イージング [Easing] (5)
分かるとおり,赤い線で書かれた式の軌跡は右と左で相似(というか合同)であることが分かる.
つまり,式を回転したり平行移動するだけで,左の式を右の式に変換することができる.
図を示さないで言葉だけで説明するが,勘弁して欲しい.軌跡を想像して読め!
まず,左の式(軌跡)を
x
軸で反転する.c → -c
f = (x1 - x0) * (-c) ^ n + x0
次に,f = (x1 - x0) * (-c) ^ n + x0
c
軸で反転する.f → -f
-f = (x1 - x0) * (-c) ^ n + x0
んで,c軸方向に -f = (x1 - x0) * (-c) ^ n + x0
+1
だけ移動させる.c → c - 1
-f = (x1 - x0) * (-(c - 1)) ^ n + x0
最後に,x軸方向に -f = (x1 - x0) * (-(c - 1)) ^ n + x0
+(x1 + x0)
だけ移動させる.(ここまでの操作で左のグラフの軌跡が右のグラフの軌跡に重なる)f → f - (x1 + x0)
-(f - (x1 + x0)) = (x1 - x0) * (-(c - 1)) ^ n + x0
ゆえに-(f - (x1 + x0)) = (x1 - x0) * (-(c - 1)) ^ n + x0
-(f - (x1 + x0)) = (x1 - x0) * (-(c - 1)) ^ n + x0
-f + x1 + x0 = (x1 - x0) * (1 - c) ^ n + x0
∴ f(c) = x1 - (x1 - x0) * (1 - c) ^ n ,,
ただし n は1以上の実数
これで完成だ.勿論この式は -f + x1 + x0 = (x1 - x0) * (1 - c) ^ n + x0
∴ f(c) = x1 - (x1 - x0) * (1 - c) ^ n ,,
ただし n は1以上の実数
f(0) = x0, f(1) = x1
を満たす.また n = 1
のとき,等速移動の式と等しくなる.前回のものとまとめる.
n >= 1,0 <= c <= 1
1) 加速のとき
f(c) = x0 + (x1 - x0) * c ^ n
2) 減速のとき
f(c) = x1 - (x1 - x0) * (1 - c) ^ n
1) 加速のとき
f(c) = x0 + (x1 - x0) * c ^ n
2) 減速のとき
f(c) = x1 - (x1 - x0) * (1 - c) ^ n
これをプログラムで書くと
var x0 = 100; // 始点のX座標
var x1 = 500; // 終点のX座標
var a = false; // 加速のとき真,減速のとき偽
var n = 6; // 加速(減速)の程度.1以上の実数.
function move(currentCount, endCount) {
if (currentCount <= endCount) {
var c = currentCount++ / endCount;
e.style.left = f(c) + "px";
setTimeout("move(" + currentCount + ", " + endCount + ");", 10);
}
}
function f(c) {
if (a) {
return x0 + (x1 - x0) * Math.pow(c, n);
} else {
return x1 - (x1 - x0) * Math.pow(1 - c, n);
}
}
となる.実際の例はこちら(減速:6)var x1 = 500; // 終点のX座標
var a = false; // 加速のとき真,減速のとき偽
var n = 6; // 加速(減速)の程度.1以上の実数.
function move(currentCount, endCount) {
if (currentCount <= endCount) {
var c = currentCount++ / endCount;
e.style.left = f(c) + "px";
setTimeout("move(" + currentCount + ", " + endCount + ");", 10);
}
}
function f(c) {
if (a) {
return x0 + (x1 - x0) * Math.pow(c, n);
} else {
return x1 - (x1 - x0) * Math.pow(1 - c, n);
}
}
設定する変数が2個(
a
と n
)になって面倒くさいと思う方はEdgingと同じく,変数を1個とし「-100を最も加速,+100を最も減速」としたものが以下(この場合,今までのn
に上限を持たせる必要があるがそれを10とした).var x0 = 100; // 始点のX座標
var x1 = 500; // 終点のX座標
var v = -80; // 加速(減速)の程度.-100 <= v <= +100.
function f(c) {
var scale = 10;
if (v <= 0) {
var n = (1 - scale) / 100 * v + 1;
return x0 + (x1 - x0) * Math.pow(c, n);
} else {
var n = (scale - 1) / 100 * v + 1;
return x1 - (x1 - x0) * Math.pow(1 - c, n);
}
}
実際の例はこちら(-100〜100)var x1 = 500; // 終点のX座標
var v = -80; // 加速(減速)の程度.-100 <= v <= +100.
function f(c) {
var scale = 10;
if (v <= 0) {
var n = (1 - scale) / 100 * v + 1;
return x0 + (x1 - x0) * Math.pow(c, n);
} else {
var n = (scale - 1) / 100 * v + 1;
return x1 - (x1 - x0) * Math.pow(1 - c, n);
}
}
値をいろいろ変えることが出来るサンプルはこちら
ちなみに
sin
関数で実装していたものはこちら.あきらかに今回のほうが加速・減速の程度が顕著になっていることが分かる.
以上,これでイージング移動の
n
次関数化は完了!ここまで読んでくれた方が何人いるか分からないけど,ありがとうございました.
と言いつつ,もう一つ,気になる人は気になる,気付く人は気付く,ほとんどの人はどうでもいい濃い話があるが,できるかも分からないので,出来たらまた書きます.
関連:
・イージングの考え方
・【数学・DHTML】 イージング [Easing] (1)
・【数学・DHTML】 イージング [Easing] (2)
・【数学】 イージングロジックメモ
・【数学・DHTML】 イージング [Easing] (3)
・【DHTML】 加速・減速を考慮したアニメーションプログラム
・【数学・DHTML】 イージング [Easing] (4)
・【数学・DHTML】 イージング [Easing] (5)
そうっそれです.
始点付近の加速度が異常に小さくなってしまう.
単項のn次関数では,「始点付近の動き」と「終点までの動き」に対するストレスみたいなものは,トレードオフの関係にある.
これを現行の関数を少し変えるだけで,解消したいけど,無理っぽいのよね.