5
// t: current time, b: begInnIng value, c: change In value, d: duration

def: 'easeOutQuad',
swing: function (x, t, b, c, d) {
    //alert(jQuery.easing.default);
    return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
},
easeInQuad: function (x, t, b, c, d) {
    return c*(t/=d)*t + b;
},
easeOutQuad: function (x, t, b, c, d) {
    return -c *(t/=d)*(t-2) + b;
},

Robert Penner の Easing Functions を Python に変換しようとしていますが、動けなくなりました! 以前にこれを行った助けはありますか?

https://github.com/danro/jquery-easing/blob/master/jquery.easing.js

4

5 に答える 5

6

JavaScript と Python の両方で/=、ほぼ同じ意味を持つ「拡張代入」演算子です。

JS で:

var i = 10;
i /= 2;

…は次と同等です:

var i = 10;
i = i / 2;

そして、Python では:

i = 10
i /= 2

... 同様に同等です (完全に同じではありませんが、数値としては十分に近いです)。

i = 10
i = i / 2

ただし、非常に大きな違いが 1 つあります。

JavaScript では、割り当ては式です。値があり、その値が変数に割り当てられる値です。そう:

var i = 10;
var j = i /= 2;

… は次とほぼ同等です。

var i = 10;
i /= 2;
var j = i;

Python では、代入はステートメントです。値がなく、式では使用できません。そう:

i = 10
j = i /= 2

… を発生させSyntaxErrorます。


式の途中で代入 (拡張またはその他) を使用するコードを移植するには、通常、その式を複数の行に分割するか、代入を必要としないように式を書き直す方法を見つける必要があります。(しかし、多くの場合、それは悪いことではありません。元の式はいずれにしてもあまり読みにくいからです…)

たとえば、JS がオペランドを左から右に評価すると仮定します (これが保証されているかどうかはわかりません)。

def easeInQuad(x, t, b, c, d):
    t /= d
    return c*t*t+b

より一般的には、次のようにします。

old_t = t
t /= d

そして、tその前のすべてのインスタンスt/=dをに置き換え、以降old_tのすべてのインスタンスをそのままにしますt/=d。幸いなことに、この場合、以前のインスタンスがないため、そのようなold_tものは必要ありません。

考えてみればt、次のいずれかの方法で、1 行で、はるかに読みやすく、変更することなく同じ効果を簡単に得ることができます。

return c * (t/d) * (t/d) + b
return c * (t/d)**2 + b
return c * t*t / d*d + b

C で考える人は、これらすべてが「遅すぎる」とすぐに文句を言うでしょう。結局、1 つ目は余分な除算を行い、2 つ目は乗算ではなく累乗を行い、3 つ目は 1 回ではなく 2 回の乗算を行います。恐怖!

もちろん、いつでも一時変数を使用できます。

t_over_d = t/d
return c * t_over_d * t_over_d + b

…しかし、繰り返しますが、C プログラマーにとっては、貴重なレジスターを使い果たしていることを意味します。確かに、たとえば 1985 年以降に作成されたすべてのコンパイラは、それtが現れるとすぐにそれを検出しt_over_d、同じレジスタを再利用しますが、可能であれば、特にいくつかのキーストロークも節約できる場合は、強制的にレジスタを再利用しないでください。

JS や Python では、乗算のコストは、関数の呼び出しやバイトコードの解釈などのコストに比べてごくわずかなので、気付かないほどです。一方、ローカル変数を再バインドするコスト (特に V8 スタイルまたは PyPy スタイルの JIT インタープリター) は、名前のない一時的な結果を渡すコストよりもはるかに高くなる可能性があります。

したがって、これは誤った「最適化」のパラダイムケースであり、コードを理解するのをはるかに難しくし、おそらく速度を上げる代わりに遅くし、とにかく最適化する価値のあるボトルネックにはなり得ない領域にあります。


gnibbler が、JavaScript が実際にこの評価順序を保証するかどうかという問題を提起したので…</p>

まず、JavaScript は事実上、「Firefox が行うこと」(および「Spidermonkey が行うこと」) として定義されますが、それは同じである必要があります。 、 右?)。しかし、ECMAScript標準によって定義されており、すべての JS 実装 (名前にもかかわらず) がリップ サービスを支払うのはこれらの標準であり、ECMAScript 5.1 がすべての実装が準拠する標準であると偽ることができます (これは、「すべての実装が" は「オペラ」を意味します)。ここで見つけることができます。

したがって、ES 5.1 では: 11.5 乗法演算子は の結果が の(t/=d)前に評価されることを保証しt11.13.2 複合代入は評価t/=dが終了する前に の値を設定することを保証しtます。(「評価」が何を意味し、何GetValueSetValue意味するかを読む必要がありますが、これは本当に保証されていると確信しています。)

于 2013-03-20T22:24:16.580 に答える
1

/=拡張代入演算子です。t /= dと同じt = t / dです。+=、、-=そして*=また存在します。

于 2013-03-20T22:17:21.650 に答える
1

まあ、それはと同じような省略形の演算子ですが、+=除算を追加する代わりに。ロングフォームはこちら

t = t / d
于 2013-03-20T22:17:49.357 に答える
1
c*(t/=d)*t + b;

に等しい

t /= d            # or t = t / d
c * t * t + b

Pythonは式内で代入できないため

tdが両方ともint/の場合long、これは Python2 では切り捨てられた除算になることに注意してください。

同様easeOutQuad

def easeOutQuad (x, t, b, c, d):
    t /= d
    return -c * t * (t - 2) + b
于 2013-03-20T22:17:52.113 に答える
0

分割して割り当てます。

>>> p = 6
>>> p /= 2
>>> p
3
于 2013-03-20T22:16:59.980 に答える