2

So I have a set of elements called .project-slide, one after the other. Some of these will have the .colour-change class, IF they do have this class they will change the background colour of the .background element when they come into view. This is what I've got so far: https://codepen.io/neal_fletcher/pen/eGmmvJ

But I'm looking to achieve something like this: http://studio.institute/clients/nike/

Scroll through the page to see the background change. So in my case what I'd want is that when a .colour-change was coming into view it would slowly animate the opacity in of the .background element, then slowly animate the opacity out as I scroll past it (animating on scroll that is).

Any suggestions on how I could achieve that would be greatly appreciated!

HTML:

    <div class="project-slide fullscreen">
        SLIDE ONE
    </div>

    <div class="project-slide fullscreen">
        SLIDE TWO
    </div>

    <div class="project-slide fullscreen colour-change" data-bg="#EA8D02">
        SLIDE THREE
    </div>

<div class="project-slide fullscreen">
        SLIDE TWO
    </div>

<div class="project-slide fullscreen colour-change" data-bg="#cccccc">
        SLIDE THREE
    </div>

</div>

jQuery:

$(window).on('scroll', function () {

    $('.project-slide').each(function() {

        if ($(window).scrollTop() >= $(this).offset().top - ($(window).height() / 2)) {
            if($(this).hasClass('colour-change')) {
              var bgCol = $(this).attr('data-bg');

              $('.background').css('background-color', bgCol);

            } else {

            }
        } else {

        }

    });

}); 
user1374796
  • 1,544
  • 13
  • 46
  • 76

2 Answers2

0
  • Set some data-gb-color with RGB values like 255,0,0
  • Calculate the currently tracked element in-viewport-height.
  • than get the 0..1 value of the inViewport element height and use it as the Alpha channel for the RGB color:

/**
 * inViewport jQuery plugin by Roko C.B.
 * http://stackoverflow.com/a/26831113/383904
 * Returns a callback function with an argument holding
 * the current amount of px an element is visible in viewport
 * (The min returned value is 0 (element outside of viewport)
 */
;
(function($, win) {
  $.fn.inViewport = function(cb) {
    return this.each(function(i, el) {
      function visPx() {
        var elH = $(el).outerHeight(),
          H = $(win).height(),
          r = el.getBoundingClientRect(),
          t = r.top,
          b = r.bottom;
        return cb.call(el, Math.max(0, t > 0 ? Math.min(elH, H - t) : (b < H ? b : H)), H);
      }
      visPx();
      $(win).on("resize scroll", visPx);
    });
  };
}(jQuery, window));



// OK. Let's do it
var $wrap = $(".background");

$("[data-bg-color]").inViewport(function(px, winH) {
  var opacity = (px - winH) / winH + 1;
  if (opacity <= 0) return; // Ignore if value is 0
  $wrap.css({background: "rgba(" + this.dataset.bgColor + ", " + opacity + ")"});
});
/*QuickReset*/*{margin:0;box-sizing:border-box;}html,body{height:100%;font:14px/1.4 sans-serif;}

.project-slide {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.project-slide h2 {
  font-weight: 100;
  font-size: 10vw;
}
<div class="project-slides-wrap background">

  <div class="project-slide">
    <h2>when in trouble...</h2>
  </div>

  <div class="project-slide" data-bg-color="0,200,255">
    <h2>real trouble...</h2>
  </div>

  <div class="project-slide">
    <h2>ask...</h2>
  </div>

  <div class="project-slide" data-bg-color="244,128,36">
    <h2>stack<b>overflow</b></h2>
  </div>

</div>


<script src="//code.jquery.com/jquery-3.1.0.js"></script>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
0

Looks like that effect is using two fixed divs so if you need something simple like that you can do it like this:

But if you need something more complicated use @Roko's answer.

var fixed = $(".fixed");
var fixed2 = $(".fixed2");
$( window ).scroll(function() {
    var top = $( window ).scrollTop();
    var opacity = (top)/300;
    if( opacity > 1 )
    opacity = 1;
    fixed.css("opacity",opacity);
   if( fixed.css('opacity') == 1 ) {
   top = 0; 
   opacity =  (top += $( window ).scrollTop()-400)/300;
  if( opacity > 1 )
    opacity = 1;
   fixed2.css("opacity",opacity);
}
});
.fixed{
    display: block;
    width: 100%;
    height: 200px;
    background: blue;
    position: fixed;
    top: 0px;
    left: 0px;
    color: #FFF;
    padding: 0px;
    margin: 0px;
    opacity: 0;
}

.fixed2{
    display: block;
    width: 100%;
    height: 200px;
    background: red;
    position: fixed;
    top: 0px;
    left: 0px;
    color: #FFF;
    padding: 0px;
    margin: 0px;
    opacity: 0;
}

.container{  
    display: inline-block;
    width: 100%;
    height: 2000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
Scroll me!!
</div> 
<div class="fixed">   
</div>
<div class="fixed2">  
</div>
Dejo Dekic
  • 2,088
  • 4
  • 27
  • 50