Javascript requestAnimationFrame不';I don’我没有按预期工作

Javascript requestAnimationFrame不';I don’我没有按预期工作,javascript,requestanimationframe,Javascript,Requestanimationframe,我的剧本有点问题,我不明白怎么回事 这是: 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) }

我的剧本有点问题,我不明白怎么回事

这是:

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)
let angle=0
设乘数=0.01
函数raf(){
如果(角度>=1 | |角度<0){
乘数=-乘数
}
角度=角度+倍增器
如果(角度<0)控制台日志(角度)
请求动画帧(raf)
}
请求动画帧(raf)
目的是将角度提高0.01,当其达到1时,应减小到0,然后再次提高到1

我有时会得到一个负角度(-8.etc),我不明白为什么(console.log应该显示这个)

我为此做了一支笔:

谢谢大家!


Mourtaza.

您遇到了一个不幸的浮点数学问题

0.94 - 0.01
0.9299999999999999
当你减去0.01的次数越来越多时,这些错误会变得越来越复杂。因此,在最后,代码不是执行0.01-0.01,而是执行以下操作

0.009999999999999247 - 0.01 

这有点负面。如果需要这样的边界,可以使用Math.max(0,yourValue)和Math.min(1,yourValue)来绑定最小值和最大值。

这是一个浮点问题

var a=0;
对于(变量i=0;i<100;++i){
a+=0.01;
} 
控制台日志(a);
对于(变量i=0;i<101;++i){
a-=0.01;
} 
控制台日志(a);
a+=0.01;

控制台日志(a)您没有收到
-8
,您收到的是
-8.xxxxxx E-17
。请注意结尾处的
e-17
。这是科学记数法,所以您的数字实际上是
-0.0000000000000000 8xxxx
。您可以使用
angle.toFixed(20)
查看不带科学符号的浮点数。数字是要显示的小数位数

如果只按
0.01
增减,为什么会得到这么小的数字?请问。这是因为浮点数不精确,因为小数不可能“保存到底”,而不像整数。例如,想象一下有无限个小数的
1/3
。在这里,您可以阅读有关JavaScript和浮点精度的更多信息:

另一个问题是有一个负角度(这么小,但仍然是负的,尽管你实际上检查了负角度)。这是因为在增加/减少之前检查负角度,所以如果乘数为负数,角度为,比方说,
0.0001(由于浮点精度问题),它仍然高于零,所以乘数仍然为负,但实际上大于角度,因此,当应用乘数时,角度将为负

我可以想一个办法来解决这个问题:

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)
let angle=0
设乘数=0.01
函数raf(){
角度=角度+倍增器;
如果(角度>1 | |角度<0){
乘数=-乘数

角度=角度离题:角度的不同方法。作为时间的函数,而不是增量变化

let start=Date.now();
让速度=1/10000;//每10秒1次
函数raf(){
设v=(Date.now()-start)*速度;
让角度=v&1?1-v%1:v%1;
document.body.textContent=“角度:”+Angle.toFixed(3);
请求动画帧(raf);
}
//或者加些糖:
速度=180/10000;
函数raf(){
设minAngle=-90,maxAngle=90,delta=maxAngle-minAngle;
设v=(Date.now()-start)*速度;
设角度=(v/delta)&1?最大角度-v%delta:minAngle+v%delta;
document.body.textContent=“角度:”+angle.toFixed(3);
请求动画帧(raf);
}

raf();
谢谢!我理解这个问题,你的解决方案也很有效!:)@Mourtazag很高兴它能帮上忙:P
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)