Jump to content
Search Community

Element animation and pinning based on other element

Xurshed test
Moderator Tag

Recommended Posts

Hello guys, I am trying to make a component like https://b14.dk/14years/ exactly, but I couldn't get the result that I want. I hope you guys can help me with this problem. I am not understanding the logic of this component. Thank you! But it is very urgent

 

 

 

ort React, {useEffect} from "react";
import {Wrapper, Image, Container, FirstChild, SecondChild, BeImage} from "./style";
import {gsap} from 'gsap'
import {ScrollTrigger} from 'gsap/ScrollTrigger';

const BeBold = () => {
    gsap.registerPlugin(ScrollTrigger);
    useEffect(() => {
        const beText = document.querySelector('.bla-hello');
        gsap.timeline({
            scrollTrigger: {
                trigger: beText,
                start: "top top",
                end: "bottom top",
                scrub: true,
                pin: '#first-child',
            }
        });



        const sections = gsap.utils.toArray('.imageToShow');

        console.log(sections)
        let tl = gsap.timeline();
        sections.forEach((section, index) => {
          
            tl.to(section, {
                scale: 1.2,
                scrollTrigger: {
                    trigger: section,
                    start: 'top bottom -= 300',
                    toggleActions: 'play none none reverse',
                    scrub: true,
                }
            })  
.to('#img500', {
                scrollTrigger: {
                    trigger: beText,
                    start: 'top 0',
                    scrub: true,
                },
                opacity: 1
            })
    return (
        <div>
            <Wrapper>
                <Container className="bla-hello">
                    <FirstChild id={"first-child"}>
                        <BeImage id="img101" src="https://b14.dk/14years/images/bebold/be-bold-be.svg"
                                 alt="kitty"/>
                    </FirstChild>
                    <SecondChild>
                        <Image id="img100" className="imageToShow"
                               src="https://b14.dk/14years/images/bebold/be-bold-light.svg"
                               alt="kitty"/>
                        <Image id="img200" className="imageToShow"
                               src="https://b14.dk/14years/images/bebold/be-bold-book.svg"
                               alt="kitty"/>
                        <Image id="img300" className="imageToShow"
                               src="https://b14.dk/14years/images/bebold/be-bold-medium.svg"
                               alt="kitty"/>
                        <Image id="img400" className="imageToShow"
                               src="https://b14.dk/14years/images/bebold/be-bold-demi.svg"
                               alt="kitty"/>
                        <Image id="img500" className="imageToShow"
                               src="https://b14.dk/14years/images/bebold/be-bold-bold.svg"
                               alt="kitty"/>
                    </SecondChild>
                </Container>
            </Wrapper>
        </div>
    )
}

export default BeBold;

This code is written in react.

Screenshot 2021-07-17 180009.png

Link to comment
Share on other sites

Hey,

 

One should determine the relevant distance for the 'containerRight'.
There is a catch though: After window resize, the scroll trigger for the words does not work correctly.
Unfortunately I can't find the bug, don't understand the logic.
In addition, here in the iframe and in debug mode 'y: -515' leads to a different result.

 

See the Pen poPwzae by mikeK (@mikeK) on CodePen

 

May the experts have an answer.

Mikel

  • Like 1
Link to comment
Share on other sites

21 hours ago, mikel said:

There is a catch though: After window resize, the scroll trigger for the words does not work correctly.
Unfortunately I can't find the bug, don't understand the logic.

The main problem is that you're shifting around the y position of the words with a PREVIOUS ScrollTrigger, thus when it refreshes all the start/end values they're post-shift (the animation is tainting the positions). Just set the refreshPriority of that first one to a lower number (or the other ones to a higher number) so that the calculations occur in the proper order and the positions aren't tainted by the  shift: 

See the Pen vYmZepb?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Other notes:

  • You don't need to add a "resize" listener that calls ScrollTrigger.refresh() because it already does that internally in a more optimized way (waiting until 200ms passes of it being still so that it doesn't bog down). 
  • If you're only putting one tween into your timeline, there's no reason to create a timeline at all. It's fine, but just extra code. 
  • invalidateOnRefresh is only useful when you have function-based values in your animations. In this case, it was wasteful/useless.  

Happy tweening!

  • Like 3
Link to comment
Share on other sites

In order to 'stop' the user for a second you could exclude the last h1 from the words loop and then add that final text fade on to the end of the right column animation.

Then the right column will move up, the last h1 will fade in and then the section will unpin.

See the Pen 9b1aff7c794bfad7383d140a31be9534?editors=1111 by cassie-codes (@cassie-codes) on CodePen

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