Efekt parallax

Parallax effect mockup

Efekt parallax na stronach internetowych jest czymś co niezmiennie cieszy i zachwyca użytkowników. Dzięki niemu strona zdecydowanie zyskuje na atrakcyjności, sprawia wrażenie głębi oraz trójwymiaru. W tym wpisie pokażę na prostym przykładzie jak można coś takiego osiągnąć.

Gotowy projekt można znaleźć pod poniższym linkiem.

DEMO
KOD

Ok, na początek stworzymy strukturę strony:

    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="style.css">
        <title>Parallax effect</title>
    </head>
    <body>
        <section id="scene">
            <img class="moon" src="img/moon.png" alt="">
            <img class="background" src="img/galaxy.jpg" alt="">
            <img class="earth" src="img/earth.png" alt="">
            <img class="asteroid-2" src="img/asteroid-2.png" alt="">
            <img class="asteroid-3" src="img/asteroid-3.png" alt="">
            <img class="asteroid" src="img/asteroid.png" alt="">
            <h1 class="hello-world">HELLO WORLD</h1>
        </section>
    </body>
    </html>

Utworzyłem sekcje o ID 'scene’, w środku której umieściłem obrazy które będę chciał animować. Dodałem również tytuł 'Hello World’.

    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="style.css">
        <title>Parallax effect</title>
    </head>
    <body>
        <section id="scene">
            <img class="moon" src="img/moon.png" alt="">
            <img class="background" src="img/galaxy.jpg" alt="">
            <img class="earth" src="img/earth.png" alt="">
            <img class="asteroid-2" src="img/asteroid-2.png" alt="">
            <img class="asteroid-3" src="img/asteroid-3.png" alt="">
            <img class="asteroid" src="img/asteroid.png" alt="">
            <h1 class="hello-world">HELLO WORLD</h1>
        </section>
        <section id="text">
          <h1>Chapter one.</h1>
          <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt
            dignissimos quos architecto a deleniti consequuntur nihil quae similique
            quam obcaecati dolores impedit eveniet neque accusamus enim
            iste beatae facilis. 
          </p>
          <p>
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt
            dignissimos quos architecto a deleniti consequuntur nihil quae similique quam
            obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis.
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt
            dignissimos quos architecto a deleniti consequuntur nihil quae similique quam 
            obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis.
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos
            quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores
            impedit eveniet neque accusamus enim, iste beatae facilis.
          </p>
      </section>
      <section>
          <h1>Chapter two.</h1>
          <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. 
            Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur
            nihil quae similique quam obcaecati dolores impedit eveniet neque 
            accusamus enim, iste beatae facilis. 
          </p>
          <p>
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. 
            Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur
            nihil quae similique quam obcaecati dolores impedit eveniet
            neque accusamus enim, iste beatae facilis.
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. 
            Dolorem nesciunt dignissimos quos architecto a deleniti
            consequuntur nihil quae similique quam obcaecati dolores 
            impedit eveniet neque accusamus enim, iste beatae facilis. 
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. 
            Dolorem nesciunt dignissimos quos architecto a deleniti 
            consequuntur nihil quae similique quam obcaecati dolores 
            impedit eveniet neque accusamus enim, iste beatae facilis.
          </p>
      </section>
    </body>
    </html>

Dodałem jeszcze dwie przykładowe sekcje, które pojawią się po przewinięciu naszej głównej sekcji z parallaxą.

Teraz dodam do niej min. wysokość na 2x wysokość okna przeglądarki, aby było po czym scrollować:

  section {
    height: 200vh;
    width: 100%;
    background-color: rgb(40, 40, 55);
    position: relative;
    perspective: 10000px;
  }

Pozostałym sekcją nadam takie style:

  section:nth-child(2){
      z-index: 200;
  }
  section:nth-child(2),
  section:nth-child(3){
      padding: 50px;
      background: #000000;
      min-height: 100vh;
      height: unset;
  }
  section:nth-child(3) {
      background: #fff;
  }
  section:nth-child(3) * {
      color: #000;
  }

  section:nth-child(2):before {
      content: '';
      width: 100%;
      height: 700px;
      background: linear-gradient(transparent, #000000);
      position: absolute;
      left: 0;
      top: -700px;
  }

Obrazy i tytuł główny również lekko ostyluję:

  .moon {
      width: 180px;
      height: 180px;
      border-radius: 100%;
      position: absolute;
      left: 50%;
      top: 400px;
      z-index: 2;
  }
  .earth {
      position: absolute;
      right: 0;
      bottom: 820px;
      z-index: 3;
  }
  .background {
      position: absolute;
  }
  .hello-world {
      position: absolute;
      top: calc(10%);
      right: 0;
      width: 700px;
      height: 200px;
      font-size: 5rem;
      -webkit-text-stroke: 1px #fff;
      color: transparent;
  }
  .asteroid,
  .asteroid-2,
  .asteroid-3 {
      position: absolute;
      z-index: 5;
  }
  .asteroid {
      right: -950px;
      top: 700px;
  }

Cały kod CSS podam na końcu wpisu.

Teraz użyje JavaScriptu abo dodać ruch do naszych elementów (obrazków + tytuł). Na poniższym przykładzie, najpierw pobieram sobie element ze strony, np księżyc:

  
	const moon = document.querySelector('.moon');
  

Dodam teraz „Event listener” do obiektu Window, tak że podczas zdarzenia 'scroll’, czyli przewijania strony, w zmiennej 'value’ będzie przechowywana bieżąca wartość o jaką zostałą przewinięta strona.

 
	window.addEventListener('scroll', () => {
        let value = window.scrollY;
    });
  

Następnym krokiem, będzie przypisanie tej zmiennej jako wartość właściwości transform tego elementu, dodatkowo mnożąc ją przez odpowiednią liczbę będziemy kontrolowali prędkość ruchu elementu:

 
	 window.addEventListener('scroll', () => {
      let value = window.pageYOffset;
      moon.style.transform = `transform3d(0px, ${value * .95}px, 0px)`;
  });
  

Po takim zabiegu teraz nasz księżyc już powinien się poruszać podczas scrollowania strony.

To samo zrobię z pozostałymi elementami:

 
    const moon = document.querySelector('.moon');
    const background = document.querySelector('.background');
    const helloWorld = document.querySelector('.hello-world');
    const asteroid = document.querySelector('.asteroid');
    const asteroid2 = document.querySelector('.asteroid-2');
    const asteroid3 = document.querySelector('.asteroid-3');
    const earth = document.querySelector('.earth');
    const scrollTopBtn = document.querySelector('a.top');

    window.addEventListener('scroll', ()=>{
        let value = window.pageYOffset;
        console.log(value);

        moon.style.marginTop = `${value * .95}px`;
        background.style.transform = `translate3d(0px, ${value}px, 0px)`;
        helloWorld.style.transform = `translate3d(-${value}px, ${value}px, 0px)`;
        asteroid.style.transform = `translate3d(-${value * 1.6}px, ${value * .2}px, ${value *
          .2}px)`;
        asteroid2.style.transform = `translate3d(-${value * .2}px, ${value * 0.65}px, 0px)`;
        asteroid3.style.transform = `translate3d(-${value * .2}px, ${value * 0.75}px, 0px)`;
        earth.style.transform = `translate3d(0px, ${value * 0.75}px, 0px)`;

        if (value > 1000) {
            scrollTopBtn.style.opacity = '1';
        } else scrollTopBtn.style.opacity = '0';
    });
  

Poniżej cały kod dla gotowego projektu:

HTML:

    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="style.css">
        <title>Parallax effect</title>
    </head>
    <body>

        <section id="scene">
            <a href="#text"></a>
            <img class="moon" src="img/moon.png" alt="">
            <img class="background" src="img/galaxy.jpg" alt="">
            <img class="earth" src="img/earth.png" alt="">
            <img class="asteroid-2" src="img/asteroid-2.png" alt="">
            <img class="asteroid-3" src="img/asteroid-3.png" alt="">
            <img class="asteroid" src="img/asteroid.png" alt="">
            <h1 class="hello-world">HELLO WORLD</h1>
            
        </section>
        <section id="text">
            <h1>Chapter one.</h1>
            <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis. 
            </p>
            <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis.
                Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis.
            </p>
        </section>
        <section>
            <h1>Chapter two.</h1>
            <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis. 
            </p>
            <p>
                Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis.
                Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dolorem nesciunt dignissimos quos architecto a deleniti consequuntur nihil quae similique quam obcaecati dolores impedit eveniet neque accusamus enim, iste beatae facilis.
            </p>
        </section>
        <a class="top" href="#scene"></a>
        <script src="jquery.min.js"></script>
        <script src="script.js"></script>
    </body>
    </html>

CSS:

   @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap');
  body {
      margin: 0;
      overflow-x: hidden;
      background-color: rgb(40, 40, 55);
      font-family: 'Poppins', sans-serif;
  }

  * {
      box-sizing: border-box;
      color: #fff;
      transition: 0s linear;
      transition-property: all;
  }
  a {
      position: absolute;
      z-index: 1000;
      right: 50px;
      top: 50px;
      width: 50px;
      height: 50px;
      background: #fff;
      border-radius: 100%;
      transition: .5s;
  }
  a:hover {
      opacity: .7;
  }
  a:before {
      content: '';
      position: absolute;
      width: 15px;
      height: 15px;
      border-left: 3px solid black;
      border-bottom: 3px solid black;
      left: calc(50% - 9px);
      top: calc(50% - 11px);
      transform: rotate(-45deg);
  }

  a.top {
      position: fixed;
      opacity: 0;
  }
  a.top:before {
      transform: rotate(135deg);
      top: unset;
      bottom: calc(50% - 11px);
  }
  .top {
      top: unset;
      bottom: 50px;
  }
  section {
      height: 200vh;
      width: 100%;
      background-color: rgb(40, 40, 55);
      position: relative;
      perspective: 10000px;
  }
  #scene{
      overflow: hidden;
  }
  section:nth-child(2) {
      z-index: 200;
  }
  section:nth-child(2),
  section:nth-child(3){
      padding: 50px;
      background: #000000;
      min-height: 100vh;
      height: unset;
  }
  section:nth-child(3) {
      background: #fff;
  }
  section:nth-child(3) * {
      color: #000;
  }

  section:nth-child(2):before {
      content: '';
      width: 100%;
      height: 700px;
      background: linear-gradient(transparent, #000000);
      position: absolute;
      left: 0;
      top: -700px;
  }
  .moon {
      width: 180px;
      height: 180px;
      border-radius: 100%;
      position: absolute;
      left: 50%;
      top: 400px;
      z-index: 2;
  }
  .earth {
      position: absolute;
      right: 0;
      bottom: 820px;
      z-index: 3;
  }
  .background {
      position: absolute;
  }
  .hello-world {
      position: absolute;
      top: calc(10%);
      right: 0;
      width: 700px;
      height: 200px;
      font-size: 5rem;
      -webkit-text-stroke: 1px #fff;
      color: transparent;
  }
  .asteroid,
  .asteroid-2,
  .asteroid-3 {
      position: absolute;
      z-index: 5;
  }
  .asteroid {
      right: -950px;
      top: 700px;
  }
  #text * {
      text-align: center;
  }
  #text h1 {
      font-weight: 400;
      font-size: 3rem;
  }
  #text p {
      font-weight: 300;
      max-width: 50%;
      margin: auto;
      font-size: 1.2rem;
      margin-bottom: 30px;
      text-align: left;
  }
  @media(max-width: 767.98px) {
      .hello-world {
          font-size: 3rem;
          width: unset;
          height: unset;
          right: -152px;
      }
      .asteroid {
         top: 500px;
      }
      #text p {
          max-width: unset;
      }

      img {
          max-width: 100%;
      }
      .background {
          max-width: 300%;
      }
  }

JavaScript + jQuery:

  const moon = document.querySelector('.moon');
  const background = document.querySelector('.background');
  const helloWorld = document.querySelector('.hello-world');
  const asteroid = document.querySelector('.asteroid');
  const asteroid2 = document.querySelector('.asteroid-2');
  const asteroid3 = document.querySelector('.asteroid-3');
  const earth = document.querySelector('.earth');
  const scrollTopBtn = document.querySelector('a.top');

  window.addEventListener('scroll', () => {
      let value = window.pageYOffset;
      moon.style.marginTop = `${value * .95}px`;
      background.style.transform = `translate3d(0px, ${value}px, 0px)`;
      helloWorld.style.transform = `translate3d(-${value}px, ${value}px, 0px)`;
      asteroid.style.transform = `translate3d(-${value * 1.6}px, ${value * .2}px, ${value *
        .2}px)`;
      asteroid2.style.transform = `translate3d(-${value * .2}px, ${value * 0.65}px, 0px)`;
      asteroid3.style.transform = `translate3d(-${value * .2}px, ${value * 0.75}px, 0px)`;
      earth.style.transform = `translate3d(0px, ${value * 0.75}px, 0px)`;

      if (value > 1000) {
            scrollTopBtn.style.opacity = '1';
        } else scrollTopBtn.style.opacity = '0';
    });

  $(function() {
      $('a[href]').click(function() {
        if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
          var target = $(this.hash);
          target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
          if (target.length) {
            $('html,body').animate({
              scrollTop: target.offset().top
            }, 3000);
            return false;
          }
        }
      });
    });
  

Jak widać użyłem również jQuery aby uzyskać płynne przewijanie strony, oraz kontrolować jego czas.

Gotowy projekt znajdziesz TUTAJ.

Efekt parallax na pewno sprawi że nasza strona stanie się dużo ciekawsza. Powyższy przykład jest bardzo prosty i stanowi jedynie mały ułamek tego co można osiągnąć. W tym poście stworzyłem efekt paralaksy na obrazkach. Można się tym bawić również na inne sposoby, np. animować płynne przejście tła w sekcjach, lub parallax reagujący na ruchy kursora myszy. Warto również korzystać z gotowych bibliotek, np. takich jak:

Parallax.js

Lax.js

Rellax

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *