2012-11-30 93 views
1

我正在做一個小型的JavaScript動畫,希望div可以沿着正弦波移動,而目前水平路徑正常工作(只是直線)。我幾乎可以肯定,我的Y軸的數學公式是錯誤的。我試圖用我找到的一些例子來糾正它,但是他們都沒有爲我工作。在我嘗試的所有可能性中,Y軸被忽略,小盒子在水平方向上直線移動。不應該這個JavaScript動畫產生正弦波運動?

我該如何解決這個問題,讓運動沿着正弦波走?我知道使用jQuery或使用html 5可以更簡單,但我只是想知道我的原始代碼中有什麼問題......如果可能,我寧願修復此問題。

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

+0

這並不能解決您的問題,但'height'拼寫錯誤爲'heigth',如果您記錄'item.style.top'的輸出,則該值始終爲400px。 – Chase

+0

ops ...謝謝:-)我拼錯了。無論如何,這是我不明白,爲什麼價值不會改變... –

+0

https://developer.mozilla.org/en-US/docs/DOM/document.width – Andreas

回答

7

我看到一些問題與您的代碼:

  • xnow包含此格式的字符串:###px你不能繁殖,所以使用parseInt()在致電Math.sin()
  • 您的代碼同樣適用於ynow,它需要parseInt()
  • 更好的是使用其他(全局)變量將x和y座標存儲爲數字。當你更新div元素的座標時,添加px
  • 當您將2*Math.PIxnow(僅包含整數)相乘時,sin()函數將始終返回0。所以你不會得到一個正弦運動。你需要用你想用來完成正弦運動的x步數除xnow
  • Math.sin()返回一個介於-1和+1之間的值,所以你需要乘以一個幅度來看一個(更清晰)的效果。

爲了保持它就像你設計的,它會成爲像這樣(採用50×運動的步驟做一個完整的正弦波,並使用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()

請參閱我的updated JSFiddle example

+0

不知道我是否理解你的最後一點。你的意思是這樣嗎?:(Math.sin(2 * Math.PI *(xnow/parseInt(document.body.clientWidth)))* document.height' –

1

有幾個誤區:

  • height是增加它(雖然它不是實際需要之前採取正弦
  • 解析ynow爲int之前拼錯
  • 解析xnow爲int,看)
  • "px"添加到作業末尾item.style.top
  • 等式ld使用一些調整:

我建議從(400 + Math.sin(2*Math.PI*xnow/document.width) * 200) + "px"開始,然後玩弄它。 400是基於正弦波的橫軸。如果您使用ynow而不是常數,則會得到累積效果(波形將比您想要的要高得多,或者橫軸會隨時間而改變)。

document.width是一個整個週期的寬度。 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); 
} 
2

您需要在xnow使用parseInt()。您還需要將數字「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); 
} 
7

甲sin函數是Y = A * SIN(B * X)+ c,其中c是函數的y中點的形式(或水平函數振盪的線),其中a是振幅(來自y = c的最大y偏移)並且b是週期(每個波的x = 2 * pi片段的數量)。我們知道我們的偏移(c)應該是恆定的,並且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';

讓我知道,如果有什麼不清楚。問候。