Introducing Flip Plugin for GSAP

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today i'll introduce the new flip plugin for gsap which animates the transition between states where layout changes would normally cause elements to suddenly jump to a new position or size for example here i've got a grid of elements that gets filtered based on my selections here so we can filter out all the green elements by clicking here bring it back clicking again but it's hard for the user to understand really what's going on but watch what happens when i uncomment this one flip call now when i click it's much more clear what's going on and here's a flexbox layout that toggles between columns and rows when i hit this change button anybody who's trying to animate between those states knows what a challenge it is with flexbox but if i just uncomment this one flip call now when i change it's much more clear what's going on with the transition anything that normally causes an element to jump to a new position can be smoothed out with flip plug-in in fact the intro animation that you saw uses this very simple markup and then changes one class in the container so this final class can be changed to let's say plane it just styles things differently and then if i change plane to say grid again it's just different styling and finally columns makes it look like so and then in the javascript i've got a function that just cycles through the classes so if i run this we'll see it going through each of those layouts but now let's enable this one flip call and now when we rerun it it's a whole different feel even if i resize this it is responsive now let's walk through how this flip concept works in this example we've got a black div that toggles in between two containers so right now it's just tucked inside of this original container and then when we hit this button it's going to jump into this new container it gets nested inside of that so we're literally changing the dom structure to re-parent it if i hit it again it goes back to its original container so in the javascript we've got this function it's pretty simple i won't walk through everything all it's doing is appending the child to the appropriate container and of course when it switches containers it jumps to a new position scale and rotation we'll use the flip technique to make it appear seamless now flip stands for first last invert play those are the steps involved so first we want to record the initial state that's what we're going to do right here we create a variable named state we just call flip dot get state and pass in the reference to the box this could be select or text or it could be multiple elements doesn't matter and the size rotation and position in the viewport are all recorded in this object that we're going to use later next we put the elements in their final state so in this case all we're doing is switching the container this could be changing styles it could be you know making whatever changes you want to layout or styling now here is where the magic happens we tell flip to animate from that previous state and it instantly applies offsets to make the element look like it hasn't moved at all yet but it's an illusion now i'll pause this initially so that we don't see the animation yet and i want to show you the illusion so if i run and then i click on the button it looks like nothing happened and that's the entire point if i right click on this choose inspect let me rerun this alright so here is the box when i hit change containers it went away because now it's tucked inside of the new container and notice that we have this transform applied that has rotation and scale so if i disable the transform you'll see where it really is sitting inside the dom but the transform is applied to offset things to put it back into the original placement in the viewport so that it looks like it hasn't moved yet so the final step is to animate it so we'll remove this paused so we can actually see the animation we'll get rid of the console we'll run this and now if i click change containers oh it's nice and smooth click again goes back and since flip is integrated with gsap you can use any of those familiar properties like ease or duration you can use an oncomplete or a delay in fact flip.from returns a timeline so you can nest other animations inside of it or you can control it with methods like play or pause resume time scale whatever you want that's it now the concept is easy but it can be quite complex to calculate those offsets especially with nested transforms thankfully flip plugin handles it all for us now notice in this example that there's a little bit of a size difference between the two states because the new container is scaled up a little bit and so when flip does its magical offsets to match the previous state it has to resize that element slightly and it can do so in one of two ways either it will edit the width and height properties of that element or it will scale it using transforms and by default it will use width and height but in this case there's this option that we set of scaled true to tell flip to to use transforms instead of width and height properties now let me show you what i mean i will just go to inspect this element and let's make the duration longer so that we can see what's going on so now if i hit change containers we'll open this up and we'll see that there's just transformed and there's the scale that was animating we'll go back again we can see the scale animating but if i remove this scale true option and we run now when i hit change containers we will see that the width and height properties are being animated instead and there's no scale being applied but in this case it looks a little bit weird because the text gets scaled immediately when it gets put into the new container and the width and height being animated is properly handling you know the overall dimensions but it just looks weird with the text shifting like that which is why we want to add scale true but the other behavior can be quite convenient in some cases now in this example we can see the default behavior of animating the width and height when i hit flip here notice that the text is reflowing inside of that element as it animates and if we scaled it that wouldn't be the case if i scroll down here we'll show the same example but with scale applied so notice that there's no reflowing of the text dynamically as we're animating so in some cases it's more desirable to use scaling to resize and in other times it looks best to use width and height the magic sauce in flip plugin is its ability to take one element and map it onto another to fit perfectly and you can tap into that power directly with the flip dot fit method now here we've got a blue target div and we'll try to fit the container with a red border into it so when we click the button we're going to fit the container and map it onto the target the blue element and we're going to use scaling instead of changing the width and height properties so when i click the button there we go it fits perfectly on top now instead of instantly fitting it we could animate it by adding a duration we'll say two and maybe we'll add an ease so we can say power one dot in out and now we'll run it and when we click the button it animates and you can specify just about any normal animation property here like an oncomplete and so on because this method returns a tween now what if we wanted to move and scale the container in a way that would make one of its child elements fit the blue target watch how easy that is we'll just say fit child and say child one because that is what we have the mark up here has got a class applied there to that child so now when i try it it stretches everything out so that it fits that child on top of course we could change this to be child two and similarly it works but here's where it gets super cool let's apply some funky transforms to both elements and then try to do the fit like it's quite tricky to calculate but flip does it all for us so now we've got some strange transforms applied rotating it scaling things and now when i hit the button it contorts everything so that it fits just right and you don't even have to use a different element you can actually fit to a previously recorded state of the same element check this out we'll record the state of the target element the blue one and notice we're recording it before we apply any of these transforms so it's in its untransformed state at that point and then later on we're going to edit this flip.fit call so that we're going to fit the target to that previously recorded state and watch what happens hit the button and it animates back to that previous state pretty wild what you can do with flipped.fit sometimes you'll face layout challenges that make it impossible to keep the elements in the normal document flow and correctly animate the dimensions take this flexbox layout for example watch what happens when i do a normal flip oh you see that sudden jump this doesn't look smooth at all let's figure out what's going on and since flip.from returns a timeline animation let's just pause it halfway through and inspect the dom pause and since it's 0.8 seconds long then we can pause it halfway through at 0.4 if i run this hit change and then inspect we'll see that the width is actually being correctly applied by flip but due to the way that the browser handles flexbox layouts and some others as well it doesn't do what you think it might do so for example let's change the width here to a crazy high number like eight thousand pixels well that's definitely not a thousand pixels so to get around that the solution is to tap into flips feature called absolute true which just tells it to switch it to a position absolute during the flip animation so it takes it out of the document flow during the flip so if we inspect it now we'll see that indeed it has been set to position absolute and those widths are behaving much more the way we would expect so now if i make it eight thousand pixels well we can't see it because of the outside of the container there but it is 8 000 pixels trust me so now let's unpause it and we'll see that it is delightfully smooth now when we have nested elements that are flipping we need to tell flip to do some extra calculations to avoid compounded offsets for example in this flexbox layout with nested elements and the containers with the outlines will be flipping as well as their child elements so here i'll switch the row order you'll see that things don't look very smooth and that's because child elements move with the parents so if it applies an x translation of 500 pixels for example to both the children will end up moving a thousand pixels the solution is to simply tell flip nested true to do those extra calculations so now if we run switch the row order and now it looks gorgeous you can pass as many targets as you want to the get state method and it returns their position and size in a state object think of it like a snapshot in time here we record the state of elements with an orange or purple class and then let's shuffle the elements and switch containers and finally we feed that state object into the flip dot from and animate those targets but we can customize things and pass in a different set of targets so we'll create a configuration object here and we'll say targets and let's only flip the elements with a purple class and let's make it take one second with the knees power one and out so now even though the state object contains information for both the orange and purple elements we're only flipping the purple ones but what if we try to flip something that has no data in the state object so for example let's say that we only got the state of the orange elements and then we try to pass that in and flip the purple ones well there's no purple element data inside of this state object so if we try to animate those it's obviously not going to work because there's no data in there for it to pull from and what if we want one target to get mapped to a totally different target's position and size like if we're swapping elements well that's where the data flip id comes in notice that if we inspect these elements in devtools they all have a unique data flip id it gets automatically added by flip this is what flip uses to identify each target so if we want to swap elements all we need to do is define matching data flip id values so we can manually define these if we want and to illustrate that let's use this simpler example where let's say we've got a thumbnail image that's 200 by 200 and then we have this full size version that's 600 by 600 we can't see it right now because we have the full size set to display none but let's just temporarily say block and then we'll also make it semi-transparent and then run this and so let's say that we want to show the full-size one but animate it as if it's coming from that same position and size of the thumbnail giving the impression that it's kind of growing out of there let's set it back to display none and in the js when we click on the document we're going to do the get state for just the thumbnail and of course store it in the state object and then we're going to set display to none on the thumbnail so that goes away and the full size we're going to reveal by saying it to display block and then we're going to do the flip dot from but for the targets we're going to pass it in the full size element but what might be confusing is that wait a minute the full size was not captured there's no state information for the full size element in this state object so what is it going to do well remember in the markup we set the data flip id to image here and this data flip id is matching this can be any string there's no magic to that just pick whatever you want and since those match that is what flip is going to look for and we're targeting full size and it's going to look into the state object and say oh i found one i found information for an element with that data flip id and it'll use that size and position information so if we run and we click sure enough it works precisely the way we were hoping now another thing that's cool about flip is that if we get the state information for both the thumbnail and the full size so now we've got two elements in there with the same data flip id when we do the flip dot from it's smart enough to figure out which one is visible and which one isn't so if one has got display none then it's going to prioritize the other one in terms of animating it and what if we wanted to cross fade those elements so it's a little bit smoother of a transition well there is a fade feature we can say fade true but it's not going to do what we think at this point and i'll tell you why if i click on this we'll see that kind of disappears and then the full size image fades in so not quite the effect we're looking for but the reason for this is because we're setting the thumbnail to be display none so it's going to of course disappear completely and it's out of the document flow but if we set absolute true and that element is in the state here and if it's in the targets which we can just not customize this because the default is to use the same targets that are in the state object then it understands that we probably want to keep that element around during the flip even if it's display none so flip is smart enough to toggle that again just during the flip so that it's in the document flow so we can do the fade before it toggles it back to display none so let's try that beautiful in this example when we deselect a color those elements get set to display none so that they're taken out of the document flow and the rest of the other elements fill in the remaining space but flip can only calculate the positions on elements that are actually in the document flow so if an element is set to display none or if flip can't find a matching element in the corresponding state it can't be flipped so they just jump in and out of document flow so even if we do a flip if i toggle off the green color you'll see that they just kind of pop in and out of existence in the document flow so everything else is animating nicely but the green elements since they're getting set to display none there's no flipping that's happening of course we want to animate these elements that are entering and leaving and if we set absolute true then we know that that will keep the elements around during the flip the ones that are set to display none so let's see that in action here so see the elements stay while the flip is happening and then they get the display none set but that's not looking very good there's no animation happening but this is exactly what the on enter and on leave callbacks are for flip gathers up those elements that are entering or leaving and passes them as an array to the associated callback so that you can do whatever you want with them so here we'll just take the elements and which again is just a parameter that's passed to the callback and we'll do a simple animation that takes the opacity from zero and a scale of zero to one for both of those over the duration of one second and for the on leaf we'll do a simple fade out and scale to zero now if we run this see that things animate on and off very nicely and if you return a gsap animation in the callback it'll cause it to be added to the flip timeline so that if the flip gets interrupted that animation is also forced to completion immediately now it's important to note that flip doesn't handle every single css property by default you can't just magically expect it to morph one entire ui into another it focuses on sizing rotation and position so it works great for something like this where we're you know shuffling going back and forth between containers this the only things that are changing here have to do with positioning really these sizes aren't even changing but if the sizes were changing or rotation was changing that's fine it would handle those as well but let's say that we're going to add some classes that only apply to when the elements are in container 2 so that they change color and then now if we rerun we'll see that if i hit shuffle the colors instantly change instead of gradually animating to those new colors but there is a solution all you need to do is add a configuration object to this git state call and tell it which properties you want it to handle as a comma delimited list and what that does is it tells flip to look at those properties record them in the state and then when we get to the flip dot from it will look at those properties as well and animate them so now let's run and we'll see that if we shuffle it indeed the colors are nicely animating and lastly let's cover a few extra little features that i think you're going to find really useful so let's run our animation here and it's just shuffling things we saw this earlier in the video but it's a little bit i don't know blah a little stagnant everything's happening at exactly the same time so it's a great place for uh stagger now for run so much nicer and we can even make our elements rotate a full rotation or more by adding spin true how fun is that and if you want to go the opposite way you can actually pass in a number here so one would be the same is true if you pass in a negative one that's the number of rotations or you know full cycles and so negative will make it go the opposite direction like so in fact we can go crazy and say a negative three and it'll rotate three full rotations it looks a little bit obnoxious but you can do it now maybe you want to add a class to your elements just during the flip maybe you have some special styles that should only apply during the flip maybe you want to handle you know z index or something which we'll touch on later but you can do a toggle class so we'll toggle this class on during the flip so in this case let's say flipping because in my css i've got a flipping class set up here that will add a 4 pixel white border so now if we run we shuffle we see that just during the course of the flip they get that class applied and lastly sometimes it's really useful to have a different z index just during the flip so let's take this example where we have you know the scrolling list and then if i click on an element then it expands and goes back down but notice that when it goes back down we have this strange overlapping issue and that's just because that's how it would naturally flow in the dom this element is technically it's next in the dom so it would be higher and so applying a different z index during the course of the flip is as simple as defining a z index in the flip so now if i run and i scroll down to that same image click on it and now when i click off it got that z index when it was going back down much better now the flip plug-in is a membership benefit of club green sock so shockingly green members and higher get access to that so it's not in the public downloads uh once you sign up then of course you can get it with the the download zip or we do have our own private npm registry and if you go to the docs there are plenty of showcases and how-to demos so if you scroll to the bottom you'll see these links and then if you click on them and then you'll get to a collection like this so you can poke around and see exactly how various things are built and that's it now you can use the flip animation technique in a way that's fully integrated with gsap for total flexibility and as always if you need any help drop by the green sock forums happy tweening
Info
Channel: GreenSockLearning
Views: 10,995
Rating: undefined out of 5
Keywords: Flip, gsap, greensock, animation, plugin, state, transition
Id: YftYHkS5Dao
Channel Id: undefined
Length: 24min 9sec (1449 seconds)
Published: Tue Jan 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.