Jump to content
Search Community

Start the same SplitType animation on different div

3mo test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hello,

I'm new to GSAP, so I apologize in advance if my problem could have been solved simply.
I have an HTML structure that looks like this:

        <div class="chapter chapter-1">

            <div class="page page-1">
                <div class="sheet">
                    <p class="storyline">Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci commodi optio fugiat eum porro provident necessitatibus vitae. Quis, doloremque inventore recusandae aperiam dolore adipisci blanditiis est dolorum architecto dicta quasi?</p>
                    <i class="fa-solid fa-circle-left reading-btn previous-chapter"></i>
                    <i class="fa-solid fa-circle-chevron-right reading-btn next-page"></i>
                </div>
            </div>

 

Of course, there are several chapters (chapter-1, chapter-2, ...) which themselves have several pages (page-1, page-2, ...).

I'd like to run a SplitType animation on my <p class="storyline">  each time it or its parent <div class="sheet"> enters the viewport.

To achieve this, I wrote the following code:

    for (let indexPage = 0; indexPage < storyLines.length; indexPage++) {
        const numPage = indexPage + 1;

        console.log('Chapter ' + numChapter);
        console.log('Page ' + numPage);
        // I used this console.log only to make sure I had the right chapter and page number

        const line = new SplitType(`.chapter-${numChapter} .page-${numPage} .storyline`, { types: 'chars' });

        gsap.fromTo(`.chapter-${numChapter} .page-${numPage} .char`,
            { 
                y: 100,
                opacity: 0
            },
            {
                y: 0,
                opacity: 1,
                stagger: 0.1,
                duration: 3,
                delay: 3,
                ease: 'power4.out',
                scrollTrigger: {
                    trigger: `.chapter-${numChapter} .page-${numPage} .storyline`,
                    toggleActions: "play none reverse none"
                }
            }
        )
    }

This loop is itself in another loop:

for (let indexChapter = 0; indexChapter < chapters.length; indexChapter++) {

    const numChapter = indexChapter + 1;

 

I've encountered two main problems: either the animations don't trigger, or they trigger at the same time, so by the time I got to the next page, the animation had already begun.

 

Thank you in advance, my code is not clean, I apologize.

See the Pen Rwqrrga by IListenToLofi (@IListenToLofi) on CodePen

Edited by 3mo
CodePen URL
Link to comment
Share on other sites

It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or CodeSandbox that demonstrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

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

 

If you're using something like React/Next/Vue/Nuxt or some other framework, you may find StackBlitz easier to use. We have a series of collections with different templates for you to get started on these different frameworks: React/Next/Vue/Nuxt.

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

Link to comment
Share on other sites

31 minutes ago, GSAP Helper said:

It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or CodeSandbox that demonstrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

 

 

If you're using something like React/Next/Vue/Nuxt or some other framework, you may find StackBlitz easier to use. We have a series of collections with different templates for you to get started on these different frameworks: React/Next/Vue/Nuxt.

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

Alright, I will try.

Link to comment
Share on other sites

at a first glance your code looks pretty good. no glaring errors but of course I have no idea how a dynamic selector like

 

`.chapter-${numChapter} .page-${numPage} .storyline`

 

is actually accurate or working, which is why a minimal demo is so important.

 

 

perhaps using something like this as a starting point will help.

 

See the Pen VwVLOBB by snorkltv (@snorkltv) on CodePen

 

Add complexity until it breaks.

I don't know what splitType is so I used GreenSock's SplitText

 

Definitely put markers: true to test your triggers and measurement.

 

Also I find it helpful to test each selector to make sure it's working with something like a simple color change like

gsap.set(`.chapter-${numChapter} .page-${numPage} .storyline`, {color:'red'})

 

 

 

 

  • Like 4
Link to comment
Share on other sites

Excuse me, I've run into some trouble with CodePen, if I can sort it out I'll share a link.
In the meantime, I've noticed something with the isInViewport() function. As soon as I scroll a bit, all my pages are considered in the viewport even if they're not yet visible. My project is quite complex, consisting of several sections each 100% the size of the viewport. Here's a scheme that might clarify things for you https://www.tldraw.com/r/v27csguvzfDD-U9eSBNrVf_
As soon as I have time, I'll try to solve this problem without using getBoundingClientRect() if possible.

Link to comment
Share on other sites

Hm, I don't see any of that code in the CodePen you provided. No ScrollTrigger code at all. Nothing matched the sample code higher up in your post. 


Here are some tips that will increase your chance of getting a solid answer:
 

  • A clear description of the expected result - "I am expecting the purple div to spin 360degrees"
  • A clear description of the issue -  "the purple div only spins 90deg"
  • A list of steps for someone else to recreate the issue - "Open the demo on mobile in IOS safari and scroll down to the grey container" 
  • A minimal demo - if possible, using no frameworks, with minimal styling, only include the code that's absolutely necessary to show the issue. Please don't include your whole project. Just some colored <div> elements is great.

 

Link to comment
Share on other sites

12 hours ago, GreenSock said:

Hm, I don't see any of that code in the CodePen you provided. No ScrollTrigger code at all. Nothing matched the sample code higher up in your post. 


Here are some tips that will increase your chance of getting a solid answer:
 

  • A clear description of the expected result - "I am expecting the purple div to spin 360degrees"
  • A clear description of the issue -  "the purple div only spins 90deg"
  • A list of steps for someone else to recreate the issue - "Open the demo on mobile in IOS safari and scroll down to the grey container" 
  • A minimal demo - if possible, using no frameworks, with minimal styling, only include the code that's absolutely necessary to show the issue. Please don't include your whole project. Just some colored <div> elements is great.

 

Sorry, I hope this new version will be easier to understand :

GSAP Starter Template (codepen.io)

 

My aim is to launch an animation on the text of each <div class="sheet"> when the latter is in the viewport. 

When rewriting my code in CodePen, I noticed that isInViewport(element) returned true if element was in the viewport horizontally (as if the viewport were 100vh high but 100% of the body wide instead of 100vw).

So I'd like a way for isInViewport(element) to return true only if (element) is "really" visible.

I hope this description is clearer.

Link to comment
Share on other sites

  • Solution

Yes, that's because that method is focused on one direction only (in the vast majority of cases, developers only want their page to scroll in one direction, vertically or horizontally and we wanted to optimize performance accordingly). It's still quite easy to accomplish. Here are two options: 

 

1) Call the method once to check vertically (default) and again to check horizontally

document.addEventListener("scroll", updateValues, {passive: true});

function updateValues() {
  viewport.innerText = ScrollTrigger.isInViewport(sheet) && ScrollTrigger.isInViewport(sheet, 0, true);
}

2) Or just use IntersectionObserver

let observer = new IntersectionObserver(handleIntersect);
observer.observe(sheet);
function handleIntersect(entries) {
  entries.forEach(entry => {
    viewport.innerText = entry.isIntersecting;
  })
}

I hope that helps.

Link to comment
Share on other sites

19 hours ago, GreenSock said:

Yes, that's because that method is focused on one direction only (in the vast majority of cases, developers only want their page to scroll in one direction, vertically or horizontally and we wanted to optimize performance accordingly). It's still quite easy to accomplish. Here are two options: 

 

1) Call the method once to check vertically (default) and again to check horizontally

document.addEventListener("scroll", updateValues, {passive: true});

function updateValues() {
  viewport.innerText = ScrollTrigger.isInViewport(sheet) && ScrollTrigger.isInViewport(sheet, 0, true);
}

2) Or just use IntersectionObserver

let observer = new IntersectionObserver(handleIntersect);
observer.observe(sheet);
function handleIntersect(entries) {
  entries.forEach(entry => {
    viewport.innerText = entry.isIntersecting;
  })
}

I hope that helps.

Thank you very much, that's exactly what I needed

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...