Jump to content
GreenSock

Search the Community

Showing results for tags 'matchmedia'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • GreenSock Forums
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Personal Website


Twitter


CodePen


Company Website


Location


Interests

Found 24 results

  1. GreenSock

    GSAP 3.11 Released

    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()
  2. Hi, Experiencing some glitches with horizontalLoop helper. I have list items overlapping and popping in and out like image shown below. Just wondering if my implementation is off or if the helper is not quite the tool for this component. I attempted to use this at the most basic case, but still experiencing some issues. Thanks for any help.
  3. Hi there, I am using ScrollTrigger a lot, its a fantastic addition! the only issue I've run into so far is cleaning up when using ScrollTrigger.matchMedia() when un-mounting in my React components. I've tried killing all ScrollTrigger instances, and killing timelines individually. simplified setup below: const buildTimeline = () => { // ... setup stuff ScrollTrigger.saveStyles([boxRef.current, mobileRef.current]); ScrollTrigger.matchMedia({ '(min-width: 720px)': () => { if (!boxRef.current) { console.log('boxRef does not exist'); } ScrollTrigger.create({ // config stuff animation: desktopTimeline.current .to( // animations ) }); }, '(max-width: 719px)': () => { if (!mobileRef.current) { console.log('mobileRef does not exist'); } ScrollTrigger.create({ // config stuff animation: mobileTimeline.current .to( // animations ) }); }, }); } useEffect(() => { if (!hasMounted.current) { hasMounted.current = true; buildTimeline(); } return () => { // kill all ScrollTrigger[s] ScrollTrigger.getAll().forEach(t => t.kill()); // try killing individual timelines also mobileTimeline.current.kill(); desktopTimeline.current.kill(); } }, []); This would normally work ok on ScrollTrigger instances generally - or at least it seems to! - but if I'm using matchMedia I'll still get media query change events firing where the component is unmounted (i.e. navigating to a different route). any idea what I'm missing here?
  4. I'm really new to this and have slowly pieced this together. I'm pretty sure I have way to much js at this point but I'm trying to fade in the H1 just after the bullseye circle disappears and then as that moves up, the other text fades in from the bottom of the screen and moves up to look like this:
  5. Hello Forum, I try to create animation only for larger screen. I animate the y position of the box. However, after the window resize the box seems to be out of position. I am creating a website that use similar animation. In my case, the image either wont show up or out of place. Thanks in advance people!
  6. I have a basic gsap animation set up with matchMedia. ScrollTrigger.matchMedia({ "(min-width: 700px)": function () { let containerWidth = parseInt(getComputedStyle(document.querySelector(".see-through")).width); let tl = gsap.timeline({ scrollTrigger: { / .... } }); tl.to(".logo-transparent", { x: containerWidth/2, scale: "0.8" }); }, "(max-width: 699px)": function () { let containerHeight = parseInt(getComputedStyle(document.querySelector(".see-through")).height); let tl = gsap.timeline({ scrollTrigger: { / .... } }); tl.to(".logo-transparent", { y: containerHeight/2, scale: "0.9" }) } }); Now what I want is to update the values of containerWidth and containerHeight on each resize event. I tried adding an eventListener for resize event and updating the variables, but it still has no effect on the animation. Perhaps the animation is not updated on each resize unless the media breakpoints change. What approach can I follow for the desired effect?
  7. Hello there, i have a homepage https://staging8.texpack.it/ that has some animations, one kind is a group of which on under 1200px screens makes "fade in moving up some" containers, above 1200px them "come in" from left or right according to a class. These animations run only one time on Chrome mobile, if i come back or refresh the home, only the animations outside the ScrollTrigger.matchMedia({ .. }) work properly. Thank you in advance for your help! Here is the js that manages the responsive functions: ScrollTrigger.saveStyles('.matchMedia'); ScrollTrigger.refresh(); ScrollTrigger.matchMedia({ '(max-width: 1199px)': function(){ // WIDGET BOX IN BOX gsap.utils.toArray('.wbib-trigger:not(.no-gsap)').forEach(function(section) { let target = section.querySelectorAll('.from-left, .from-right'); gsap.from(target, { scrollTrigger: { trigger: section, end: '+=45%', scrub: 1.2, }, opacity: 0, y: 100, duration: 1 }); }); }, '(min-width: 1200px)': function() { // MAIN NAVIGATION var origin = ''; $('.menu-item-has-children').mouseenter(function(event) { origin = $(this).children('a').html(); $(this).addClass('active').find('.sub-menu').addClass('active'); }); $('.menu-item-has-children').mouseleave(function(event) { $(this).removeClass('active').find('.sub-menu').removeClass('active'); }); $('.sub-menu').mouseenter(function(event) { $(this).parents('li').addClass('active'); }); $('.sub-menu').mouseleave(function(event) { if (event.relatedTarget.innerHTML != origin) { $(this).removeClass('active').parent('li').removeClass('active'); } }); // WIDGET BOX ON BOX gsap.utils.toArray('.wbib-trigger:not(.no-gsap)').forEach(function(section) { let target = section.querySelectorAll('.from-left'); gsap.from(target, { scrollTrigger: { trigger: section, end: '+=45%', scrub: 1.2, }, opacity: 0, x: -100, duration: 1 }); }); gsap.utils.toArray('.wbib-trigger:not(.no-gsap)').forEach(function(section) { let target = section.querySelectorAll('.from-right'); gsap.from(target, { scrollTrigger: { trigger: section, end: '+=45%', scrub: 1.2, }, opacity: 0, x: 100, duration: 1 }); }); } });
  8. Context: I want the counting animation to happen only when the screen size is larger than 1024px So for example, starting number is 30 and the number will increment until the target number 50. However, when I resize the screen the number becomes 30 rather than staying at the target number 50. From the documentation, it seems like the ScrollTrigger will kill the animation and revert to its original state when the media query doesn't match However, is there any way to maintain the final state? I'm using React and here is the code snippet I'm new to this forum and GSAP and thank you in advance for your help and guidance. Here is the code import React, { useEffect } from "react" import { gsap } from "gsap" import { ScrollTrigger } from "gsap/ScrollTrigger" const TestPage = () => { const stats = [{ finalNum: 50, startNum: 30 }] useEffect(() => { gsap.registerPlugin(ScrollTrigger) ScrollTrigger.matchMedia({ "(min-width: 1024px)": function () { ScrollTrigger.create({ trigger: "#counter-trigger", start: "-=350", end: "+=200", markers: true, animation: gsap.from(".mycounter", { duration: 0.55, innerText: stats[0].startNum, snap: { innerText: 1, }, once: true, }), }) }, }) }, []) return ( <div> <div style={{ height: "1000px", backgroundColor: "lightcoral", }} > some stuff here </div> <div my={100} id="counter-trigger"> <span className="mycounter" style={{ fontSize: "80px" }}> {stats[0].finalNum} </span> </div> </div> ) } export default TestPage
  9. I'm working on a menu that needs to react differently for mobile vs desktop. I got it working but when I change the viewport width, the animation and reverse animation are bugged one time, after that they adept to the 'new' situation. On browser refresh it also works correctly. Can anyone point out why the animations don't work correctly when changing the viewport width the first time? If I look in the inspector I see the values being being used are still from the other timeline, even though the new screensize is active.. Item 2 slides out a sub-menu, other items should do the same but I left that out for now.
  10. Hi, I'm back at it again and need some help understanding what is going wrong. I want my scrollTrigger to only be active on mobile devices. Thus, I created the scrollTrigger animation within a media query. As I understand the documentation my implementation should work but it obviously doesn't 🙃 I'm having trouble understanding where I'm going wrong this time ://
  11. I have a Next.js/React project with typescript and Storybook: when using Scrolltrigger.matchmedia() function the component always give an error when running inside Storybook: _win is undefined matchMedia@http://localhost:6006/vendors~main.d3f7aa1f55228e485314.hot-update.js:1541:10 Removing matchmedia it all works as expected, but I need it in the project, this is very upsetting... You can find the demo code here on github: https://github.com/marcello-palmitessa/gsap-scrolltrigger-issues-demo
  12. HI Guys, I have created 2 boxes(large & small).. And i want to animate those boxes differently in different screen sizes. Here in code pen u can see a demo. Its for the large screen device. Here the small box is showing after the first box appears & then sliding to left. But i want to change the animation for medium or small screens. Like first the large box will appear like it do for large screens and then the small box will appear after a few seconds & then instead of sliding left it will disappear after showing a few seconds. I used matchMedia for making changes. But somehow im unable to get the result i want. Im so confused. I dont know what to do. Can anyone tell me whats the problem in my code.
  13. Hello, can anyone help me with this error? (I want to preface that I'm a newbie at coding and I only try to adapt from other as much as I can understand...) I have adapted some code from the forum which explained how to use GSAP for different media queries but I cannot seem to make the functionality work... The idea: When page is fullscreen, the menu icon should trigger and animate GSAP timeline on >mouseenter/mouseleave< for selector ".menu-links". ( I used .play(); and .reverse(); ) When page is going devices size screens, mobile/tablet < 733px, the menu icon should trigger and animate GSAP timeline on >click< for selector ".menu-links + #social" ( I used .restart(); and .reverse(); ) ---- the code works right now only when page is loaded in mobile size to begin with, if resized functionality breaks. also vice versa, desktop resized to mobile ---- My question is can: this be done better? Ideal would be to resize page without losing functionality going from big screens to small screens without page reload. ==== ps: if this topic is wrongfully opened please feel free to delete it. Thank you very much, Alex
  14. Hello everyone, I have an animation that needs to display only above 992px width and 700px height. however it seems i cant add more than one condition to matchMedia. What is the (proper) way to do this? (I hope you dont mind i used your matchMedia demo as a starting point for my codepen) Thanks, Patrick Rijkee
  15. Hey guys, Couldn't find any info in the docs about using ScrollTrigger.matchMedia and pointers? I tried it with pointer:coarse and it didn't seem to register? Is this a feature / would it be in the future? Something like below. Thanks heaps ScrollTrigger.matchMedia({ "(pointer: coarse)": function() { // setup animations and ScrollTriggers for pointer: coarse?? }, });
  16. Hi there, I am running into an odd issue with my React site and using GSAP. Website: https://gpstaging.netlify.app For all the scroll based triggers, if I resize the window they will either disappear https://take.ms/6VGoD or not fire their animation when scrolling down the page. It looks like they disappear because an inline style of opacity: 0 and visibility: none is getting applied to them. But I have no idea why and even when I removed all the other components that had GSAP animation applied, the styles keep showing up. Here is a simplified demonstration of the items disappearing once the window get's resized a few times. https://codesandbox.io/s/festive-feistel-puiib?file=/src/App.js For the full production code version, please see the below Github link. https://github.com/GedalyaKrycer/gedalyakrycer.github.io/blob/gsapBackup/gk-portfolio/src/components/Bio/index.js I suspect I am not using the useRef correctly and maybe there is issues with having multiple components that have GSAP on it. But I am not sure how to troubleshoot it. Much appreciation for any insight. Gedalya
  17. I'm trying to trigger different timelines at different breakpoints using the window.matchmedia(); method. I've attempted to put together a potential example here: const box = document.querySelector(".box"); const change = document.querySelector(".change"); const mqs = [ window.matchMedia("(min-width: 600px)"), window.matchMedia("(min-width: 768px)"), window.matchMedia("(min-width: 1024px)") ]; const tl = gsap.timeline({ paused: true; }); if (mqs[0].matches) { tl.to(box, { backgroundColor: "green" }); } else if (mqs[1].matches) { tl.to(box, { backgroundColor: "pink" }); } else { tl.to(box, { backgroundColor: "black" }); } function playTl() { tl.play(); } change.addEventListener("click", playTl); My idea is to have the change button trigger the animations. Is it a little more complex that this approach? Having dug around in the forums it seems media queries plus gsap tends to throw up a number of complex solutions, I was hoping for something a little more simpler. Here's a Codepen also:
  18. animation is working correctly when browser loads, when I resize the browser, the animation does not work. gsap.registerPlugin(ScrollTrigger); ScrollTrigger.matchMedia({ "(min-width: 750px)": ()=>{ let timeline = gsap.timeline({ scrollTrigger:{ trigger: " #skill", start: "top 60%", toggleActions: "restart ", duration: 2 }}); timeline .from("#skill .title", { x:"-120%", ease:'power3', opacity: 0 }) .from("#skill .skill", { x:"-120%", opacity: 0 }) .from("#skill .progress", { x:"-100%", ease:'power2', stagger: 0.15, opacity: 0 }, 1); }, "(max-width: 749px)": ()=>{ let timeline = gsap.timeline({ scrollTrigger:{ trigger: " #skill", start: "top 60%", toggleActions: "restart", duration: 2 }}); timeline .from("#skill .title", { x:"-100%", ease:'power3', stagger:0.15 }) .from("#skill .skill-bar", { x:"-100%", ease:'power3', stagger:0.15 }) .from("#skill .progress", { x:"-100%", ease:'power3', stagger:0.15 }, 1); } });
  19. Hi! I try to change animation with (window.matchMedia()).matches How can i get tween from timeline and replace (or edit) it? I read about .remove() method, but how can i add on removed place other tween and how can i add label to tween. for example: tl .addLabel('start') .to('.box-1', {x:100}, "start") // <--- how to change this or how to .remove() this and place other tween on this place .to('.box-2', {x:100}, "start")
  20. Had a trawl through the site and codepen but couldn't find an answer. I have timelines that require different scrolltrigger values according to media queries, is it correct to place paused timelines outside the ScrollTrigger.matchMedia() and the scrolltrigger/s inside the function? Or is it best practice to duplicate timelines in each media query? Or some other setup? Thanks
  21. Hello, I'm trying to implement matchMedia with ScrollTrigger, it works very well but I have this little problem with gsap.set that I'm required to use because the pin method overrides my CSS transforms (in my CSS comments). But it doesn't seem to apply at all, or just for a brief moment when crossing my 800px breakpoint. Any help and comment very much appreciated, Thanks, David
  22. ScrollTrigger Matchmedia function does not work as I expected. It works successfully when i scroll without resizing screen. Please check my codesandbox link (https://codesandbox.io/s/blissful-franklin-j6rdo?file=/src/contents.js) here. Once I resize the screen to tablet view (~1024px) or opposite way from tablet view to Desktop view, - ScrollTrigger behavior does not work as initial setting. - Having console error message with `GSAP target null not found` As I found out the simple examples of matchmedia was working with resizing. But, my code does not work. Once resize the screen, seems scrollTrigger is getting confused. What did I miss on here?
  23. Hi, I have a question regarding using ScrollTrigger.matchMedia in multiple places within a web app (which will include using the same breakpoints in multiple places) To paint the scenario for you, so you have some more context. I have a Nuxt.js web app, that is using ScrollTrigger for various animations, which are setup within individual components throughout the app, which allows me to only create / destroy ScrollTrigger and gsap instances where needed to keep things nice and tidy. I noticed in the video tutorial for ScrollTrigger.matchMedia, that declaring this object once seems to be the recommended way, and then using the media queries as keys - e.g '(min-width: 800px)' pointing to a function which would handle ALL the ScrollTrigger instances for each breakpoint. My question is, is there a specific way that I should be using ScrollTrigger.matchMedia() within a component, and setting up the gsap / scrollTrigger animations only related to that component. I have been playing around with this for the last few hours, and I keep running up against issues, as I am presumably using it incorrectly. UPDATE: Small Codepen example in the below reply. Apologies in advance as I haven't included any specific code in this post. I am just seeing if there is a simple way of achieving this with ScrollTrigger.matchMedia, or if I need to setup something a bit more custom to acheive this. If its better for me to setup a small repo / codesandbox with a simple example showing exactly what I mean, let me know and I will reply to this post with it P.S Just wanted to say that ScrollTrigger is the absolute bomb, and I've been using it since the day it launched! Thanks in advance!
  24. GreenSock

    GSAP 3.4 Released

    GSAP 3.4 has arrived with some significant improvements to ScrollTrigger like: Accommodating different setups for various screen sizes, like a mobile version and desktop version - ScrollTrigger.matchMedia() Batching and staggering elements that enter the viewport, similar to what's often done with IntersectionObserver - ScrollTrigger.batch() Integrating with smooth scrolling libraries - ScrollTrigger.scrollerProxy() ScrollTrigger.matchMedia() You can use standard media queries to seamlessly transition between different ScrollTriggers. It's surprisingly simple to set up and let ScrollTrigger automatically handle all of the creating, undoing, and destroying for you. Basic setup ScrollTrigger.matchMedia({ // desktop "(min-width: 800px)": function() { // setup animations and ScrollTriggers for screens 800px wide or greater (desktop) here... // These ScrollTriggers will be reverted/killed when the media query doesn't match anymore. }, // mobile "(max-width: 799px)": function() { // The ScrollTriggers created inside these functions are segregated and get // reverted/killed when the media query doesn't match anymore. }, // all "all": function() { // ScrollTriggers created here aren't associated with a particular media query, // so they persist. } }); See the Pen ScrollTrigger.matchMedia() Demo by GreenSock (@GreenSock) on CodePen. There's a new ScrollTrigger.saveStyles() method that can be useful with matchMedia(). It saves the current inline styles for any element(s) so that they're reverted properly if animations added other inline styles. It's explained in the video above. See the ScrollTrigger.matchMedia() docs for details. ScrollTrigger.batch() Normally, each ScrollTrigger fires its callbacks (onEnter, onLeave, etc.) immediately when they occur but what if you want to coordinate an animation (like with staggers) of ALL the elements that fired a similar callback around the same time? ScrollTrigger.batch() creates a coordinated group of ScrollTriggers (one for each target element) that batch their callbacks within a certain interval, delivering a neat Array so that you can easily do something like create a staggered animation of all the elements that enter the viewport around the same time. It's a great alternative to IntersectionObserver because it's more widely compatible and easier to work with. Plus you're not restricted to only entering or exiting the viewport - batch() can use ANY start and end values! Demo See the Pen ScrollTrigger.batch() Demo by GreenSock (@GreenSock) on CodePen. See the ScrollTrigger.batch() docs for details. ScrollTrigger.scrollerProxy() ScrollTrigger purposefully avoids "scrolljacking" (disabling the browser's native scrolling behavior in favor of a custom, non-standard scrolling solution). However, smooth scrolling was by far the most requested feature to pair with ScrollTrigger. There are plenty of smooth-scrolling libraries out there, so we created the .scrollerProxy() method to make it simple to integrate any of them with ScrollTrigger (or create your own effects). Here's a basic example using Locomotive Scroll but check out the .scrollerProxy() docs for examples with other libraries. See the Pen ScrollTrigger with LocomotiveScroll by GreenSock (@GreenSock) on CodePen. And more... GSAP 3.4 also delivers various bug fixes, so we'd highly recommend installing the latest version today. There are many ways to get GSAP - see the Installation page for all the options (download, NPM, zip, Github, etc.). Resources Full release notes on Github Full documentation Getting started with GSAP Learning resources Community forums ScrollTrigger Express video course from Snorkl.tv Happy tweening!
×