I have a loop that changes the background color of a page, but the transitions are just too rough. I was wondering if there's a way to apply an effect to smooth them. Something like "ease" when using CSS.
let x = document.body;
let color = ["blue", "green", "yellow", "red"];
setInterval(function() {
for(let y = 0; y < 4; y ){
x.style.backgroundColor = color[Math.floor(Math.random() * 3)];
}
}, 1000);
body {
background-color: black;
}
CodePudding user response:
Use css transition
property
CSS
let x = document.body;
let color = ["blue", "green", "yellow", "red"];
setInterval(function() {
for(let y = 0; y < 4; y ){
x.style.backgroundColor = color[Math.floor(Math.random() * 3)];
}
}, 1000);
body {
background-color: black;
transition: background-color 2s;
}
JS
let x = document.body;
let color = ["blue", "green", "yellow", "red"];
setInterval(function() {
for(let y = 0; y < 4; y ){
x.style.backgroundColor = color[Math.floor(Math.random() * 3)];
x.style.transition = 'background-color 2s';
}
}, 1000);
body {
background-color: black;
}
CodePudding user response:
CSS transition (as in Pablo's answer) is likely the easiest solution.
However, the colors get a grey-ish tint during the transition. This is a side-effect of RGB color interpolation. Relevant blog article explaining the color interpolations in detail: here.
An alternative solution is to use a different color interpolation algorithm in javascript.
d3-interpolate
javascript library provides a variety of color interpolation algorithm.
The snippet below shows how to smoothly transition colors using d3.interpolateLab
function.
let x = d3.select('body');
let color = ["blue", "green", "yellow", "red"];
setInterval(function() {
for(let y = 0; y < 4; y ){
let currentColor = x.style('background-color')
x.transition()
.duration(800)
.styleTween('background-color'
, function() {
return d3.interpolateLab(
currentColor
, color[Math.floor(Math.random() * 3)]
)
})
}
}, 1000);
body {
background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>