Is there a way to make parallax work within a DIV

11,151

Yes, that's possible.

As you presumably know a normal parallax effect just puts a bg image on the body tag and either changes its background offset as you scroll, or moves some divs on top of it slower than the scroll rate.

Since you want separate images in each of the windows, you need to go with the background offset approach. Each div is just something like this in CSS:

#div1 {
    background: url('/ui/div1bg.jpg') 0 -800px no-repeat;
}

The 0 -800px are the background-position. As the window scrolls down you want to shift the backgrounds downward by increasing that second value gradually, to simulate perspective. In simulated perspective, farther things move slowly past you, close things move quickly.

So you just get the scroll event:

$(window).scroll(function () {
    parallax();
});

Gather the metrics you'll be using:

function parallax() {
    var ev = {
        scrollTop: document.body.scrollTop || document.documentElement.scrollTop
    };
    ev.ratioScrolled = ev.scrollTop / (document.body.scrollHeight - document.documentElement.clientHeight);
    render(ev);
}

And render the changes:

function render(ev) {
    var t = ev.scrollTop;
    var y = Math.round(t * 2/3) - 800;
    $('#div1, #div2, #div3').css('background-position', '0 ' + y + 'px');
}

So, as the t variable increases (user scrolls down), the image shifts at 2/3 the rate. It starts at -800px and gradually makes its way to 0 once the user has scrolled to 1200px down. If the page is longer than 1200px AND the element is still visible you'll have to adjust the math, since after that the code is going to scroll past the top of the image. If they'll already be past the element by that point though, you can ignore it.

Obviously you should adjust the numbers there to get the right effect for your divs and images.

If you want to base it on the total page height no matter what it happens to be, you can use the second metric up there, .ratioScrolled, like:

var y = Math.round((1 - ev.ratioScrolled) * -100);

So for example if you had a div with height 150px, and an image 250px tall, the above would work perfectly - it starts at -100px (shifted up) and as the page scrolls by, no matter how long it happens to be, it ends at 0px (no shift - so the bottom 100px is clipped).

Share:
11,151
Joseph Gregory
Author by

Joseph Gregory

Not much to tell

Updated on June 14, 2022

Comments

  • Joseph Gregory
    Joseph Gregory almost 2 years

    May be completely barking up the wrong tree but can you make a parallax scrolling image using a div background-image element?

    What I want to happen is I currently have some DIVs with images with a text effect rollover but I as I'm using parallax in a background image I want to keep the 3D theme with all the sites images.

    EDIT: For example, is it possible to make the blue boxes on this page:

    www.parkhallmanor.co.uk/new

    Scroll separate images using a parallax effect?