Как повторить эффект скролла
есть сайт: https://www.nobili.it/ru/
Как сделать такой же эффект перехода между блоками "как будто друг на друга смещаются когда скролить вниз",
Из того что я нашел на сайте примере есть модуль "HPSections" но в гугл толком ничего про такой модуль не известно, и достать файл "hpsections.js" с самого сайта не могу
Ответы (2 шт):
Если совсем быстро что-то приготовить, то ниже есть пример (запускайте и разворачивайте на весь экран что бы было лучше видно).
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:
немного поменял способ расчёта затемнения.
Конечно использовать самописный вариант - хорошая идея, но как по мне лучше использовать библиотеку которая специально создавалась под сложные анимации и просчёты.
Речь идёт про 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>
Самописный вариант может и будет меньше весить, ибо направлен только на конкретное использование, но вот будет ли он быстрее - вопрос.