2

Similar to this unresolved question (jQuery - parallax - update background position correctly)

I am animating the transform property of an element on page scroll to achieve a parallax-like effect. I want this element to only begin animating up when it is in view. The problem now is that if the element appears further down the page, it has already moved up a lot and loses the effect.

Here is my code currently

function parallax() {
  var scrolled = $(window).scrollTop();
  $('[data-scroll]').css('transform', 'translateY('+-(scrolled*0.02)+'px)');
}

$(window).scroll(function(e){
  parallax();
});
Community
  • 1
  • 1
hidanielle
  • 464
  • 3
  • 10
  • thats way too little code.. make a fiddle – Rachel Gallen May 30 '16 at 14:07
  • in fact, forget the fiddle, check out this site https://ihatetomatoes.net/demos/parallax-scroll-effect/ – Rachel Gallen May 30 '16 at 14:10
  • http://stackoverflow.com/questions/20791374/jquery-check-if-element-is-visible-in-viewport – GL.awog May 30 '16 at 14:11
  • @Rachel Gallen It's not way too little code, since it's all the code that is being used for the effect. I guess if you'd like to see the HTML it's literally just a div with [data-scroll] on it... Thanks for the link though, I will check it out – hidanielle May 30 '16 at 14:29
  • @GL.awog I know how to check if the element is visible, and I've been experimenting with that. I guess I'm just not sure how to then figure out what the transform position should be based off the of the scroll position and speed. – hidanielle May 30 '16 at 14:30

1 Answers1

8

In answer to your question how to separate "parallax'ed" divs, so they shift their position independently from each other upon scrolling, one should rely on their unique coordinates - each one has it's own $(elem).offset().top - a general vertical offset from the top of the page (it's stays the same all the time unless you meddle with the TOP property manually).

so all calculation could be based against this property.

$('.parallax').each(function(){ 
    
    if ($(this).is_on_screen()) {
      var firstTop = $(this).offset().top;
      var winScrollTop = $(window).scrollTop();
      var shiftDistance = (firstTop - winScrollTop)*0.02;

      $(this).css("transform":"translateY("+shiftDistance+"px)");
    }
});

plus you check if the element is in the viewport. Thus, you assure it moves the same delta distance in its own time no matter where it's on the page - further down or up.

Another thing is that how to put "borders" of visibility of the element on the screen. If you are moving an element when it's in viewport, i would suggest making a wrapping div within which the movement occurs (like a bg moving within a div wrapper).

<div class="parallax-section slide1">
 <span class="moving-block"></span>
</div>

div has a bigger height and we check when this div is on the screen, not the moving element.

demo

Also other modifications can be applied if one needs different speed, offset for each element. I found this plugin a good beginner stuff to learn parallax.

P.S. btw, all initial properties should be cached in variables instead of retrieving them each time in a callback, like firstTop for instance

Community
  • 1
  • 1
GL.awog
  • 1,343
  • 1
  • 7
  • 13
  • Thanks for the jsfiddle demo. I came across it when trying to fix an inherent issue with parallax. In your example, the parallax item is practically touching the top of the viewport. However, on the site I was building, the parallax box was visible on-screen, however starting around 75% of the way down the page. As soon as I start scrolling, the element 'jumps' down to commence its parallax as it receives its first translateY value. – Scott Richardson Nov 23 '18 at 02:26
  • I tried performing an update on the translateY as soon as the window has finished loading to pre-position the element, but there was still a minor variation in the translateY value. So - the question is - how do we account for that initial change in translateY value from nothing, to something - creating a jump? My only workaround so far has been to assess where it first sets the translateY when you scroll, and set that as the initial translateY value in the CSS for that element. But this feels clunky. – Scott Richardson Nov 23 '18 at 02:28