Here’s what I’m trying to achieve:
-when the elements become visible to the user, the scroll-driven rotate animation starts on them one-by-one,and all 3 elements become sticky (meaning that they do not disappear while the user is scrolling down) until the animation on the last one is finished.
-when the animation is finished, the page returns to its normal behavior
Executable code:
This code doesn’t make the elements sticky when needed.
document.addEventListener('DOMContentLoaded', function() {
const elements = document.querySelectorAll('.animation');
let delay = 0;
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.animationDelay = `${delay}s`;
entry.target.style.animationPlayState = 'running';
console.log('running');
// Add sticky class when the element is in view
entry.target.classList.add('sticky');
delay += 2.5; // Increase delay for the next element
observer.unobserve(entry.target); // Stop observing once the animation is triggered
}
});
}, {
threshold: 0.5
}); // Trigger when 50% of the element is in view
elements.forEach(element => {
console.log('paused');
element.style.animationPlayState = 'paused'; // Pause animation until triggered
observer.observe(element);
// Remove sticky class after the animation ends
element.addEventListener('animationend', () => {
console.log('animationend')
element.classList.remove('sticky');
});
});
});
.content {
width: 75%;
max-width: 800px;
margin: 0 auto;
}
p,
h1 {
font-family: Arial, Helvetica, sans-serif;
}
h1 {
font-size: 3rem;
}
p {
font-size: 1.5rem;
line-height: 1.5;
}
.animation {
view-timeline: --subjectReveal block;
animation-timeline: --subjectReveal;
width: 200px;
height: 200px;
background-color: bisque;
animation-iteration-count: 1;
animation-name: mymove;
animation-duration: 3s;
position: relative;
/* Normal position */
}
.animation:nth-child(1) {
animation-delay: calc(var(--subjectReveal) * 1);
}
.animation:nth-child(2) {
animation-delay: calc(var(--subjectReveal) * 2);
}
.animation:nth-child(3) {
animation-delay: calc(var(--subjectReveal) * 3);
}
/* Define the sticky behavior */
.sticky {
position: sticky;
top: 10px;
/* Adjust top as needed */
z-index: 10;
/* Ensure it stays on top */
}
@keyframes mymove {
0% {
opacity: 1;
transform: rotate(0deg);
}
50% {
opacity: 1;
transform: rotate(90deg);
}
100% {
opacity: 1;
transform: rotate(180deg);
}
}
.as-console-wrapper { height:50px; }
Scroll this
<div style="height:1000px; min-height: 300px; max-width: 100%; display: flex; flex-direction: row; justify-content: space-between; align-items: center;">
<div class="animation"></div>
<div class="animation"></div>
<div class="animation"></div>
</div>