Alexandra Spalato Posted July 12, 2020 Share Posted July 12, 2020 Hello, I have this grid with filters https://thefalconlab.netlify.app/our-work/ the clients want it to animate like that on filtering http://falcon.vserve.co/ is there a way to do that with gsap I tried with framer motion, adding a shuffle on projects and using the positionTransition prop, but it doesn't work Link to comment Share on other sites More sharing options...
GreenSock Posted July 12, 2020 Share Posted July 12, 2020 I'm not at all familiar with Framer Motion, but you should certainly be able to do it with GSAP. I'd use the FLIP technique which is described here: https://greensock.com/docs/v3/HelperFunctions#FLIP Good luck! 1 Link to comment Share on other sites More sharing options...
OSUblake Posted July 12, 2020 Share Posted July 12, 2020 1 hour ago, GreenSock said: I'd use the FLIP technique which is described here: https://greensock.com/docs/v3/HelperFunctions#FLIP I think that demo is rather confusing, and the helper function has issues. It doesn't work with a single element, and it doesn't handle interruptions correctly. getBoundingClientRect throws it off mid animation. Click repeatedly to see the issue. See the Pen 9d0a2b57a1e70f57f752969f588216c5 by osublake (@osublake) on CodePen Handling size changes would be even better, although scaling requires a little bit of work to counter scale. The less performant way would be to animate width and height. 1 Link to comment Share on other sites More sharing options...
Alexandra Spalato Posted July 12, 2020 Author Share Posted July 12, 2020 Thank you! going to look at this! Link to comment Share on other sites More sharing options...
GreenSock Posted July 14, 2020 Share Posted July 14, 2020 On 7/12/2020 at 2:10 AM, OSUblake said: I think that demo is rather confusing, and the helper function has issues. It doesn't work with a single element, and it doesn't handle interruptions correctly. getBoundingClientRect throws it off mid animation. Click repeatedly to see the issue. Here's an updated function that uses more modern JS: function flip(elements, changeFunc, vars) { elements = gsap.utils.toArray(elements); vars = vars || {}; let tl = gsap.timeline({onComplete: vars.onComplete, delay: vars.delay || 0}), bounds = elements.map(element => { let b = element.getBoundingClientRect(); element._flip && element._flip.progress(1); element._flip = tl; return b; }), copy = {}, p; changeFunc(); for (p in vars) { p !== "onComplete" && p !== "delay" && (copy[p] = vars[p]); } copy.x = (i, element) => "+=" + (bounds[i].left - element.getBoundingClientRect().left); copy.y = (i, element) => "+=" + (bounds[i].top - element.getBoundingClientRect().top); return tl.from(elements, copy); } I updated the docs of course too. As for interrupting, the problem was that your function that was establishing the new state wasn't resetting the x/y to 0 (the way you'd want it to be in the final state) but I added some code to the helper function that'll keep track of the flip stuff assigned to each element and force it to completion on subsequent flip() calls, so it should allow you to avoid resetting the x/y in your function. See the Pen eYJLOdj by GreenSock (@GreenSock) on CodePen Better? 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now