junior
junior

Reputation: 496

Manipulate colors through a loop in Javascript

I am trying to create a for loop to manipulate the background of a page in Javascript, I would like to create a fade in effect from rgb(0;0;0) to rgb(255;0;0)

But I got very stuck in the loop, I didn't find a way to pass a variable to the rgb() function.

Here is my Javascript code:

var r;

function change() {
  var doc = document.body;
  var color;

  for(r = 0; r < 256; r++){
    color = rgb(r; 0; 0);
    doc.style.backgroundColor = color;
  }
}

setInterval(change, 100);

Upvotes: 3

Views: 1388

Answers (4)

Ajay Thomas
Ajay Thomas

Reputation: 101

For creating a smooth 60fps transition, it's better to use requestAnimationFrame instead of setInterval.

By calling setInterval(change, 100), the background color will only be updated once every 100ms. Most devices refresh their screens 60 times a second. So, in order to get a smooth transition, you need to update the background color once every 16.67ms (1second/60). But, passing 16.67 to setInterval is not a reliable way to do this. This is where requestAnimationFrame comes in. When you put some code inside a requestAnimationFrame callback, the browser makes sure that that code gets executed just before the next repaint.

These are some great resources to learn more about this:

Window.requestAnimationFrame()

Rendering Performance

Optimize JavaScript Execution

Jake Archibald: In The Loop - JSConf.Asia

This recursive change function takes a callback and the value of red and calls itself using requestAnimationFrame till the value of red reaches 255. If you have passed a callback, it gets fired after the transition.

function change(callback, r) {
  r = r === undefined ? 0 : r;
  if (r >= 0 && r < 256) {
    const color = `rgb(${r}, 0, 0)`;
    requestAnimationFrame(() => {
      document.body.style.backgroundColor = color;
      change(callback, r + 1);
    });
  } else {
    callback && callback();
  }
}

change(() => {
  alert('Transition complete');
});

Also, if you're using setInterval, don't forget to clear it using clearInterval once the transition is complete.

WindowOrWorkerGlobalScope.setInterval()

WindowOrWorkerGlobalScope.clearInterval()

Upvotes: 1

GirkovArpa
GirkovArpa

Reputation: 4912

This fade function uses an async loop to gradually change the red component of the background color from 0 to 255:

const fade = async () => {
  const getRed = () => +window.getComputedStyle(document.body, null)
    .backgroundColor
    .match(/\d+/)[0];
  while (getRed() < 255) {
    document.body.style.backgroundColor = `rgb(${getRed() + 1}, 0, 0)`;
    await new Promise(resolve => setTimeout(resolve, 100));
  }
}
fade();
body {
  background-color: rgb(0, 0, 0);
}

Upvotes: 0

sonEtLumiere
sonEtLumiere

Reputation: 4562

Try this

var r = 0;

function change() {
    color = 'rgb(' + r +', 0, 0)';
    document.body.style.backgroundColor = color;
    r < 256 ? r++ : 0;
}

setInterval(change, 100);

Upvotes: 2

Abito Prakash
Abito Prakash

Reputation: 4770

For setting color, you can use template literals, as backgroundColor property needs to be a string

color = `rgb(${r}, 0, 0)`;
doc.style.backgroundColor = color;

Upvotes: 2

Related Questions