1

小さなJavaScriptアニメーションを実行して、小さなものが正弦波に沿って移動できることを期待していdivます。今のところ、水平パスは正常に機能します(直線だけ)。Y軸の数式が間違っていることはほぼ間違いありません。私は見つけたいくつかの例でそれを修正しようとしましたが、それらのどれも私のために働きませんでした。私が試したすべての可能性で、Y軸は無視され、小さなボックスは水平方向に直線的に移動します。

どうすればこれを修正できるので、動きは正弦波に沿って進みますか?jQueryまたはhtml5を使用すると簡単に実行できることはわかっていますが、元のコードの何が問題になっているのか疑問に思いました...可能であればこれを修正したいと思います。

function animate() {
    xnow = item.style.left;
    item.style.left = parseInt(xnow)+1+'px';
    ynow = item.style.top;
    item.style.top = ynow + (Math.sin((2*Math.PI*xnow)/document.width))*document.heigth;
    setTimeout(animate,20); 
}

ここに完全なコード: JSFiddle

4

4 に答える 4

7

sin関数はy=a * sin(b * x)+ cの形式です。ここで、cは関数のy中点(または関数が振動する水平線)です。ここで、aは振幅(最大y-y = cからのオフセット)およびbは周期(波ごとのx = 2 * piセグメントの数)です。

それを考えると、正弦波が-aから+ aに振動することがわかっているので、オフセット(c)は1)一定であり、2)上限と下限の中間である必要があります。これには使用できます

c = document.height / 2;

オブジェクトが画面全体をトラバースする場合、振幅はcと同じ値になります。テストすると、これでページの下部を通過することがわかるので、90%にします。

a = 0.9 * c;

ページ全体で1の期間、bにxに2*piの分数になるような係数を掛ける必要があります。この場合

b = 2*Math.PI/document.width;

各反復で、の値を取得する必要はありません。ynowこれはの関数ですxnow。あなたはの線に沿って何かをすることができます

xnow = parseInt(item.top.left) + 5;

次に、で新しいyを計算します

ynow = c + a * Math.sin(b * xnow);

次に、アイテムのスタイルを設定します。

item.style.left = xnow + 'px';

item.style.top = ynow + 'px';

不明な点があれば教えてください。よろしく。

于 2012-11-30T15:56:34.330 に答える
7

コードにいくつか問題があります。

  • xnowこの形式の文字列が含まれています。###px乗算することはできないため、呼び出しで使用parseInt()しますMath.sin()
  • 同じことがあなたのコードがつかむためにも当てはまりますynow、それは必要parseInt()です。
  • 他の(グローバル)変数を使用して、x座標とy座標を数値として格納することをお勧めします。pxまた、div要素の座標を更新するときに追加します。
  • (整数のみを含む)を乗算2*Math.PIすると、関数は常にを返します。したがって、正弦波のような動きは得られません。完全な正弦波のような動きをするために使用したいxステップの数で割る必要がありますxnowsin()0xnow
  • Math.sin()-1から+1の間の値を返すため、(より明確な)効果を確認するには、振幅を掛ける必要があります。

設計どおりに維持するには、次のようになります(完全な正弦波を実行するには、50回のx移動ステップを実行し、10ピクセルの振幅を使用します)。

function animate() {
    xnow = parseInt(item.style.left);
    item.style.left = (xnow+1)+'px';
    ynow = parseInt(item.style.top);
    item.style.top = (ynow+Math.sin(2*Math.PI*(xnow/50))*10) + "px";
    setTimeout(animate,20);
}

前述のように、(parseInt()常に使用するのではなく)値を含むいくつかのグローバル変数を使用する方がはるかに優れています

更新されたJSFiddleの例を参照してください。

于 2012-11-30T15:20:36.903 に答える
2

parseInt()で使用する必要がありますxnow。また、正しくフォーマットされた文字列にするために、数値の末尾に「px」を追加する必要があります。

このコードは機能します:

function animate() {
  xnow = parseInt(item.style.left);
  item.style.left = xnow+1+'px';
  item.style.top = 200 + (Math.sin((2*Math.PI*xnow)/200))*document.height+'px';
  setTimeout(animate,20); 
}
于 2012-11-30T15:38:23.180 に答える
1

いくつかのエラーがあります:

  • heightスペルミス
  • xnowサインを取る前にintとして解析します
  • 追加する前にintとして解析ynowします(実際には必要ありませんが、以下を参照してください)。
  • 割り当ての最後に追加"px"するitem.style.top
  • 方程式はいくつかの微調整を使用することができます:

最初にそれを試してみることをお勧め(400 + Math.sin(2*Math.PI*xnow/document.width) * 200) + "px"します。は400、正弦波の基になる横軸です。定数の代わりに使用ynowすると、累積効果が得られます(波は意図したよりもはるかに高くなるか、横軸が時間とともに変化します)。

document.width1つの完全な期間の幅です。これ200はピーク振幅です(水平からピークまでの距離-document.heightボックスを画面から両方向に押し出します)。現在の関数の代わりにこの関数をプラグインすると、数字をいじることができます。

function animate() {
  xnow = parseInt(item.style.left);
  item.style.left = xnow+1+'px';
  item.style.top = (400 + Math.sin(2*Math.PI*xnow/document.width) * 200) + "px";
  setTimeout(animate,20); 
}
于 2012-11-30T15:34:24.220 に答える