I’m trying to achieve something very similar to hero section on Apple website (video seek on scroll).
The Problem:
The transition between different scroll positions and video playback states isn’t smooth.
Things I Tried:
- Using
Number.prototype.toFixed()
- Limit updates to roughly 60 FPS (ensures that the video’s currentTime is updated roughly every 16 milliseconds, which corresponds to approximately 60 frames per second)
The Code:
const video = document.getElementById('video');
const section = document.getElementById('video-container');
const sectionHeight = section.clientHeight;
video.onloadedmetadata = () => {
// Get video duration
const videoDuration = video.duration;
window.addEventListener('scroll', function() {
const scrollTop = window.scrollY;
const sectionTop = section.getBoundingClientRect().top;
const sectionHeight = section.offsetHeight;
// Calculate scroll progress within the section
const scrollProgress = (scrollTop - sectionTop) / sectionHeight;
// Ensure scroll progress is within the range [0, 1]
const normalizedProgress = Math.max(0, Math.min(1, scrollProgress));
// Update video currentTime based on scroll progress
video.currentTime = normalizedProgress * videoDuration;
});
};
#video-container {
width: 100%;
height: 2000px;
}
video {
position: sticky;
position: -webkit-sticky;
top: 0;
display: block;
width: 100%;
height: auto;
}
<div id="video-container">
<video id="video" src="https://www.w3schools.com/html/mov_bbb.mp4"></video>
</div>