Home > Enterprise >  How to trigger CSS keyframe animation based on scroll position?
How to trigger CSS keyframe animation based on scroll position?

Time:09-07

I want to trigger a circle fadeIn animation based on the user scroll position. With every scroll down, the circle gets bigger. With every scroll up, the circle gets smaller.

The animation would stop if the user is not scrolling anymore - so the user has to scroll a few times for the animation to be complete. If the scrolling stops, the circle would remain at a certain width (depending on how much he scrolled up/down).

I only have it running with basic CSS and HTML at the moment. I am missing JS the scroll function that would trigger the circle getting bigger/smaller depending on how much the user scrolls in the background.

.section {
      animation: 3s fadeInAnimation reverse;
      animation-delay:0s;
      animation-timing-function: ease-in-out;
        animation-iteration-count: 1;
      background: yellow;
      height: 100vh;
    }
    
    @keyframes fadeInAnimation {
        0% { 
                clip-path: circle(75%); 
        }
      100% { 
            clip-path: circle(0%); 
        }
    }
<div >
<h1>
Section Title
</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>
</div>

Fiddle Here

CodePudding user response:

This is a perfect scenario for using a CSS Custom Property and updating its value via JavaScript whenever the window is scrolled.

If we initially set the following custom property:

  • :root { --clip-circle: 0% }

We can then update the value of that custom property at any time by:

  • re-calculating clipCircleValue
  • document.documentElement.style.setProperty('--clip-circle', clipCircleValue);

Working Example (click Full Page) :

const updateClipCircleValue = () => {

  let documentScrollHeight = document.documentElement.scrollHeight;
  let documentScrollPosition = window.scrollY;
  let documentScrollPercentage = ((documentScrollPosition / documentScrollHeight) * 100);
  let clipCircleValue = documentScrollPercentage   '%';
  
  document.documentElement.style.setProperty('--clip-circle', clipCircleValue);
}

window.addEventListener('scroll', updateClipCircleValue);
:root {
  --clip-circle: 0%;
}

body {
  min-height: 400vh;
}

.section {
  position: fixed;
  top: 0;
  left: 0;
  background-color: rgb(255, 255, 0);
  clip-path: circle(var(--clip-circle));
}
<div >
<h1>
Section Title
</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut tincidunt commodo lacus vitae porttitor. Morbi lobortis diam lorem, sed faucibus leo gravida ac. Curabitur ex velit, consectetur vitae ligula in, fringilla tincidunt turpis. Curabitur sem turpis, scelerisque et pretium in, ornare at dui. Morbi pellentesque viverra rhoncus. 
</p>
</div>

CodePudding user response:

If it has to be linked with the distance scrolled from the top i would make an event listener in order to track the distance from the top of the page.

  • Related