Jump to content
Search Community

ScrollTrigger Video Animation - Astro

EdoRaba test
Moderator Tag

Go to solution Solved by Cassie,

Recommended Posts

I'm building a site using the Astro framework, where there will be video animations on scroll.
Unfortunately using this framework it is not possible for me to create a demo on CodePen but I recorded a video to show the problem (here is the link to the site in production).
The problem is that sometimes when I refresh the page the second section overlaps the first after a slight scroll (you notice when the error occurs because you see the "start" marker of the second section just below the first section, and therefore before the "end" marker of the first section).

In the video, from seconds 01 to 07 the site loaded ScrollTrigger correctly, while from second 08 onwards, after the refresh, as you can see, the second section ends above the first, before it can finish scrolling.

Do you have any idea what it could be even without having a demo? is this a known scrollTrigger issue or can it be caused by the framework?


This is the index.astro:
 

---
import Layout from '../layouts/Layout.astro';
import VideoScroll from '../components/VideoScroll.astro';
---

<script>
	gsap.registerPlugin(ScrollTrigger);
</script>

<Layout title="TUC">
	<main>
		<section class="container relative min-h-screen py-6 mx-auto" id="home">
			<VideoScroll
				client:load
				section={1}
				main="Hello TUC"
				title="LOREM IPSUM"
				description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
				video="/video/esploso_edit.mp4"
			/>
		</section>
		<section class="container relative min-h-screen py-6 mx-auto" id="technology">
			<VideoScroll
				client:load	
				section={2}
				main="All in one"
				title="LOREM IPSUM"
				description="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
				video="/video/sedile_edit.mp4"
			/>
		</section>
	</main>
</Layout>


And this is how I created the components (.astro):

---
export interface Props {
    section: number;
    main: string;
    video: string;
	title: string;
    description: string;
}

const { section, main, video, title, description } = Astro.props;
---

<script>
    class VideoScroll extends HTMLElement {
        constructor() {
        super();

        // Read the message from the data attribute.
        const section = this.dataset.section;

        const IntroVideoRef = document.getElementById(`section-${section}`);
        const videoRef = document.getElementById(`video-section-${section}`); 
        videoRef.onloadedmetadata = function() {
            const pauseVideo = () => { 
                videoRef.removeAttribute("autoplay");
                videoRef.currentTime = 0;
                videoRef.pause();
                gsap.delayedCall(4, () => ScrollTrigger.refresh());
            }
            
            if (videoRef) {
                pauseVideo()
            }

            const videoDuration = this.duration;

            ScrollTrigger.create({
                trigger: IntroVideoRef,
                scrub: true,
                pin: IntroVideoRef,
                start: '-100',
                end: `+=${videoDuration * 300}`,
                markers: true,
                onUpdate: function(self) { 
                    if (videoRef) {
                    const scrollPos = self.progress;
                    const videoCurrentTime = videoDuration * scrollPos;
                    if(videoCurrentTime) {
                        videoRef.currentTime = videoCurrentTime;
                    }
                    }
                },
            });
            console.log(videoTime)
        };  
        
    }
  }
  customElements.define('video-scroll', VideoScroll);
</script>

<video-scroll data-section={section}>
    <div class='w-full h-full hyperboards-container min-h-[200px] md:min-h-[300px]' id={`section-${section}`}>
        <div class='flex justify-end w-full translate-y-[30px] lg:translate-y-[70px]'>
            <h2 class='text-4xl font-bold md:text-7xl text-grey'>
                {main}
            </h2>
        </div>
        <div class='grid grid-cols-1 gap-4 md:grid-cols-12'>
            <div class='w-full col-span-1 col-start-1 overflow-hidden rounded-xl video-col md:col-span-7 md:col-start-2'>
            <video muted playsinline autoplay disableRemotePlayback id={`video-section-${section}`} class="min-h-[200px]">
                <source src={video} type="video/mp4"/>
            </video>
            </div>
            <div class='col-span-1 section-text md:col-span-4'>
                <h4 class='bold text-[25px] text-white'>{title}</h4>
                <p class='light text-light-grey'>{description}</p>
            </div>
        </div>
    </div>
</video-scroll>

<style>
    .section-text {
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
    }
</style>


You will probably have to refresh a few times to get both versions (working and not working).

 

Link to comment
Share on other sites

Hey there!

It's very hard for us to debug live sites I'm afraid, can you replicate this in a vanilla demo? If you can replicate the issue without astro then we can focus on that, and if not then we know it's an astro integration issue. It's a good first step!

 

Here's a starting point for you.

 

See the Pen bGxQBqO by GreenSock (@GreenSock) on CodePen

 

 

Link to comment
Share on other sites

Hey @Cassie, thanks for the reply!

 

Here is the CodePen

See the Pen YzORaGR?editors=1010 by edoardo-baravaglio (@edoardo-baravaglio) on CodePen

 

I partially reproduced the site on CodePen in vanilla javascript, and surprisingly the error still exists!
I'm almost certainly doing something wrong...
In addition to linking the CodePen, I am also attaching a screen recording showing the bug.
From second 01 to 11 it works fine, when I refresh at second 12 it doesn't seem to load gsap (an error that often happened to me even before and I haven't solved).
From the second 29 the bug I was talking about is created.
So I ask you again to try to refresh the CodePen sometimes to replicate the errors.

Link to comment
Share on other sites

  • Solution

Heya!

 

It's important to create your ScrollTriggers in the code in the same order they appear on the page

 

In your demo the creation is dependant on which video loads first, you can get around this by adding a refreshpriority on your ScrollTriggers and then calling .sort to order them correctly.

 

Here - I simplified it down and moved them out of order, without refreshPriority and sort it breaks, but if you comment those lines in it should work as expected.

See the Pen WNgYgBK?editors=0011 by GreenSock (@GreenSock) on CodePen



Hope this helps!

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...