Prosty efekt parallax

|

Niewątpliwie jednym z najpopularniejszych upiększaczy naszych stron w ostatnim czasie jest efekt parallax. W skrócie polega na tym, że fragment strony przesuwa się z inną prędkością niż pozostałe, co daje pewne złudzenie trójwymiarowości. Wbrew pozorom stworzenie takiego efektu dość łatwe, co postaram się udowodnić poniżej.

Zobacz demo

HTML+CSS

Zacznijmy od prostego HTML-a.

<section class="bgnd bgnd-1 js-parallax-bg">
    <!-- zawartość -->
</section>

Od strony CSS potrzebujemy przede wszystkim odpowiedniego ustawienia tła oraz wysokości animowanej sekcji.

.bgnd {
    background-attachment: fixed;
    background-position: 50% 0;
    background-repeat: no-repeat;
    background-size: cover;
    height: 54vh;
    max-height: 1200px;
    min-height: 200px;
}

Oczywiście każda sekcja otrzymuje inne tło:

.bgnd-1 {
    background-image: url(../img/01.jpg);
}

.bgnd-2 {
    background-image: url(../img/02.jpg);
}

.bgnd-3 {
    background-image: url(../img/03.jpg);
}

Pierwszą, tytułową sekcję wyróżnimy zwiększając nieco jej wysokość.

header + .bgnd {
    height: 86vh;
}

Odrobina magii

Zacznijmy od zebrania wszystkich sekcji, które chcemy animować. Wykorzystamy do tego natywną metodę querySelectorAll. Ponieważ metoda ta zwraca wynik w postaci obiektu NodeList, który nie pozwala na iterację w pętli, musimy posłużyć się drobną sztuczką, by otrzymany wynik przekształcić w tablicę.

var images = [].slice.call(document.querySelectorAll('.js-parallax-bg'));

Niezbędna będzie informacja o wysokości okna przeglądarki, a ponieważ różne przeglądarki podają nieco rozbieżne wyniki, musimy posłużyć się kolejną sztuczką.

function getViewportHeight() {
    var a = document.documentElement.clientHeight, b = window.innerHeight;
    return a < b ? b : a;
}

Potrzebna będzie również informacja o aktualnym położeniu strony w pionie:

function getViewportScroll() {
    if(typeof window.scrollY != 'undefined') {
        return window.scrollY;
    }
    if(typeof pageYOffset != 'undefined') {
        return pageYOffset;
    }
    var doc = document.documentElement;
    doc = doc.clientHeight ? doc : document.body;
    return doc.scrollTop;
}

Następnie dla każdej sekcji, która jest widoczna na ekranie, wykonamy drobne obliczenia i ustawimy odpowiednią pozycję tła.

function doParallax() {
    var el, elOffset, elHeight,
        offset = getViewportScroll(),
        vHeight = getViewportHeight();

    for(var i in images) {
        el = images[i];
        elOffset = el.offsetTop;
        elHeight = el.offsetHeight;

        if((elOffset > offset + vHeight) || (elOffset + elHeight < offset)) { continue; }

        el.style.backgroundPosition = '50% '+Math.round((elOffset - offset)*3/8)+'px';
    }
}

Całość wesprzemy biblioteką Gator, pozwalającą na delegację zdarzeń (dla prostych skryptów jest to dobra alternatywa jQuery), w tym przypadku scroll-a:

Gator(window).on('scroll', doParallax);

Wsparcie przeglądarek

Oczywiście tradycyjnie problemy dotyczą Internet Explorera w wersji 8 i starszych. Drobne błędy występują także w Operze opartej o silnik Presto i starszych wersjach przeglądarek mobilnych.

Parallax gotowy

Zobacz demo
Dodaj na LinkedIn
Mariusz Kuta
Programista (PHP/MySQL, Node.js/MongoDB), koder (HTML/CSS/JS), ale od biedy nawet layout machnie ;)