4

I've a small bit of parallax on a site I'm working on, it's working almost fine but the foreground divs are a bit jumpy when I scroll down the page.

Near the top of the page I have a div called #top-banner, it has a fixed background image, sitting within this div are two more within a row, the fisrt div / column has an image of a model & the second div has just text.

Below the #top-banner div is a div with a background image of a waterline, the desired effext is to have the waterline to cover the #top-banner as the user scrolls down, to make it seem as if the model, text & background are being covered by water.

I've got it working by using jQuery to change the css bottom property to make it seem that the two columns divs are moving down the page beneath the waterline at a similar speed to the scroll when the user scrolls down the page. I've set the speeds/increments to be slightly different to create a parallax effect.

It's working pretty well but is a bit jumpy, I've also tried to use the jQuery animate function but that is even more jumpy.

HTML

<section id="top-banner">
    <div class="row">
        <div class="col-2 prlx-1">
            <img src="model.png"/>
        </div>
        <div class="r-col-2 prlx-2">
            <h3>Lorem Ipsum</h1> 
            <p>More Ipsum</p>
        </div>                            
</section>   

<section id="hp-water-line"></section>

CSS

#hp-top-banner {
  background: url(bg.png);
  height: 600px;
  background-attachment: fixed;
  background-origin: initial;
  background-clip: initial;
  background-size: cover;
  overflow: hidden;
  width: 100%;
  position: relative;
}

#hp-water-line {
  background: url(water-line.png) no-repeat transparent;
  min-height: 92px;
  margin: 0 auto;
  width: 100%;
  position: relative;
  top: -15px;
  background-size: cover;
}

JS

$(document).ready(function(){

    function parallax(){
        var prlx_effect_1= -((window.pageYOffset / 4) *2.25 );
        $('.prlx-1').css({"position": "relative","bottom":prlx_effect_1, "transition": "0s ease-in-out"});
           // jQ('.prlx-1').css({"position": "relative"});
           // jQ('.prlx-1').animate({"bottom":prlx_effect_1},"fast");

        var prlx_effect_2= -(window.pageYOffset / 5 );
        $('.prlx-2').css({"position": "relative","bottom":prlx_effect_2, "transition": "0s ease-in-out"});

    }

    window.addEventListener("scroll", parallax, false);

});

Updated JS based on Prinzhorn Comment

var requestAnimationFrame = window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    window.oRequestAnimationFrame;

function onScroll() {
    requestAnimationFrame(parallax);
}

function parallax(){
    var prlx_effect_1= +(window.pageYOffset *.7).toFixed(2); // .55 is a good speed but slow
    var prlx_str_1 = "translate3d(0, "+prlx_effect_1+"px, 0)";
    jQ('.prlx-1').css({
        "transform":prlx_str_1,
        "-ms-transform":prlx_str_1,
        "-webkit-transform":prlx_str_1
    });

    var prlx_effect_2= +(window.pageYOffset * 1 ).toFixed(2); // .33 is a good speed but slow
    var prlx_str_2 = "translate3d(0, "+prlx_effect_2+"px, 0)";
    jQ('.prlx-2').css({
        "transform":prlx_str_2,
        "-ms-transform":prlx_str_2,
        "-webkit-transform":prlx_str_2
    });

    requestAnimationFrame(parallax);

}

window.addEventListener("scroll", onScroll, false);
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Holly
  • 7,462
  • 23
  • 86
  • 140
  • Don't animate `bottom` (use `transform`). Don't use `scroll` event (use `requestAnimationFrame`). – Prinzhorn Jul 19 '14 at 11:38
  • @Prinzhorn thank you, I've tried doing this but my new code is not working. jQuery is only adding `-webkit-transform: translateY(0px);` and only when I scroll back up to the top of the page?? I've updated my question with the new code. – Holly Jul 19 '14 at 12:36
  • You didn't specify a unit, e.g. `px`. If it worked for `bottom` before I assume you're missing a correct DOCTYPE, because that only works in quirks mode. – Prinzhorn Jul 19 '14 at 13:51
  • @Prinzhorn Thanks, that was it. Why is transform better than bottom? Am I using the requestAnimationFrame() method properly? It's seems to be working fine but I'm not really sure how? – Holly Jul 19 '14 at 18:04
  • 1
    "Am I using the requestAnimationFrame() method properly?" No. Read this to answer all your questions https://medium.com/@dhg/82ced812e61c – Prinzhorn Jul 19 '14 at 21:03
  • 1
    https://github.com/Prinzhorn/skrollr highly recommended – Aessandro Jul 23 '14 at 09:03

1 Answers1

3

I used to build parallax sites in a similar way,by using jquery to adjust the background-position or margins, however, i read this article a few months back which really changed the way I approach them.

He suggest using CSS translateZ and perspective to move containers or imagery forward and backwards into the 3 dimensional space to create 'real' parralax. This creates more fluid animations, and also renders better on mobile devices. I also personally find this much easier to execute.

I.E.

.parallax {
    perspective: 1px;
    height: 100vh;
    overflow-x: hidden;
    overflow-y: auto;
}
.parallax__layer {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
.parallax__layer--base {
    transform: translateZ(0);
}
.parallax__layer--back {
    transform: translateZ(-1px);
}

The only issue is, that using real 3Dimensional layers, means you have to be smart with your Z-Index to make sure your layers are not overlapping at the wrong places.

The article has an excellent demo, which you can view the side profile of the 3D space to see how the layers are distributed in the z-axis. Just click the 'debug' button in the top left corner.

http://keithclark.co.uk/articles/pure-css-parallax-websites/

Todd Padwick
  • 155
  • 2
  • 11
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Nachi Nov 03 '14 at 15:50
  • ah ok... thank you Nachi... im new to stackoverflow... still learning the ropes and how best to answer questions. Appreciate your feedback. I will do this in future. I will also edit my answer when i get a chance to strip down that article for key parts to include. thanks – Todd Padwick Nov 03 '14 at 16:18