簡體   English   中英

requestAnimationFrame無法正常工作

[英]requestAnimationFrame doesn't work as expected

我的腳本有問題,我不明白發生了什么。

這里是 :

let angle = 0
let multiplier = .01

function raf() {

  if(angle >= 1 || angle < 0) {
    multiplier = - multiplier 
  }

  angle = angle + multiplier

  if(angle < 0) console.log(angle)

  requestAnimationFrame(raf)
}

requestAnimationFrame(raf)

目的是將角度增加0.01,當角度達到1時,應減少到0,然后再次增加到1。

有時我會遇到一個負角(-8.etc),但我不明白為什么(console.log應該顯示出來)。

我為此寫了一支筆: https : //codepen.io/mourtazag/pen/QvjjLy

謝謝你們 !

Mourtaza。

您遇到了不幸的浮點數學運算的情況

0.94 - 0.01
0.9299999999999999

這些錯誤會隨着您越來越多地減去0.01而變得更加復雜,因此最終不會執行0.01-0.01(該操作會得到0),而是執行類似

0.009999999999999247 - 0.01 

這是負面的。 如果您需要像這樣限制邊界,則可能只用Math.max(0,yourValue)和Math.min(1,yourValue)限制最小值和最大值。

這是一個浮點問題

 var a = 0; for (var i = 0; i < 100; ++i) { a += 0.01; } console.log(a); for (var i = 0; i < 101; ++i) { a -= 0.01; } console.log(a); a += 0.01; console.log(a); 

版畫

1.0000000000000007
-0.010000000000000087
-8.673617379884035e-17

考慮使用整數或時鍾,並從中計算角度

您不會收到-8 ,您會收到-8.XXXXXXe-17 請注意最后的e-17 這是科學計數法,因此您的電話號碼實際上是-0.00000000000000008XXXXX 您可以使用angle.toFixed(20)來查看浮點數而無需科學記數法。 該數字是您要顯示的小數位數。

如果僅增加和減少0.01為什么會得到這么小的數字? 請問。 發生這種情況是因為浮點數不准確,因為不可能像整數一樣將小數點“保存到末尾”。 例如,假設1/3具有無限數量的小數。 在這里,您可以了解有關JavaScript和浮點精度的更多信息: 處理Javascript中的浮點精度

另一個問題是有一個負角(雖然您實際上檢查了負角,但角度很小,但仍然是負數)。 發生這種情況是因為您在增加/減小之前先檢查了負角,因此,如果乘數為負,並且角度為0.0001whatever (因為浮點精度問題),那么它仍然大於零,因此乘數仍然為負,但實際上大於角度,因此當應用乘數時,角度將為負。

我可以想到這種方式來解決這個問題:

let angle = 0
let multiplier = .01

function raf() {

  angle = angle+multiplier;

  if(angle > 1 || angle < 0) {
    multiplier = -multiplier 
    angle = angle<0?0:1;
  }
  console.log(angle.toFixed(20))

  requestAnimationFrame(raf)
}

requestAnimationFrame(raf)

使用此工具,您可以在加工后檢查角度是否在極限范圍內,從而可以解決精度問題: https : //codepen.io/anon/pen/eWppGy

另一種方法是使用整數(因為如上所述,因為它們不存在精度問題),並且在使用整數時將角度除以100,如下所示:

let angle = 0
let multiplier = 1

function raf() {

  angle = angle+multiplier;

  if(angle >= 100 || angle <= 0) {
    multiplier = -multiplier;
    angle = angle<=0?0:100;
  }
  console.log(angle/100)

  requestAnimationFrame(raf)
}

requestAnimationFrame(raf)

筆: https : //codepen.io/anon/pen/XRmmVq

離題:對角度的另一種方法。 作為經過時間的函數,而不是增量變化。

 let start = Date.now(); let speed = 1 / 10000; //1 in every 10 seconds function raf() { let v = (Date.now() - start) * speed; let angle = v&1? 1-v%1: v%1; document.body.textContent = "Angle: " + angle.toFixed(3); requestAnimationFrame(raf); } //or with some sugar: speed = 180/10000; function raf() { let minAngle = -90, maxAngle = 90, delta = maxAngle - minAngle; let v = (Date.now() - start) * speed; let angle = (v/delta)&1? maxAngle-v%delta: minAngle + v%delta; document.body.textContent = "angle: " + angle.toFixed(3); requestAnimationFrame(raf); } raf(); 

或加糖 當我們不討論從01的范圍時的整個計算

 let start = Date.now(); let speed = 180 / 10000; let minAngle = -30, maxAngle = 45; function raf() { let delta = maxAngle - minAngle; let v = (Date.now() - start) * speed; let backwards = (v/delta)&1; let angle = backwards? maxAngle - v%delta: minAngle + v%delta; document.body.textContent = "angle: "+ angle.toFixed(3) +", direction: " + (backwards? "backward": "forward"); requestAnimationFrame(raf); } raf(); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM