j0hannes
Content Type
Profiles
Forums
Store
Blog
Product
Showcase
FAQ
Downloads
Posts posted by j0hannes
-
-
8 minutes ago, GreenSock said:
I'm slightly concerned that maybe you haven't actually called it properly after everything is settled. The code you provided earlier definitely did NOT do that correctly.
If you'd like some help, please isolate the issue in a minimal demo, like perhaps in a CodePen or CodeSandbox with only a few colored <div> elements. Please don't provide your whole project, as that is way beyond the scope of help we can provide here (see the forum guidelines). Or you can post in the "Jobs & Freelance" forum to seek paid assistance.
whether I called it inside a setTimeout callback or in different parts of the lifecycle, the start-end markers don't seem to care.
-
4 hours ago, SteveS said:
If switching to refs broke something then there is definitely something funky going on. Using refs is the de facto way of selecting dom elements in react.
because I forgot adding .current.
Now the animation works with Refs. But the start and end values are still relying on where you refresh the page.
-
9 hours ago, GreenSock said:
No no, that's incorrect. That won't wait any time before firing ScrollTrigger.refresh(). I think you meant:
setTimeout(() => ScrollTrigger.refresh(), 4000);
Right?
yes that's right. I've actually tried to call the ScrollTrigger.refresh() command from multiple locations. It never had any effect.
9 hours ago, SteveS said:Hi @j0hannes , In my experience, it's a much better practice to create GSAP effects for elements inside their component and use Refs whenever possible. Doing this often solves a lot of issues just due to the fact that you make everything more predictable.
Also, you can register your plugins just under your imports, not as an effect of a component. I'd probably make that change as well.Thanks. It's now registered under imports.
I've also changed all the gsap.to() commands to target Refs instead of classnames. Both changes had no impact on the start&end markers unfortunately.
And since using Refs the animation doesn't start at all anymore, so I reverted back to the commit I made just before.
Speaking of commits - If someone would be kind enough to take a look at the project, I'd happily give a Github invite and a more detailed walkthrough. (And a tip if the issue gets resolved)
---
It's something about changing the --scalefactor variable which represents the value of zoom on the root of the landing page that causes this.
I've also tried using a styled-component instead of body.style.setProperty
Inside of the useLayoutEffect of index.tsx.
Changing it from:
const scaleFactor = currentBodyWidth / baseWidth body.style.setProperty('--scalefactor', (scaleFactor < 1) ? scaleFactor.toString() : "1")
To:
setScaleFactor(currentBodyWidth / baseWidth)
Which sets:
const LandingWrapper = styled.div` zoom: ${scaleFactor} `
Didn't improve the situation 😔
-
42 minutes ago, GreenSock said:
Agreed, a minimal demo is essential but if you want to test your theory about the page changing AFTER ScrollTrigger calculates the start/end positions, you could try a setTimeout() to run a full second or two later and call ScrollTrigger.refresh() just as a test. This isn't for final deployment or anything - just testing your theory. ScrollTrigger automatically listens for the "load" event on the window and calls ScrollTrigger.refresh() but obviously if your app is making layout changes after initial load, you must tell ScrollTrigger to refresh() after you're done.
React.useLayoutEffect(() => { setTimeout(() => {}, 4000) ScrollTrigger.refresh() })
This is what I was looking for. Thank you
however it didn't resolve the issue :/
-
I'm sorry, but I can't recreate it.
I think the best I can do is to iterate the fact, removing the logic that changes the "--scalefactor" that represents the zoom value takes care of the issue (as shown in the video) .
... but I can't get rid of the scale-factor. Otherwise the site wouldn't be responsive.
Is there any way to delay GSAP doing its thing?
I've tried the useLayoutEffect as seen above.
I've also tried conditionalising the useEffect, that houses the GSAP Logic with a pageHeightIsSteady variable, that is set true, right after I call:
const scaleFactor = currentBodyWidth / baseWidth body.style.setProperty('--scalefactor', (scaleFactor < 1) ? scaleFactor.toString() : "1")
// GSAP Scroll Animation React.useEffect(() => { if (pageHeightIsSteady) { //@ts-ignore gsap.registerPlugin(ScrollTrigger); gsap.to(".contentCardLeft", { x: 500, y: 500, scale: 0.6, // scale of card scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, markers: true, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // Email gsap.to(".sourceIconMail", { x: 580, y: 650, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // YouTube gsap.to(".sourceIconYoutube", { x: 450, y: 650, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // Twitter gsap.to(".sourceIconTwitter", { x: 250, y: 600, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // Wifi gsap.to(".sourceIconRss", { x: 550, y: 400, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // User gsap.to(".sourceIconPodcast", { x: 400, y: 250, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // Pix art gsap.to(".sourceIconPinterest", { x: 250, y: 350, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // right side // cards gsap.to(".contentCardRight", { x: -430, y: 550, scale: 0.6, // scale of card scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // Vimeo gsap.to(".sourceIconVimeo", { x: -450, y: 670, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // Instagram gsap.to(".sourceIconInstagram", { x: -550, y: 650, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // // arrow down gsap.to(".sourceIconPocket", { x: -650, y: 500, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // gsap.to(".sourceIconReddit", { x: -450, y: 200, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); // // stat icon gsap.to(".sourceIconFeedly", { x: -250, y: 450, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); gsap.to(".sourceIconBookmark", { x: -350, y: 280, scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iconAnimationStart}%`, end: `+=${animationEndValues.iconAnimationEnd}%`, scrub: 1, // animation - max speed bound // scrub: true // speed of animation equal to scroll speed }, }); gsap.to(".iPhone", { scale: 0.8, // scale of phone scrollTrigger: { trigger: ".PlasmicBringItAllTogetherSection_root", start: `-=${animationStartValues.iphoneAnimationStart}%`, end: `+=${animationEndValues.iphoneAnimationEnd}%`, scrub: 1, // animation - max speed bound markers: {startColor: "purple", endColor: "fuchsia"} // scrub: true // speed of animation equal to scroll speed }, }); } },[pageHeightIsSteady]);
You can also have a look at the live page here:
Sth else, that I want to note is that the two cards often have odd positions - but only on the live page 🤷♂️ -
I have a landing page that utilises the css "zoom" value (to scale it's content based on the screen-size).
It takes a brief moment to calculate the correct zoom value.
This happens in a useLayoutEffect on the landing page component. So right before it renders.
I think a side effect of this is that the hight of the entire page isn't entirely reliable in the first few milliseconds when the page is loaded.
This assumption would explain the problem I'm having:
The animation starts too early or too late, depending on where I am inside the page when I hit refresh.
I have the markers turned on, that signal me the start and the end of the animation. Their position is too far down or too far up. Depending on where I am, when I do the refresh (refreshing when I'm at the top of the page will bring the start and end values too far down)
The start and end values rely on the hight of the entire webpage, right?And I think the zooming process changes the hight.
An attempt at solving this was to delay the rendering of the component that houses the animation (and thus the gsap code)
So maybe then GSAP does its internal calculations later, when the hight of the webpage is reliable.
But this didn't solve my problem.
Maybe there is another way to delay GSAP doing its thing?
Or maybe my assumptions are wrong and something else is causing the problem?
You probably want a look at the code of the animation, so here is a snippet:
there are may different elements animated this way.
(except for the iPhone image), their values are:
start: "-=10%"
end: "+=60%"
(experimenting with the values (eg by using px values) is fruitless)
Here is a video, where I show it in actionhttps://www.awesomescreenshot.com/video/9767109?key=36310e15cbe8f26b1514abfc8031bca9
Is there a way to delay the GSAP Scroll trigger start and end-value calculations?
in GSAP
Posted
Is there a Codesandbox project with React and Scroll Trigger that I can riff of on?