简体   繁体   中英

Parallax with background-position: center center without jump

I couldn't think of a solution myself after trying dozens of approaches

#banner .slide {
    position: static;
    top: 0px;
    left: 0px;
    z-index: 99;
    opacity: 1;
    display: block;
    visibility: hidden;
    background-image: url(http://wp-content/uploads/2260-000-01.jpg);
}


#banner .slide {
    background-attachment: inherit;
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
    position: relative;
}

The background-image is positioned center center as you can see and it is intentional that the background-attachement is not fixed (as it would always in combination with cover lead to a to narrow view of the image.)

In order to achieve the desired parallax I use this snippet.

$(window).on('scroll', function(e) {
        $('#banner .slide').css('background-position', 'center ' + $(window).scrollTop()*0.4 + 'px')
    })

The problem I have of course is that the initial scroll (very first change in scrollTop) leads to a jump of the image because of course JS does not know what center means for me.

So my goal is to keep the image position intially center center as I want to always see the very vertical and horizontal cenver of the image.

Do you know any trick or idea how I could tell the JS the current vertical center of the image, so the parallax calculation would start from this point instead of starting from 0.

Thanks, Matt

I would suggest taking a slightly different approach by changing transform value of the slide instead.

 const parallaxables = document.querySelectorAll('.parallax'); function runParallaxLoop() { requestAnimationFrame(runParallaxLoop); parallax(); } function parallax() { parallaxables.forEach(parallaxable => { let distance = window.scrollY * 0.5; parallaxable.style.transform = `translate3d(0,-${distance}px, 0)`; }); } runParallaxLoop(); 
 .parallax { width: 100vw; height: 500px; margin-bottom: 400px; background: url(http://lorempixel.com/1200/800/sports/) no-repeat center center; background-attachment: fixed; } 
 <div class="parallax"></div> 

Every frame, you transform the element that needs to be parallaxed by a certain percentage of speed with which the browser is scrolling.

For this to work, you need the background-attachment of the parallax-able element to be fixed.

I know this is a little bit old but I just wanted to throw an alternative way in that I have used in the past. This is 100% vanilla javascript. One thing to note: you need to call init seperately inside the function so you don't get that ju

 let parallax = (id, rate) => { const parallaxObject = document.querySelector(id); const init = () => { const x = parallaxObject.getBoundingClientRect().top / rate; const y = Math.round(x * 100 / 100); parallaxObject.style.backgroundPosition = 'center ' + y + 'px'; } init(); window.addEventListener('scroll', () => { init(); }) } parallax('.hero', 5)
 .hero { background: #fff url('https://source.unsplash.com/random') no-repeat fixed center center / cover; margin-top: 1000px; margin-bottom: 1000px; min-height: 75vh; display: grid; place-items: center; }
 <div class="hero"> <h1>Hero Text</h1> <div> // Scroll Down To See Effect

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM