Jump to content
Search Community

Okaka

Members
  • Posts

    6
  • Joined

  • Last visited

Posts posted by Okaka


  1. https://codesandbox.io/p/devbox/mutable-sunset-phspgm
     

    Your advice so far has been very helpful.
    My ultimate goal is to create this as a wordpress block.
    One of the things I am wondering is if it is possible to place an arbitrary DOM element or component and have it end at that location, instead of determining the end of the animation or pin (fixed end) based on the number of images.
    If you have any ideas, I would like to hear them.
    Thank you in advance.

    demo 
    # gsap demo
    https://codesandbox.io/p/devbox/mutable-sunset-phspgm?file=%2Fapp%2Fpage.tsx%3A93%2C75

    # canva demo
    https://codesandbox.io/p/devbox/mutable-sunset-phspgm?file=%2Fapp%2Fcanvademo%2Fpage.tsx%3A21%2C14

  2. 7 minutes ago, GSAP Helper said:

    Hi there! I see you're using React -

    Proper animation cleanup is very important with frameworks, but especially with React. React 18 runs in strict mode locally by default which causes your useEffect() and useLayoutEffect() to get called TWICE.

    In GSAP 3.11, we introduced a new gsap.context() feature that helps make animation cleanup a breeze. All you need to do is wrap your code in a context call. All GSAP animations and ScrollTriggers created within the function get collected up in that context so that you can easily revert() ALL of them at once.

    Here's the structure:

    // typically it's best to useLayoutEffect() instead of useEffect() to have React render the initial state properly from the very start.
    useLayoutEffect(() => {
      let ctx = gsap.context(() => {
        // all your GSAP animation code here
      });
      return () => ctx.revert(); // <- cleanup!
    }, []);

    This pattern follows React's best practices, and one of the React team members chimed in here if you'd like more background.

    We strongly recommend reading the React information we've put together at https://gsap.com/resources/React/

    Happy tweening!

    Thanks for the reply!
    I see that it consisted of the React v18 spec.
    I'm very impressed with your advice, which is based on a wide range of knowledge.

  3. On 11/27/2023 at 10:55 PM, mvaneijgen said:

    Here is a simple timeline that tweens through images,

     

    Instead of having a tween for each image you probably want to create a loop or use the stagger object https://gsap.com/resources/getting-started/Staggers

     

     

     

     

    if you would hook this up to ScrollTrigger it would just work.

     

     

     

    Thank you for your reply and advice.
    I am aiming to implement this in Next.js.
    I have tried to implement the suggested code here in Next.js.
    While it works for reverse scrolling, it does not work for forward scrolling.
    The pin works incorrectly.

     

    import React, { useLayoutEffect, useRef } from "react";
    import gsap from "gsap";
    import { ScrollTrigger } from "gsap/dist/ScrollTrigger";
    import { css } from "../../../../styled-system/css";
    
    gsap.registerPlugin(ScrollTrigger);
    
    const Parallax07 = () => {
      const imagesRef = useRef<HTMLDivElement | null>(null);
    
      const styles = {
        imageStyle: css({
          position: "absolute",
          top: 0,
          left: 0,
          width: "600px",
          opacity: 0,
        }),
      };
    
      useLayoutEffect(() => {
        const images = imagesRef.current?.children;
    
        if (!images) return;
    
        const tl = gsap.timeline({
          scrollTrigger: {
            trigger: imagesRef.current,
            start: "top top",
            end: "bottom+=3000px top",
            scrub: true,
            pin: true,
            markers: true,
          },
        });
    
        Array.from(images).forEach((img, index) => {
          tl.to(img, {
            opacity: 1,
            duration: 1,
            ease: "none",
          }).to(
            img,
            {
              opacity: 0,
              duration: 1,
              ease: "none",
            },
            `+=${index}`
          );
        });
      }, []);
    
      return (
        <>
          <div>
            <h1>Parallax07</h1>
          </div>
          <div
            id="images"
            className={css({ position: "relative" })}
            ref={imagesRef}
          >
            <img
              className={styles.imageStyle}
              src="https://images.pexels.com/photos/346529/pexels-photo-346529.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=400&w=600"
            />
            <img
              className={styles.imageStyle}
              src="https://images.pexels.com/photos/206359/pexels-photo-206359.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=400&w=600"
            />
            <img
              className={styles.imageStyle}
              src="https://images.pexels.com/photos/709552/pexels-photo-709552.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=400&w=600"
            />
          </div>
          <section style={{ height: "500vh", backgroundColor: "pink" }}>
            <h1>Extra space just for demo, remove this</h1>
          </section>
        </>
      );
    };
    
    export default Parallax07;

     

  4. Thanks for the reply.
    I am stuck in this situation because I was coding without understanding anything in depth.
    As you advised, I will go back to the basics and read the documentation and try to figure it out, but I would welcome any examples of implementations that are close to my concept.
    I'm very stumped and any advice would be appreciated.
    Thank you very much.

    29 minutes ago, mvaneijgen said:

    Hi @Okaka welcome to the forum!

     

    I have the feeling you're going about this in the wrong direction. My advies remove ScrollTrigger. The best thing to do when working with ScrollTrigger is to remove it! This seems counter intuitive, but ScrollTrigger is just animating something on scroll, so just focus on the animation at first and only when you're happy with the animation add ScrollTrigger back in. This way you can focus on one part at a time and it will save a lot of headache when debugging. 

     

    Here is a topic discussing an image sequence with GSAP, it uses one image with the background position, but you could easily just stack all the images on top of each other and animate their opacity (or what ever property you want). But below example uses just one ScrollTrigger with a tween, that would also be the recommendation I would give you, right now each image has a ScrollTrigger with all their own tweens, this means none of the ScrollTriggers are aware of each other and nothing will line up. 

     

     

    I would suggest creating a timeline (with ScrollTrigger disabled) and just create the animation of the images fading in and out, if you have that working add ONE ScrollTrigger to that timeline that animates that timeline on scroll. 

     

    But the most important step when working with React is doing proper clean up, if you're using GSAP with React, you must read this, hope it helps and happy tweening!  

     

     

  5. I am not a native English speaker and my writing may be poor, but thank you in advance.

    What I want to do
    Final Goal.
    * As a Wordpress block, I want to create a component that switches images as it scrolls, like a GIF.

    Specifications
    1. the image changes by scrolling 2. the block is like a sticky
    Ideally, the block should behave like a sticky. 2. When the scrolling brings the block to a given location, in this case the middle, the animation of the image switching will start, and when it switches to the last image, the sticky-like behavior will resume. 3.
    3. The number of images and the amount of scrolling per image should be adjustable.
    4. Use Next/image for performance.

    However, we are currently unable to meet most of the specifications.
    Please advise.

    https://codesandbox.io/p/devbox/mutable-sunset-phspgm?layout=%7B%22sidebarPanel%22%3A%22EXPLORER%22%2C%22rootPanelGroup%22%3A%7B%22direction%22%3A%22horizontal%22%2C%22contentType%22%3A%22UNKNOWN%22%2C%22type%22%3A%22PANEL_GROUP%22%2C%22id%22%3A%22ROOT_LAYOUT%22%2C%22panels%22%3A%5B%7B%22type%22%3A%22PANEL_GROUP%22%2C%22contentType%22%3A%22UNKNOWN%22%2C%22direction%22%3A%22vertical%22%2C%22id%22%3A%22clpgsu9rd000c3b6hk9fvt80r%22%2C%22sizes%22%3A%5B70%2C30%5D%2C%22panels%22%3A%5B%7B%22type%22%3A%22PANEL_GROUP%22%2C%22contentType%22%3A%22EDITOR%22%2C%22direction%22%3A%22horizontal%22%2C%22id%22%3A%22EDITOR%22%2C%22panels%22%3A%5B%7B%22type%22%3A%22PANEL%22%2C%22contentType%22%3A%22EDITOR%22%2C%22id%22%3A%22clpgsu9rd00033b6hgs78ghyh%22%7D%5D%7D%2C%7B%22type%22%3A%22PANEL_GROUP%22%2C%22contentType%22%3A%22SHELLS%22%2C%22direction%22%3A%22horizontal%22%2C%22id%22%3A%22SHELLS%22%2C%22panels%22%3A%5B%7B%22type%22%3A%22PANEL%22%2C%22contentType%22%3A%22SHELLS%22%2C%22id%22%3A%22clpgsu9rd00093b6h4tuvn8da%22%7D%2C%7B%22type%22%3A%22PANEL%22%2C%22contentType%22%3A%22SHELLS%22%2C%22id%22%3A%22clpgsv2wp00as3b6h9q1zxkca%22%7D%5D%2C%22sizes%22%3A%5B50%2C50%5D%7D%5D%7D%2C%7B%22type%22%3A%22PANEL_GROUP%22%2C%22contentType%22%3A%22DEVTOOLS%22%2C%22direction%22%3A%22vertical%22%2C%22id%22%3A%22DEVTOOLS%22%2C%22panels%22%3A%5B%7B%22type%22%3A%22PANEL%22%2C%22contentType%22%3A%22DEVTOOLS%22%2C%22id%22%3A%22clpgsu9rd000b3b6hz66bjsev%22%7D%5D%2C%22sizes%22%3A%5B100%5D%7D%5D%2C%22sizes%22%3A%5B50%2C50%5D%7D%2C%22tabbedPanels%22%3A%7B%22clpgsu9rd00033b6hgs78ghyh%22%3A%7B%22id%22%3A%22clpgsu9rd00033b6hgs78ghyh%22%2C%22tabs%22%3A%5B%5D%7D%2C%22clpgsu9rd000b3b6hz66bjsev%22%3A%7B%22tabs%22%3A%5B%7B%22id%22%3A%22clpgsu9rd000a3b6hs7vcy8u6%22%2C%22mode%22%3A%22permanent%22%2C%22type%22%3A%22TASK_PORT%22%2C%22taskId%22%3A%22dev%22%2C%22port%22%3A3000%2C%22path%22%3A%22%2F%22%7D%5D%2C%22id%22%3A%22clpgsu9rd000b3b6hz66bjsev%22%2C%22activeTabId%22%3A%22clpgsu9rd000a3b6hs7vcy8u6%22%7D%2C%22clpgsu9rd00093b6h4tuvn8da%22%3A%7B%22tabs%22%3A%5B%7B%22id%22%3A%22clpgsu9rd00043b6ht4kjqek2%22%2C%22mode%22%3A%22permanent%22%2C%22type%22%3A%22TASK_LOG%22%2C%22taskId%22%3A%22dev%22%7D%2C%7B%22id%22%3A%22clpgsu9rd00053b6hea0ksahd%22%2C%22mode%22%3A%22permanent%22%2C%22type%22%3A%22TASK_LOG%22%2C%22taskId%22%3A%22build%22%7D%2C%7B%22id%22%3A%22clpgsu9rd00063b6hps2cukre%22%2C%22mode%22%3A%22permanent%22%2C%22type%22%3A%22TASK_LOG%22%2C%22taskId%22%3A%22start%22%7D%2C%7B%22id%22%3A%22clpgsu9rd00073b6hr3bn3ejy%22%2C%22mode%22%3A%22permanent%22%2C%22type%22%3A%22TASK_LOG%22%2C%22taskId%22%3A%22lint%22%7D%2C%7B%22id%22%3A%22clpgsu9rd00083b6hay6mh0wm%22%2C%22mode%22%3A%22permanent%22%2C%22type%22%3A%22TASK_LOG%22%2C%22taskId%22%3A%22install%22%7D%5D%2C%22id%22%3A%22clpgsu9rd00093b6h4tuvn8da%22%2C%22activeTabId%22%3A%22clpgsu9rd00083b6hay6mh0wm%22%7D%2C%22clpgsv2wp00as3b6h9q1zxkca%22%3A%7B%22tabs%22%3A%5B%7B%22id%22%3A%22clpgsutp300ao3b6hzundduq5%22%2C%22mode%22%3A%22permanent%22%2C%22type%22%3A%22TERMINAL%22%2C%22shellId%22%3A%22clpgsv34k00hwefge61fm17o6%22%7D%5D%2C%22id%22%3A%22clpgsv2wp00as3b6h9q1zxkca%22%2C%22activeTabId%22%3A%22clpgsutp300ao3b6hzundduq5%22%7D%7D%2C%22showDevtools%22%3Atrue%2C%22showShells%22%3Atrue%2C%22showSidebar%22%3Atrue%2C%22sidebarPanelSize%22%3A15%7D

×
×
  • Create New...