1

I am trying to reduce opacity with JavaScript. But the problem is that 'if' condition is always false therefor the opacity is getting 0. Please can anyone explain why this is happening and the correct solution.

var opacity = 1;
var decrement = 0.01;
var id = setInterval(frame, 10);
function frame(){
    if (opacity == 0.4) //It is always false..
    {
        clearInterval(id);//Not able to clear Interval
    }
    else
    {
        opacity = opacity-decrement;
        document.getElementsByClassName('menu_bar')[0].style.backgroundColor='rgba(66,64,61,'+opacity+')';
    }
}
Teemu
  • 22,918
  • 7
  • 53
  • 106

4 Answers4

2
 if(Math.abs(opacity - 0.4) < 0.01) {

Floating point math is "broken", therefore you have to be fault tolerant.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
1

Instead of using opacity == 0.4 in your code, try using opacity < 0.5 or opacity <= 0.4 as fractions are not very reliable in javascript.

Try running 1-0.1-0.1-0.1-0.1-0.1-0.1 (The math that happens before your == 0.4 check should return true) in your console to see what I mean.

Aayush Sharma
  • 779
  • 4
  • 20
  • 1
    It's not just Javascript, it's pretty much every programming language since the invention of "floating point" representation. – IMSoP Jul 09 '18 at 09:22
1

As mentioned, the floating point math is broke.

A simple fix is to use integers and divide the end result with 100.

That will also avoid any extra Math.abs, or calc, at every interval.

Stack snippet

var opacity = 100;
var decrement = 1;
var id = setInterval(frame, 10);

function frame() {
  if (opacity == 40)
  {
    clearInterval(id);
  } else {
    opacity = opacity - decrement;
    //document.getElementsByClassName('menu_bar')[0].style.backgroundColor='rgba(66,64,61,'+opacity/100+')';
    document.body.style.backgroundColor='rgba(66,64,61,'+opacity/100+')';
  }
}
Asons
  • 84,923
  • 12
  • 110
  • 165
0
You can use opacity.toFixed(2) to restrict the decimal digits to 2, this will sole the issue

var opacity = 1;
var decrement = 0.01;
var id = setInterval(frame, 10);
function frame(){
    if (opacity.toFixed(2) == 0.40) //It is always false..
    {
        console.log("Cleared");
        clearInterval(id);//Not able to clear Interval
    }
    else
    {
        opacity = opacity-decrement;
       // document.getElementsByClassName('menu_bar')[0].style.backgroundColor='rgba(66,64,61,'+opacity+')';
    }
}
Amaldev ps
  • 257
  • 2
  • 12