Kshitij Shah
Kshitij Shah

Reputation: 39

Link Background Color to Scroll Position

I want to link the background color of the body element to the scroll position such that when the page is scrolled all the way to the top its color 1, but then but then when its scrolled past screen.height, its a completely different color, but I want it to be interpolated such that when it is half-way scrolled, the color is only half-way transitioned. So far, I have it linked to

$(window).scrollTop() > screen.height 

and

$(window).scrollTop() < screen.height 

to add and remove a class that changes background-color but I want it to be dependent on scroll position not just to trigger the event, but rather smoothly animate it so fast scrolling transitions quickly, slow scrolling transitions it slowly.

Upvotes: 0

Views: 489

Answers (3)

oldboy
oldboy

Reputation: 5954

A much, much easier way to accomplish what you're looking to do is by simply using a gradient as the background.

There is absolutely zero need for any JS here, which will only slow down the page.

body {
  height: 600vh;
  background: linear-gradient(#2E0854, #EE3B3B)
}

Is there a particular reason you want to do this with JS?

Upvotes: 0

rafaelcastrocouto
rafaelcastrocouto

Reputation: 12161

var randomHex = function () {
  return (parseInt(Math.random()*16)).toString(16) || '0';
};
var randomColor = function () {
  return '#'+randomHex()+randomHex()+randomHex();
};
var randomGradient = function () {
  $('.longContent').css('background', 'linear-gradient(0.5turn, #222, '+randomColor()+','+randomColor()+')');
};
$(window).on('load', randomGradient);
body {
  margin: 0;
}
.longContent {
  height: 400vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>

<div class="longContent"></div>

Upvotes: 0

P.S.
P.S.

Reputation: 16384

One of possible solutions is to bind a rgb color to current height, count the step and set new rgb color depending on current position of scrolling. Here I've created the simplest case - black and white transition:

const step = 255 / $('#wrapper').height();
const multiplier = Math.round( 
  $('#wrapper').height() / 
  $('#wrapper').parent().height()
);

$('body').scroll(() => {
  const currentStyle = $('body').css('backgroundColor');
  const rgbValues = currentStyle.substring(
    currentStyle.lastIndexOf("(") + 1, 
    currentStyle.lastIndexOf(")")
  );
  const scrolled = $('body').scrollTop();
  const newValue = step * scrolled * multiplier;
  $('#wrapper').css('background-color', `rgb(${newValue}, ${newValue}, ${newValue})`);
});
html,
body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  background-color: rgb(0, 0, 0);
}

#wrapper {
  height: 200%;
  width: 100%;
  overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<section id="wrapper"></section>

And here is another one example with transition from yellow to blue:

const step = 255 / $('#wrapper').height();
const multiplier = Math.round( 
  $('#wrapper').height() / 
  $('#wrapper').parent().height()
);

$('body').scroll(() => {
  const currentStyle = $('body').css('backgroundColor');
  const rgbValues = currentStyle.substring(
    currentStyle.lastIndexOf("(") + 1, 
    currentStyle.lastIndexOf(")")
  );
  const scrolled = $('body').scrollTop();
  const newValue = step * scrolled * multiplier;
  $('#wrapper').css('background-color', `rgb(${255 - newValue}, ${255 - newValue}, ${newValue})`);
});
html,
body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  background-color: rgb(255, 255, 0);
}

#wrapper {
  height: 200%;
  width: 100%;
  overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<section id="wrapper"></section>

Upvotes: 1

Related Questions