Search the Community
Showing results for tags '3.11'.
-
Highlights: gsap.matchMedia() is a game-changer for responsive, accessible-friendly animations. 💚 gsap.context() that greatly simplifies setup and reverting of a bunch of animations/ScrollTriggers, especially for React developers! You can now revert() any animation to return the targets to their original state. Set lockAxis: true on an Observer to make it lock into whichever direction the user first drags 🥳 Responsive, accessibility-friendly animations with gsap.matchMedia() One of the hardest challenges for web-animators is crafting animations that work seamlessly on all screen sizes and respect users motion preferences. Well, not anymore! gsap.matchMedia() lets you easily tuck setup code into a function that only executes when a particular media query matches and then when it no longer matches, all the GSAP animations and ScrollTriggers created during that function's execution get reverted automatically! Customizing for mobile/desktop or prefers-reduced-motion is remarkably simple and incredibly flexible. Basic syntax // create let mm = gsap.matchMedia(); // add a media query. When it matches, the associated function will run mm.add("(min-width: 800px)", () => { // this setup code only runs when viewport is at least 800px wide gsap.to(...); gsap.from(...); ScrollTrigger.create({...}); return () => { // optional // custom cleanup code here (runs when it STOPS matching) }; }); // later, if we need to revert all the animations/ScrollTriggers... mm.revert(); Conditions syntax - 💪 POWERFUL 💪 What if your setup code for various media queries is mostly identical but a few key values are different? If you add() each media query individually, you may end up with a lot of redundant code. Just use the conditions syntax! Instead of a string for the first parameter, use an object with arbitrarily-named conditions and then the function will get called when any of those conditions match and you can check each condition as a boolean (matching or not). The conditions object could look like this: { isDesktop: "(min-width: 800px)", isMobile: "(max-width: 799px)", reduceMotion: "(prefers-reduced-motion: reduce)" } Name your conditions whatever you want. Below we'll set the breakpoint at 800px wide and honor the user's prefers-reduced-motion preference, leveraging the same setup code and using conditional logic where necessary: let mm = gsap.matchMedia(), breakPoint = 800; mm.add({ // set up any number of arbitrarily-named conditions. The function below will be called when ANY of them match. isDesktop: `(min-width: ${breakPoint}px)`, isMobile: `(max-width: ${breakPoint - 1}px)`, reduceMotion: "(prefers-reduced-motion: reduce)" }, (context) => { // context.conditions has a boolean property for each condition defined above indicating if it's matched or not. let { isDesktop, isMobile, reduceMotion } = context.conditions; gsap.to(".box", { rotation: isDesktop ? 360 : 180, // spin further if desktop duration: reduceMotion ? 0 : 2 // skip to the end if prefers-reduced-motion }); return () => { // optionally return a cleanup function that will be called when none of the conditions match anymore (after having matched) } }); Nice and concise! 🎉 See the Pen gsap.matchMedia() by GreenSock (@GreenSock) on CodePen. You can set a scope so that all selector text inside the function maps only to descendants of a particular element or React Ref or Angular ElementRef. This can greatly simplify your code. See the full documentation for all the details. gsap.context()
- 4 comments
-
- 6
-
-
- gsap
- responsive
-
(and 4 more)
Tagged with:
-
Hello! On version 3.10, when you use .set() or .from() with the ScrollTrigger plugin applied as the first call, they behave like a method on gsap object without any plugins - they just get added as inline style immediately after loading the script. Today I updated my project to version 3.11 and to my surprise, most of the animations were behaving weirdly (easy to notice at fade in animations). After looking things up in DevTools i noticed that now in 3.11 .set() and .from() launches only after getting between the ScrollTrigger's values - start and end. Not sure if it's a bug or an intended thing, but if its a feature I can't find any mentions about this on GSAP's GitHub update page. Example for 3.10 (fadein working as intended) gsap.fromTo( fadeInRef.current?.children || [], { autoAlpha: 0, }, { scrollTrigger: { trigger: fadeInRef.current, start: 'bottom bottom', once: true, end: '+=0', }, stagger: 0.1, autoAlpha: 1, }, ); Example for 3.11 (it's a fix for code above) gsap.set(fadeInRef.current?.children || [], { autoAlpha: 0 }); gsap.to(fadeInRef.current?.children || [], { scrollTrigger: { trigger: fadeInRef.current, start: 'bottom bottom', once: true, end: '+=0', }, stagger: 0.1, autoAlpha: 1, });