Как повторить эффект скролла

есть сайт: https://www.nobili.it/ru/

Как сделать такой же эффект перехода между блоками "как будто друг на друга смещаются когда скролить вниз",

Из того что я нашел на сайте примере есть модуль "HPSections" но в гугл толком ничего про такой модуль не известно, и достать файл "hpsections.js" с самого сайта не могу


Ответы (2 шт):

Автор решения: DronDron

Если совсем быстро что-то приготовить, то ниже есть пример (запускайте и разворачивайте на весь экран что бы было лучше видно).

const scrolls = document.querySelectorAll(".scroll *");
const colors = document.querySelectorAll(".scroll__color");
window.onscroll = e => {
    const openedPage = Math.floor((getBodyScrollTop() - 1) / window.innerHeight) + 1;
    for (let i = 1; i < 3; i++)
        document.querySelector(".scroll__" + i).style.position = i <= openedPage ? "fixed" : "static";

    for (let i = 0; i < colors.length - 1; i++) {
        const scroll = ((getBodyScrollTop() / window.innerHeight + 1) - (i + 1));
        colors.item(i).style.opacity = (scroll < 0.19 ? scroll : Math.pow(scroll, 0.3)) + "";
    }
}

function getBodyScrollTop() {
    return self.pageYOffset || (document.documentElement && document.documentElement.scrollTop) || (document.body && document.body.scrollTop);
}

setPaddings();
function setPaddings() {
    const padding = document.querySelector(".header").clientHeight;
    for (let i = 0; i < scrolls.length; i++) {
        if (/scroll__content/.test(scrolls.item(i).className))
            scrolls.item(i).style.paddingTop = padding + "px";
    }
}
body {
  overflow-x: hidden;
}

* {
  padding: 0;
  margin: 0;
}

.wrapper {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.scroll {
  z-index: 1;
  flex-grow: 1;
  width: 100%;
  background: blue;
  display: flex;
  flex-direction: column;
  position: relative;
}
.scroll * {
  height: 100vh;
  width: 100%;
}
.scroll__content {
  padding: 30px 10px 10px 10px;
  position: absolute;
  width: 100%;
  height: 100vh;
}
.scroll__1 {
  background: url("http://www.alleycat.org/wp-content/uploads/2019/03/FELV-cat.jpg") center;
  background-size: cover;
}
.scroll__2 {
  background: url("https://media.4-paws.org/a/5/3/7/a537f08d227326121b80790ba54036498668c9c8/VIER%20PFOTEN_2016-07-08_011-4993x3455-1920x1329.jpg") center;
  background-size: cover;
}
.scroll__3 {
  background: url("https://cdn.sci.news/images/enlarge9/image_10897e-Cats.jpg") center;
  background-size: cover;
}
.scroll__1 {
  z-index: 2;
}
.scroll__1 .scroll__content {
  z-index: 3;
}
.scroll__1 .scroll__color {
  position: absolute;
  width: 100%;
  height: 100vh;
  z-index: i1;
  background: rgba(0, 0, 0, 0.76);
  opacity: 0;
  transition: 0.5s opacity;
}
.scroll__2 {
  z-index: 3;
}
.scroll__2 .scroll__content {
  z-index: 4;
}
.scroll__2 .scroll__color {
  position: absolute;
  width: 100%;
  height: 100vh;
  z-index: i1;
  background: rgba(0, 0, 0, 0.76);
  opacity: 0;
  transition: 0.5s opacity;
}
.scroll__3 {
  z-index: 4;
}
.scroll__3 .scroll__content {
  z-index: 5;
}
.scroll__3 .scroll__color {
  position: absolute;
  width: 100%;
  height: 100vh;
  z-index: i1;
  background: rgba(0, 0, 0, 0.76);
  opacity: 0;
  transition: 0.5s opacity;
}

.other {
  background: white;
  z-index: 5;
}

.header {
  width: 100%;
  position: fixed;
  z-index: 6;
  text-align: center;
}
.header__text {
  padding: 5px;
  background: rgba(216, 191, 216, 0.47);
}

/*# sourceMappingURL=index.css.map */
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>scroll</title>
    <link rel="stylesheet" href="css/index.css">
</head>
<body>
    <header class="header">
        <div class="header__text">HEADER!<br>---</div>
    </header>
    <div class="wrapper">
        <main class="scroll">
            <div class="scroll__1">
                <div class="scroll__content">
                    lorem ipsum
                </div>
                <div class="scroll__color"></div>
            </div>
            <div class="scroll__f"></div>
            <div class="scroll__2">
                <div class="scroll__content">
                    lorem ipsum
                </div>
                <div class="scroll__color"></div>
            </div>
            <div class="scroll__f"></div>
            <div class="scroll__3">
                <div class="scroll__content">
                    lorem ipsum
                </div>
                <div class="scroll__color"></div>
            </div>
        </main>
        <div class="other">
            hi!<br>
            hi!<br>
            hi!<br>
            hi!<br>
            hi!<br>
            <footer>
                FOOOOOOTER!
            </footer>
        </div>
    </div>
    <script src="js/index.js"></script>
</body>
</html>

И вот scss файл. обязательно используйте именно его, иначе замучаетесь:

$scrollsCount: 3 !global;

body {
  overflow-x: hidden;
}

* {
  padding: 0;
  margin: 0;
}

.wrapper {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.scroll {
  z-index: 1;
  flex-grow: 1;
  width: 100%;
  background: blue;
  display: flex;
  flex-direction: column;
  position: relative;
  * {
    height: 100vh;
    width: 100%;
  }

  &__content {
    padding: 30px 10px 10px 10px;
    position: absolute;
    width: 100%;
    height: 100vh;
  }

  &__1 {
    background: url("http://www.alleycat.org/wp-content/uploads/2019/03/FELV-cat.jpg") center;
    background-size: cover;
  }

  &__2 {
    background: url("https://media.4-paws.org/a/5/3/7/a537f08d227326121b80790ba54036498668c9c8/VIER%20PFOTEN_2016-07-08_011-4993x3455-1920x1329.jpg") center;
    background-size: cover;
  }

  &__3 {
    background: url("https://cdn.sci.news/images/enlarge9/image_10897e-Cats.jpg") center;
    background-size: cover;
  }


  @for $i from 1 to $scrollsCount + 1 {
    &__#{$i} {
      z-index: #{$i + 1};
      .scroll__content {
        z-index: #{$i + 2};
      }
      .scroll__color {
        position: absolute;
        width: 100%;
        height: 100vh;
        z-index: #{i + 1};
        background: rgba(0, 0, 0, 0.76);
        opacity: 0;
        transition: 0.5s opacity;
      }
    }
  }
}

.other {
  background: white;
  z-index: #{$scrollsCount + 2};
}

.header {
  width: 100%;
  position: fixed;
  z-index: #{$scrollsCount + 3};
  text-align: center;
  &__text {
    padding: 5px;
    background: rgba(216, 191, 216, 0.47);
  }
}

Содержание header'а, собственно в .header.

Контент страниц лежит в .scroll scroll__<номер страницы> .scroll__content. Сейчас страницы всего 3, но можно дублировать блок scroll__<номер страницы>, обязательно между всеми .scroll__<номер страницы> должен быть пустой <div class="scroll__f"></div>. И в js скрипте в строке (6 строка, если быть точным)

for (let i = 1; i < 3; i++) {

заменить 3 на количество страниц. Вообще можно соорудить авто-определение количества страниц, не должно быть сложно. И чуть не забыл. В scss измените значение переменной $scrollsCount в начале файла на количество страниц.

Как я увидел последняя страница прокручивается как обычно. Тут для этого есть блок .other.


UPD:
немного поменял способ расчёта затемнения.

→ Ссылка
Автор решения: De.Minov

Конечно использовать самописный вариант - хорошая идея, но как по мне лучше использовать библиотеку которая специально создавалась под сложные анимации и просчёты.

Речь идёт про GSAP и плагин к нему ScrollTrigger.

gsap.registerPlugin(ScrollTrigger);

document.querySelectorAll('.slide-sections__item').forEach(function(section) {
  gsap.to(section, {
    '--shading': .75,
    scrollTrigger: {
      trigger: section,
      start: 'top top',
      //markers: true,
      pin: true,
      pinSpacing: false,
      scrub: 1
    }
  })
})
body {margin: 0;}

.slide-sections {
  display: block;
  width: 100%;
}

.slide-sections__item {
  display: block;
  width: 100%;
  height: 100vh;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
  position: relative;
  overflow: hidden;
}

.slide-sections__item::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: var(--shading, 0);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
}
<script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js"></script>
<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>

<div class="slide-sections">
  <section class="slide-sections__item" style="background-image: url('//i.imgur.com/LHyv6By.png')"></section>
  <section class="slide-sections__item" style="background-image: url('//i.imgur.com/5TnTZ59.png')"></section>
  <section class="slide-sections__item" style="background-image: url('//i.imgur.com/2ZOAae6.png')"></section>
</div>

Самописный вариант может и будет меньше весить, ибо направлен только на конкретное использование, но вот будет ли он быстрее - вопрос.

→ Ссылка