Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change color when user has scrolled down enough and then back

I have several divs arranged vertically one on top of the other which from here on out I will call panels. Each panel has the width and height of the viewport. All panels have the same background color at all times. Initially, that color is black.

Every other panel is empty, and acts as a gap between panels that actually have content. The order is like this:

  1. Content
  2. No content
  3. Content
  4. No content
  5. Content

What I want to do is make it so that when a user has scrolled down enough for a panel with content to be out of view, the color should change from black to white. Then, once they have scrolled far enough for the second panel with content to be out of view, it should change back.

This is the part I cannot figure out. I have a working demo with my code so far:

$(document).scroll(function() {

  var viewportHeight = $("html").outerHeight();
  var currentY = $(document).scrollTop();
  if (currentY % viewportHeight != 0) {
    lighten();
  } else {
    darken();
  }
});

function darken() {
  $("body").css("background-color", "black");
  $(".panel.content").css("color", "white");
}

function lighten() {
  $("body").css("background-color", "white");
  $(".panel.content").css("color", "black");
}
html,
body,
.panel {
  width: 100%;
  height: 100%;
}

body {
  background-color: black;
  overflow-y: visible;
  overflow-x: hidden;
  transition: background-color 500ms linear;
}

.panel {
  border: 2px solid red;
}

.content {
  color: white;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<body>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
</body>

As you can see, my code is a ways off from achieving the desired result. Not only is the order wrong, the main problem is that it only triggers when the user is at the exact Y for the change to happen.

The order should be:

  1. Black
  2. White
  3. White
  4. Black
  5. Black
  6. White
  7. White
  8. Black
  9. Black

etc.

How do I do this?

like image 713
Thsise Faek Avatar asked Jul 30 '17 22:07

Thsise Faek


1 Answers

$(document).scroll(function() {

  var viewportHeight = $("html").outerHeight();
  var currentY = $(document).scrollTop();
  var panelNumber = Math.floor(currentY / viewportHeight);
  if (panelNumber % 4 === 1 || panelNumber % 4 === 2) {
    lighten();
  } else {
    darken();
  }
});

function darken() {
  $("body").css("background-color", "black");
  $(".panel.content").css("color", "white");
}

function lighten() {
  $("body").css("background-color", "white");
  $(".panel.content").css("color", "black");
}
html,
body,
.panel {
  width: 100%;
  height: 100%;
}

body {
  background-color: black;
  overflow-y: visible;
  overflow-x: hidden;
  transition: background-color 500ms linear;
}

.panel {
  border: 2px solid red;
}

.content {
  color: white;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
  <div class="panel content">
    <h2> CONTENT </h2>
  </div>
  <div class="panel blank">
  </div>
</body>

Not only is the order wrong, the main problem is that it only triggers when the user is at the exact Y for the change to happen.

yes..that is right. currentY % viewportHeight != 0 will not work. Scrolling is not smooth. Pulling scrollbar down may result in change of 10000 px/sec, but browser renders 60fps which means your currentY (scroll-y) will increase by 150px every frame (your are expecting a change of 1px). So if your code contains if(currentY === 100){} definitely not going to work. currentY may have values like 0,50,80,99,120,....

It should be clear currentY % viewportHeight != x is not so much different.

So if(0<currentY<500) will be be better option.

Now suppose viewportHeight = 500. We can get panelNumber = Math.floor(currentY/viewportHeight) (=>0,1,2,3,4,5...)

(Not clear from your question) Suppose you want to have panel: 0 =>black, 1=>white, 2=>white, 3=>black, 4=>black ... you can get black by panelNumber%4==0 || panelNumber%4==3.

[please change accordingly if you want something different]

like image 136
amit77309 Avatar answered Sep 30 '22 05:09

amit77309