I am trying to reproduce the effect found on this page. So the idea is that when the user scroll the tabs reveal themselves. My take on this was to use jquery to translate them along the scroll. My problem is that I gave them specific scroll area during which they will be translated but if the scroll 'jumps' out of the area they will remain out of place.
I cannot find how to fix that, any help is welcome.
Also I'm sure there are smarter ways to achieve this, feel free to point me towards something you'd rather have done.
Here is my code or a codepen to test it
Thank you for reading me and have a nice day.
var hDoc = 0;
$(".classic, .holder, .holder__item").each(function () {
hDoc += $(this).height();
});
$("body").height(hDoc);
// since both our classic and holder are 100vh, once we scrolled more than classic.height we are passed the sticky element
var hPrev = $(".classic").height();
var itemHeight = $(".item1").height();
// console.log($(window).height());
$(function () {
$(window).scroll(function () {
var pageScrolled = $(window).scrollTop();
console.log("we scrolled: " + pageScrolled);
// if we scrolled the length of hPrev(.classic) but not more then hPrev and the size of one item
if (pageScrolled > hPrev && pageScrolled < hPrev + itemHeight) {
// we translate the first item by the length scrolled minus the .classic section divided by the window height
// this calculus cant go all the way up TO FIX
// var translate = ((pageScrolled - hPrev) / $(".classic").height()) * 100;
$(".item1").css({
transform: "translateY(-" + (pageScrolled - hPrev) + "px"
});
// "transform": "translateY("+ transform + $(window).scrollTop() +"px)"
} else if (
pageScrolled > hPrev + itemHeight &&
pageScrolled < hPrev + itemHeight * 2
) {
// var translate = ((pageScrolled - hPrev ) / $(window).height()) * 100;
$(".item2").css({
transform: "translateY(-" + (pageScrolled - (hPrev + itemHeight)) + "px"
});
}
});
});
// This function could be a for each
// bumper avant chaque item, quand on scroll dans son range le titre translate sur la droite
*,
*::before,
*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
html,
body {
height: 100%;
scroll-behavior: smooth;
}
section {
height: 100vh;
}
.classic {
background-color: pink;
}
.holder {
text-align: center;
display: flex;
justify-content: center;
align-items: center;
// sets it as sticky so that we can have all the scroll space we need but still visually end on this section
position: sticky;
top: 0px;
overflow: hidden;
& h2 {
font-size: 6rem;
}
&__item {
height: 100vh;
width: 100vw;
position: absolute;
&.item1 {
height: calc(100vh - 80px) !important;
top: calc(100vh - 80px) !important;
border: 1px solid black;
background-color: teal;
}
&.item2 {
height: calc(100vh - 60px) !important;
top: calc(100vh - 60px) !important;
border: 1px solid red;
background-color: crimson;
}
&.item3 {
height: calc(100vh - 40px) !important;
top: calc(100vh - 40px) !important;
border: 1px solid purple;
background-color: DarkSalmon;
}
&.item4 {
height: calc(100vh - 20px) !important;
top: calc(100vh - 20px) !important;
background-color: tomato;
border: 1px solid blue;
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="classic">
</section>
<section class="holder">
<div class="holder__placeholder">
<h2>Hello world.</h2>
<p>Nice to see you again.</p>
</div>
<div class="holder__item item1">
<p>hello hello</p>
</div>
<div class="holder__item item2"></div>
<div class="holder__item item3"></div>
<div class="holder__item item4"></div>
</section>