I am trying to animate four headings as the user scrolls. First I create a sticky
positioned div, then the user scrolls over the headings toggling the class .active
one at a time, leaving the last one visible and continuing scrolling to the last div.
The problem I am having is that once the .sticky
div becomes sticky the browser no longer detects further scrolling until the div becomes non-sticky again.
— UPDATE
I have changed the code to transition sequentially and works better, but I would like to start the animations only when the .sticky
div becomes sticky, but I tried that and the scroll animation stops working completely. Also, I would like to keep all headings on the same block but If I do position: absolute
on them it breaks the animations too.
const headings = Array.from(document.querySelectorAll('.animated-text'));
const sticky = document.querySelector('.sticky');
let currentActive = null;
window.addEventListener('scroll', () => {
const viewportHeight = window.innerHeight;
headings.forEach((heading, index) => {
const headingRect = heading.getBoundingClientRect();
if (headingRect.top <= viewportHeight / 2) {
if (currentActive) {
currentActive.classList.remove('active');
}
heading.classList.add('active');
currentActive = heading;
}
});
});
body {
margin: 0
}
section {
position: relative;
}
.sticky {
padding-bottom: 150px;
background: #2d232c;
position: sticky;
top: 0;
overflow: hidden;
height: auto;
color: white;
}
.animated-text {
opacity: 0;
height: 0;
overflow: hidden;
transition: opacity 1s ease, height 1s ease, transform 1s ease;
transform: translateY(0);
}
.animated-text.active {
height: auto;
opacity: 1;
transform: translateY(-20px);
}
.hero, .end {
height: 100px;
background: white;
}
<section class='hero'>
<p>Start</p>
</section>
<section class='sticky'>
<div class='text-animations'>
<h1 class='animated-text active'>Intro</h1>
<h2 class='animated-text'>First</h2>
<h2 class='animated-text'>Second</h2>
<h2 class='animated-text'>Third</h2>
</div>
<p class='intro_content'>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam
</p>
</section>
<section class='end'>
<p>End<p>
</section>
2
Answers
It looks like you are trying to create an animation effect for your headings as the user scrolls and the sticky div comes into view. However, the current code only handles the scroll event once, and the scrolling doesn’t continue after the .sticky div becomes sticky.
To achieve the desired effect of toggling the "active" class for the headings one by one as the user scrolls, you’ll need to continuously check the scroll position and update the active heading accordingly. You can achieve this by using the getBoundingClientRect() method to determine the positions of the headings relative to the viewport.
With this updated code, as the user scrolls and the .sticky div becomes sticky, the browser will continue to detect further scrolling and update the "active" class for the headings accordingly, providing the desired animation effect for the headings one by one.
As per the requirementm for positioning all headings at the top, adding
in
.active
class resolves the problem.And for starting animation only when the
div
becomes sticky, the stickyDiv position needs to be compared and then the animation logic should be implemented.I have tried to put the logic for transitioning of headings on the basis of scroll up or down event too so that the heading transition correctly in order irrespective of scroll direction.
I am aware the code requires a lot of refactoring, but I hope it works as per the requirement.
The full code snippet is as follows:-
Please feel free to ask if any part of the logic is unclear or require clarification.