Reputation: 496
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
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()
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
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
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
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