Jump to content
Search Community

need some help with .matchMedia()

Luquatic test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

hopefully someone can help me out because I'm a bit confused.

could someone point me into the right direction and tell me what I'm doing wrong?

as far as I know the default behavior should be the code defined inside the function and that should be overwritten by the gsap.matchMedia() right?
thanks in advance!

const imageScrollTriggerOptions = {
  [Device.MOBILE as Device]: {
    start: 'top top+=90px',
    end: () => `+=${content.value.offsetHeight - 400}`,
  },
  [Device.TABLET as Device]: {
    start: 'top top+=265px',
    end: () => `+=${content.value.offsetHeight}`,
  },
};

const mm = gsap.matchMedia();

// add a media query. When it matches, the associated function will run
mm.add('(max-width: 768px)', () => {
  // this setup code only runs when viewport is at least 800px wide
  gsap.to('.stacked-image-title-text__image-container:not(:first-child)', {
    scrollTrigger: {
      start: 'top top+=90px',
      end: () => `+=${content.value.offsetHeight - 400}`,
    },
  });
});

const handleImageAnimations = (): void => {
  tl.fromTo('.stacked-image-title-text__image-container:not(:first-child)', {
    opacity: 0,
    scale: 2,
  }, {
    duration: 0.6,
    opacity: 1,
    scale: 1,
    stagger: 1,
    scrollTrigger: {
      pin: '.stacked-image-title-text__images-container',
      scrub: 0.1,
      start: 'top top+=265px',
      end: () => `+=${content.value.offsetHeight}`,
    },
  });
};

 

Link to comment
Share on other sites

Hi,

 

There is not a lot we can do without a minimal demo, please try to create a small codepen example that clearly illustrates the issue you're having (keep it small please).

 

The only thing I can spot is that you are creating ScrollTrigger instances without a trigger element. It's highly recommended to use a trigger element so ScrollTrigger can run all it's calculations.

 

Also here you're animating the element you're pinning as well, that's a bad idea and you should try to avoid it at all costs:

const handleImageAnimations = (): void => {
  tl.fromTo('.stacked-image-title-text__image-container:not(:first-child)', {
    opacity: 0,
    scale: 2,
  }, {
    duration: 0.6,
    opacity: 1,
    scale: 1,
    stagger: 1,
    scrollTrigger: {
      pin: '.stacked-image-title-text__images-container',
      scrub: 0.1,
      start: 'top top+=265px',
      end: () => `+=${content.value.offsetHeight}`,
    },
  });
};

Finally the instance you're creating inside the MatchMedia instance will run only if the screen is 768px width or less. Above that breakpoint that particular instance is reverted. The other problem is that in small screens the code inside the MatchMedia instance is running as well as the code outside (that runs always) and the Tween inside the MatchMedia instance is not doing anything at all 🤷‍♂️

mm.add('(max-width: 768px)', () => {
  // this setup code only runs when viewport is at least 800px wide
  gsap.to('.stacked-image-title-text__image-container:not(:first-child)', {
    scrollTrigger: {
      start: 'top top+=90px',
      end: () => `+=${content.value.offsetHeight - 400}`,
    },
  });
});

So is really unclear what you're trying to achieve here, hence the need for a minimal demo.

 

Happy Tweening!

Link to comment
Share on other sites

Thanks for the fast reply! I'll try to create a small code pen when I have more time.

Does that mean I should move my fromTo code inside the matchMedia().add?

For clarification I'm trying to adjust the start and end positions in the scrollTrigger based on the device and make it responsive.
 

Currently my animation works as intended but breaks when I change the viewport.

So for mobile it's: 

      start: 'top top+=90px',
      end: () => `+=${content.value.offsetHeight - 400}`

 

and for desktop: 
 

      start: 'top top+=265px',
      end: () => `+=${content.value.offsetHeight}`,
Link to comment
Share on other sites

  • Solution

Hi,

 

You can define different screen size breakpoints, so if you want something to work in screens smaller than tablets it has to go up to 767px and everything else above 768px. It could be like this:

const mm = gsap.matchMedia();

// Small screens
mm.add("(max-width: 767px)", () => {});

// Large sreens
mm.add("(min-width: 768px)", () => {});

You can also tack into the conditions syntax as well:

const mm = gsap.matchMedia();

mm.add({
  isDesktop: "(min-width: 768px)",
  isMobile: "(max-width: 767px)",
}, (context) => {
  let { isDesktop, isMobile } = context.conditions;
  
  ScrollTrigger.create({
    trigger: ".element",
    start: isMobile ? "top 200" : "top 400",
  });
});

You can learn more here:

https://gsap.com/docs/v3/GSAP/gsap.matchMedia()

 

Happy Tweening!

Link to comment
Share on other sites

Hi,

I solved it by combining my first two code snippets:

const handleImageAnimations = (): void => {
  const mm = gsap.matchMedia();

  mm.add({
    isTablet: '(min-width: 768px)',
    isMobile: '(max-width: 767px)',
  }, (context) => {
    const { isTablet, isMobile } = context.conditions;

    tl.fromTo('.stacked-image-title-text__image-container:not(:first-child)', {
      opacity: 0,
      scale: 2,
    }, {
      duration: 0.6,
      opacity: 1,
      scale: 1,
      stagger: 1,
      scrollTrigger: {
        pin: '.stacked-image-title-text__images-container',
        scrub: 0.1,
        start: isMobile ? 'top top+=90px' : 'top top+=265px',
        end: () => {
          const contentHeight = content.value.offsetHeight;
          return isMobile ? `+=${contentHeight - 400}` : `+=${contentHeight}`;
        },
      },
    });
  });
};


Thank you for the help!
 

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