Jump to content
Search Community

Problem with ScrollTrigger.saveStyles and ScrollTrigger.matchMedia

Nickicool test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi!

 

I have a problem on starting the animation. Animation elements are not set to the start position ("from" point) of the animation "behind the scene". This happens right before the animation starts, so the animated elements "flash" at the start of the animation.

 

Experimentally, I found that the reason is in the "ScrollTrigger.saveStyles"method. But without it (if comment it), the animation also works incorrectly when changing the media query. Although the "blinking" disappears when the animation starts.

 

I do not know how to fix it... Please help me!

See the Pen oNLzeog?editors=1010 by nickicool (@nickicool) on CodePen

Link to comment
Share on other sites

  • Solution

Ah yes, sorry about the confusion there. It's a very particular scenario related to from() animations inside matchMedia(). That should be resolved in the next release which you can preview at https://assets.codepen.io/16327/ScrollTrigger.min.js

 

Better? 

 

An alternate solution is simply to reset things at the top of your matchMedia() functions, like: 

gsap.set(".list, .item", {clearProps: "all"});

 

  • Like 2
Link to comment
Share on other sites

  • 5 months later...

Hi GSAP forum,

 

I am having the same issue as the original poster.

 

I am using ScrollTrigger.matchMedia and ScrollTrigger.saveStyles so that animations do not get applied on mobile.

 

Adding the ScrollTrigger.saveStyles correctly reapplies the original styles when the media query isn't matched -- for instance when resized outside the bounds of the matchMedia query. However, like the original poster, adding saveStyles causes the animation to glitch (the origin state/position is displayed for a spit-second before starting).

 

Also like the original poster, commenting-out the ScrollTrigger.saveStyles code removes the glitch. However, content remains in the unanimated state on window resize. (So, elements that animate "from" "opacity: 0" are invisible when I resize below the bounds of the matchMedia query.)

 

Please see CodePen below:

See the Pen qBRayvw by lindauson (@lindauson) on CodePen

 

Works fine without ScrollTrigger.saveStyles:

See the Pen wvgzYGY by lindauson (@lindauson) on CodePen


Adding CSS to start the elements at "opacity: 0" might solve the problem, although it ruins progressive enhancement -- the page will be broken without JS.

Link to comment
Share on other sites

Interesting...

 

I'm not sure why, but replacing clearProps: true with an onComplete function (that should be doing the same thing) seems to resolve the problem:

 

onComplete: function() { gsap.set(this.targets(), {clearProps: true})}

 

________________________________________________________

Update: After a bit of testing, it looks like clearing the properties in the onComplete function does not resolve the issue.

Edited by Lin Hazell
Update: incorrect solution
Link to comment
Share on other sites

Alright, the issue was that ScrollTrigger reverts to the saved styles whenever it refreshes, and it automatically refreshes on DOMContentLoaded and when all assets finish loading (because sometimes that affects where things are positioned, like if an image loads and there were no dimensions defined). So the .from() would render its starting values immediately, and THEN the window would fire its "load" event or the document would fire DOMContentLoaded, and a refresh() would occur, causing the reversion of the inline styles. It all depends on the sequence of the firing of those events by the browser - you may have seen different behavior on occasion because the browser fired it before or slightly after that first .from() render. 

 

I'll implement a workaround in the next release, but in the mean time you can just use this function instead of the ScrollTrigger.saveStyles() - it does basically the same thing:

function saveStyles(elements) {
	let styles, matchedMedia;
	elements = gsap.utils.toArray(elements);
	ScrollTrigger.saveStyles(elements);
	ScrollTrigger.addEventListener("refreshInit", () => {
		matchedMedia = false;
		styles = elements.map(el => el.style.cssText);
	});
	ScrollTrigger.addEventListener("matchMedia", () => {
		matchedMedia = true;
	})
	ScrollTrigger.addEventListener("refresh", () => matchedMedia || elements.forEach((el, i) => el.style.cssText = styles[i]));
}

Let me know if that resolves things for you. 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Wow, that was quick!!!

 

Thanks Jack!!!

 

Looks like you beat me to it -- I took a stab at writing my own saveStyles function ;)

 

Like you said -- the unpredictability of the executions was the real issue. I didn't think of using the ScrollTrigger events.

 

Your modified saveStyles function completely resolves the issue.

 

(I am going to do some more tests. I will post here if I find anything new.)

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