Search
Close this search box.

Play Video On Scroll Elementor Section (GSAP)

[updated_on]
Share this post:

Below is the GSAP JavaScript code that creates the effect. This needs to be put into an Elementor HTML widget BELOW the video you’re applying the effect to. It should work without you needing to add any IDs or Classes to the video widget in Elementor. If you run into problems, refer to the video above. If you would prefer to SKIP all the work and IMPORT this functionality into your site with just a few clicks, you can purchase this section below.

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.3/ScrollTrigger.min.js"></script>

<script>
/* Code written by Bjorn from WPLearningLab. Check out my WordPress YouTube channel for more awesome videos, code and webdesign inspiration! */

document.addEventListener('DOMContentLoaded', function() {
    console.clear();

    const video = document.querySelector('video');
    video.classList.add('video-background');
    const src = video.currentSrc || video.src;

    // Function to add an event listener that triggers only once
    function addOnceEventListener(element, event, handler, options) {
        function eventHandler(e) {
            element.removeEventListener(event, eventHandler);
            handler(e);
        }
        element.addEventListener(event, eventHandler, options);
    }

    // Activate video on iOS
    addOnceEventListener(document.documentElement, "touchstart", () => {
        video.play();
        video.pause();
    });

    gsap.registerPlugin(ScrollTrigger);

    // GSAP ScrollTrigger timeline
    const tl = gsap.timeline({
        scrollTrigger: {
            trigger: "#container",
            start: "top top",
            end: "bottom bottom",
            scrub: true
        }
    });

    addOnceEventListener(video, "loadedmetadata", () => {
        tl.fromTo(video, { currentTime: 0 }, { currentTime: video.duration || 1 });
    });

    // Fetch and replace video source for iOS
    setTimeout(() => {
        if ('fetch' in window) {
            fetch(src)
                .then(response => response.blob())
                .then(blob => {
                    const blobURL = URL.createObjectURL(blob);
                    const currentTime = video.currentTime;
                    
                    video.src = blobURL;
                    video.currentTime = currentTime + 0.01;

                    addOnceEventListener(document.documentElement, "touchstart", () => {
                        video.play();
                        video.pause();
                    });
                });
        }
    }, 1000);
});
</script>

Below is the ffmpeg code needed to render the perfect MP4 file for this effect to the best. Credit for this code goes to Cassie from the GSAP forum.

ffmpeg -i input.mp4 -movflags faststart -vcodec libx264 -crf 23 -g 1 -pix_fmt yuv420p output.mp4

If you’re unable to get the ffmpeg code to work you can still create this effect, but it may be a little jumpy. The most important things you need to make sure of is that the video file is an MP4 and that it is 30 frames per second. You can find online tools like this one that will convert your video to MP4 and make it 30 frames per second for free.

Share this post:

Leave a Comment

Your email address will not be published. Required fields are marked *

WPLearningLab