Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Animate translateY Based On Scroll Percentage

I'm trying to build a simple overlapping "parallax" effect without any plugins. I have html like:

<section>
    <h2>Example Text</h2>
</section>
<section>
    <h2>Example Text</h2>
</section>
<section>
    <h2>Example Text</h2>
</section>
<section>
    <h2>Example Text</h2>
</section>
<section>
    <h2>Example Text</h2>
</section>

Each section has a height of 100% of the viewport. I'm using an each loop inside $(window).scroll(). I need to animate the transform: translateY() property of the top section until the following section is at the top of the browser. This percentage essentially needs to be based on the percetange from the top of the browser. I've tried a number of things involving getting the offset().top, and height() values, and comparing them to $(window).scrollTop() but I can't seem to work it out. This is the effect I'm trying to achieve, though its using a jQuery plugin.

http://codepen.io/rocbear/pen/bdIaG

Edit I have this almost worked out now, but I have one small issue scroll back to the top. The translate property doesn't go all the way back to 0% and leaves a gap at the top.

My codepen: http://codepen.io/mdmoore/pen/MwjoLZ

$(function(){
  $('section').each(function() {
    var off = $(this).offset().top
    $(this).data('orig-offset', off);
  });
  $(window).scroll(function(){
    var scrollTop = $(window).scrollTop();

    $('section').each(function(){
      var off = $(this).data('orig-offset');
      var translate =  (scrollTop - off) / $(window).height() * 100;
      if (scrollTop >= off) {
        $(this).css({transform: 'translateY(' + translate +'%)'});
      }
    });
  });
});
like image 341
WordPress Mike Avatar asked Oct 15 '25 17:10

WordPress Mike


1 Answers

Here's one way. Feel free to optimize it if you want.

$(function(){
  $('section').each(function() {
    var off = $(this).offset().top
    $(this).data('orig-offset', off);
  });
  $(window).scroll(function(){
    var scrollTop = $(window).scrollTop();

     $('section').each(function(){
      var off = $(this).data('orig-offset');
      
       
      if (scrollTop >= off) {
        var translate =  (scrollTop - off) / $(window).height() * 100;
        console.log(translate);
        $(this).css({transform: 'translateY(' + translate +'%)'});
      }
     });
  });
});
html, body {
  height: 100%;
  margin: 0;
}

h2 {
  margin: 0;
  text-align: center;
}

section {
  background: #000;
  height: 100%;
  width: 100%;
  position: relative;
  top: 0;
}
section:first-of-type {
  background-color: coral;
}
section:nth-of-type(2) {
  background-color: lightgreen;
}
section:nth-of-type(3) {
  background-color: lightblue;
}
section:nth-of-type(4) {
  background-color: #ffff6e;
}
section:nth-of-type(5) {
  background-color: #3c3c3c;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="top">
<h2>Some Text</h2>
</section>
<section>
<h2>Some Text</h2>
</section>
<section>
<h2>Some Text</h2>
</section>
<section>
<h2>Some Text</h2>
</section>
<section>
<h2>Some Text</h2>
</section>
like image 68
Robert McKee Avatar answered Oct 18 '25 06:10

Robert McKee