I am using Locomotive Scroll for a smooth scroll effect.
I need to change the background-color and the color of the whole HTML when reaching a certain section. At the moment I am using the call event on locomotive to add a custom function called 'updateBg' and when it is called I change wrapper's background and color.
The tricky part is that if the section is still in the viewport and I reverse the scroll it will not change the colors.
Example: If I scroll to the second intro section (AND the first intro is in the viewport) it will change to a black background. But if I scroll up it will not change to a white background as the section did not get out from the viewport and the last call was with a black background.
You have to completely pass through a section to be able to reverse the colors.
const initLocomotiveScroll = () => {
const wrapper = document.querySelector('.wrapper')
const locoScroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true
})
locoScroll.on('call', (func, dir, obj) => {
const {
el
} = obj
if ('updateBg' === func) {
const bg = el.getAttribute('data-bg')
const color = el.getAttribute('data-color')
if (dir === 'enter') {
wrapper.style.backgroundColor = bg
wrapper.style.color = color
}
}
})
}
setTimeout(() => {
initLocomotiveScroll()
}, 1000);
/* ------------------------------------------------------------ *\
Base
\* ------------------------------------------------------------ */
html {
background: #fff;
font-size: 16px;
font-weight: 500;
line-height: 1.4;
color: #000;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin-bottom: 1rem;
}
h1 {
margin-bottom: 20px;
font-size: 50px;
font-weight: 800;
line-height: 1.44;
}
h2 {
font-size: 36px;
line-height: 1.1667;
}
h3 {
font-size: 24px;
font-weight: 800;
}
h4 {
font-size: 18px;
font-weight: 600;
}
h5 {
margin-bottom: 10px;
font-size: 16px;
font-weight: 600;
text-transform: uppercase;
}
h6 {
font-size: 14px;
}
p {
margin-bottom: 1rem;
&:last-child {
margin-bottom: 0;
}
}
.text-large {
font-size: 24px;
line-height: 1.7;
}
/* ------------------------------------------------------------ *\
Wrapper
\* ------------------------------------------------------------ */
.wrapper {
overflow: hidden;
min-height: 100vh;
padding-top: 90px;
background: #fff;
color: #000;
backface-visibility: hidden;
transition: background-color .4s ease-in, color .4s ease-in;
will-change: background-color, color;
}
/* ------------------------------------------------------------ *\
Container
\* ------------------------------------------------------------ */
.container {
width: 100%;
max-width: 1156px;
padding: 0 60px;
margin: 0 auto;
}
/* ------------------------------------------------------------ *\
Fullsize Image
\* ------------------------------------------------------------ */
.fullsize-image {
position: relative;
display: block;
background-position: 50% 50%;
background-size: cover;
background-repeat: no-repeat;
&>img {
position: absolute;
top: 0;
left: 0;
height: 1px;
width: 1px;
opacity: 0;
}
}
/* ------------------------------------------------------------ *\
Intro
\* ------------------------------------------------------------ */
.intro {
position: relative;
padding: 105px 0;
&__content {
max-width: 800px;
}
&__entry {
max-width: 520px;
margin-bottom: 15px;
}
}
/* ------------------------------------------------------------ *\
Section Gutter
\* ------------------------------------------------------------ */
.section-gutter {
padding: 50px 0;
}
<script src="https://cdn.jsdelivr.net/npm/locomotive-scroll@3.5.4/dist/locomotive-scroll.min.js"></script>
<div class="wrapper" data-scroll-container>
<main class="main">
<div data-scroll-section>
<section class="intro" data-scroll data-bg="#ffffff" data-color="#000000" data-scroll-repeat="true" data-scroll-call="updateBg">
<div class="container">
<div class="intro__content">
<h5 class="intro__subtitle">
<span>Lorem ipsum dolor.</span>
</h5>
<h2 class="intro__title">If I scroll to the second intro section (AND the first intro is in the viewport) it will change to a black background. But if I scroll up it will not change to a white background as the section did not get out from the viewport and the last
call was with a black background.</h2>
<p>You have to completely pass through a section to be able to reverse back the colors.</p>
</div>
</div>
</section>
</div>
<div data-scroll-section>
<div class="section-gutter">
<div class="container">
<h1>This is section just for gutters</h1>
</div>
</div>
</div>
<div data-scroll-section>
<section class="intro" data-scroll data-bg="#000000" data-color="#ffffff" data-scroll-repeat="true" data-scroll-call="updateBg">
<div class="container">
<div class="intro__content">
<h5 class="intro__subtitle">
<span>Lorem ipsum dolor.</span>
</h5>
<h1 class="intro__title">There is some kind of bug for changing the colors of the next sections, but they are not part of the main problem. On real project, it is working correctly.</h1>
</div>
</div>
</section>
</div>
<div data-scroll-section>
<div class="section-gutter">
<div class="container">
<h1>This is section just for gutters</h1>
</div>
</div>
</div>
<div data-scroll-section>
<section class="intro" data-scroll data-bg="#ffffff" data-color="#000000" data-scroll-repeat="true" data-scroll-call="updateBg">
<div class="container">
<div class="intro__content">
<h5 class="intro__subtitle">
<span>Lorem ipsum dolor.</span>
</h5>
<h1 class="intro__title">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, asperiores?</h1>
</div>
</div>
</section>
</div>
<div data-scroll-section>
<div class="section-gutter">
<div class="container">
<h1>This is section just for gutters</h1>
</div>
</div>
</div>
<div data-scroll-section>
<section class="intro" data-scroll data-bg="#000000" data-color="#ffffff" data-scroll-repeat="true" data-scroll-call="updateBg">
<div class="container">
<div class="intro__content">
<h5 class="intro__subtitle">
<span>Lorem ipsum dolor.</span>
</h5>
<h1 class="intro__title">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, asperiores?</h1>
</div>
</div>
</section>
</div>
</main>
</div>
The only approach I think that what will work is to find the sections offset top and to set the colors based on section's offset top and locomotive's scroll delta. The problem is that the only place I can take their offsets is when call event is triggered.
How can I take all of the sections offset tops on load? Can somebody think up another workaround?