Back

Scroll Effects on Videos with JavaScript

Scroll Effects on Videos with JavaScript

Images and videos serve as crucial ingredients for crafting visually engaging websites. However, relying solely on static images and videos with manual controls can become monotonous. This article goes beyond the basics and explores how videos can be smoothly integrated with scrolling.

Instead of just talking about typical scroll effects (like fade/slide in on scroll or scroll reveal animations), we’ll look at how videos can become part of the scrolling experience, making websites more engaging. This involves manipulating video frames through scrolling, as well as pausing or playing a video when it comes into the page view, among other functionalities.

Understanding the Video API

To implement scroll effects on videos using JavaScript, it’s crucial to grasp the Video API, which provides a set of methods and properties for interacting with HTML video elements.

Here’s a straightforward method to showcase a video using the HTML <video> element:

<video controls>
  <source src="video.mp4" type="video/mp4" />
  <source src="video.webm" type="video/webm" />
  <!-- fallback content here -->
</video>

The most important attribute here is controls. This attribute allows the user to play/pause and control other video elements. If you remove this, the user will have no manual control of the video. The <video> element can contain two <source> elements so that different formats can be loaded depending on the browser viewing the site.

Now, let’s look at the properties and methods that JavaScript provides.

Video Element Methods

  • JavaScript Video Object: To manipulate videos in JS, we need to first access the video. You can use any JavaScript selection method here. In this case, we get the video using its id “videoID”.
const video = document.getElementById('videoID');
  • Play and Pause: Using these functions, you can play and pause a video. These functions can be linked to custom buttons, for example.
video.play(); 
video.pause();
  • Load: You can reload a video using this method.
video.load();
  • Manipulate Controls: You can also manipulate the controls attribute through JavaScript.
video.removeAttribute("controls");

Video Element Properties

  • Video Duration: This returns the total duration of the video in seconds.
const videoDuration = video.duration;
  • Control Autoplay: When loaded, you can get or set whether the video should start playing automatically.
const AutoplayEnabled = video.autoplay;
video.autoplay = true; 
  • Get and set volume: Get the current volume and also set it (from 0.0 to 1.0).
const currentVolume = video.volume;
video.volume = 0.75; // Set volume to 75%
  • Current Time: Jump to specific points in the video by manipulating the currentTime attribute.
video.currentTime = 30; // set the playback time to 30 seconds

The currentTime attribute is particularly important for more complex animations as it can be linked to properties such as scroll values, etc.

Video Event Listeners

There are also multiple video-specific event listeners that won’t be used in this article but are good to know:

  • timeupdate: Fired when the current playback position changes.
  • ended: Fired when the video ends.
  • loadedmetadata: Fired when the metadata (such as duration or volume) is loaded.
  • progress: Fired as the browser loads the video data.

Playing Videos When Scrolled To

Now, let’s create a practical example using our knowledge of the video API. Let’s say you have a video on your site that you want to play automatically, but the video needs to be scrolled to. If we can detect when it comes into the user’s view, we can start it directly, as opposed to having it play when it is not visible.

Firstly, to detect if the video is in view, we can use a simple formula:

rect.top >= 0 &&
rect.left >= 0 &&
rect.right <= windowWidth &&
rect.bottom <= windowHeight

windowWidth and windowHeight represent the visible height and width of the browser window. The formula checks if all four sides of the video are within the viewport. If this condition is met, we play the video; otherwise, we pause it. This logic is encapsulated in a function named isVideoInViewport, linked to the scroll event.

document.documentElement.clientWidth ensures compatibility across various browsers, as some browsers may use one property while others use the alternative.


Note: this pen is best viewed fullscreen.

Manipulating Video Playback Position

Let’s look at how we can control video playback using JavaScript. With this information, videos can be played based on, for example, scroll values or other forms of user input.

As discussed earlier, video.currentTime is essential. We can also control the playback rate using this line:

// Set the playback speed to 1.5x
video.playbackRate = 1.5;

Let’s create a simple example where the user can input a specific time, and the video will jump to that point. Firstly, we will get the user input (in seconds). Make sure to validate that the time is not less than 0 and greater than the video duration. We can then use video.currentTime to set the playback position.

The demo and code can be seen below:

Playing a Video Using Scroll Values

Now, let’s get to the main example of this article. We will create a demo in which a video is played as the user scrolls. This will be done both forward and backward. This effect is very common and can give off an illusion of a 3d modal being moved on scroll. However, it is usually just a fullscreen video based on scroll values.

Let’s look at the main steps we need to follow:

  1. One initial challenge is the inability to create a scrollbar that mirrors the length of the video, allowing users to scroll through it using traditional HTML and CSS. To address this, we will implement a JavaScript function that dynamically adjusts the height of a div element encapsulating the video based on the video’s duration. We will use the video loadedmetadata event listener for this. We also will use a speed constant variable in the formula. Increasing this constant will result in a longer scrollbar and slower video playback, while decreasing it will have the opposite effect.
// get video element
const video = document.getElementById("myVideo");
const container = document.getElementById("videoContainer");

// set the container height according to video length
video.addEventListener('loadedmetadata', function() {
  const speed = 250; // can be any number (adjust to your preference)
  container.style.height = (video.duration * speed) + 'px';
});
  1. Get the Scroll Y position and convert it into a percentage of the total page height. This is quite simple. We will create a function linked to the scroll event in which all the logic will be present. The formula will be something like this.
// get current scroll progress
var scrollY = window.scrollY;
// get total page height and calculate percentage
var height = document.documentElement.scrollHeight - window.innerHeight;
var percentage = scrollY / height;
  1. Use this calculated percentage to set the currentTime of the video, syncing the video playback with the scroll progress.
// set video playback position.
video.currentTime = video.duration * percentage;
  1. Smoothen things out: Lastly, we will use the requestAnimationFrame function to enhance the smoothness of video playback during scrolling.
 window.requestAnimationFrame(playVideo);

The complete code and demo can be seen below:

Conclusion

Adding scroll effects to videos is a fantastic way to elevate user engagement and enhance the visual appeal of websites. With the help of the Video API and JavaScript, you can integrate videos into the scrolling experience, providing users with a dynamic and engaging experience.

Credits

Both the videos used and this example are inspired by these two examples. A third is attached for further reference.

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay