Flutter Chained Animations, Curves and Clippers - Learn About Chained Explicit Animations in Flutter

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone and welcome to the second video of the flutter animations course in the previous video as you saw we worked actually we talked quite a lot about trigonometry and we also looked at animation controller animation tween and we also uh looked at animated Builder and transform and we created a quite a simple animation in the previous video and in this video we're going to build on top of what we've learned in the previous chapter and also uh I think during the introduction mainly of the previous chapter where we talked about trigonometry we're going to create a little bit more advanced animation I'll I'll show you how this animation looks like what we're trying to achieve I'll bring it up here try to zoom into it a little bit and you can see it's basically two half circles that are rotating around which axis they're rotating around I mean this will be actually difficult to see right now but they're rotating around the set axis of course because it's rotating counterclockwise around the center that is the Z axis right and also they're rotating around what seems like first like this is the y-axis and then the x-axis so you would probably think that other three animations don't worry if this is a little bit complicated right now but I'll explain it if this is actually just two simple animations connected to each other okay and there's no X and Y animation it's simply a y animation flipping on its head I will I will explain how this is working and uh I just wanted to tell you that when it comes to animations in any front-end framework it doesn't it doesn't just have to be flutter or it could be swift UI it could be jetpack compose wherever you're working with animations the important at first I'll get rid of this animation the important thing to remember is that the most significant phase of creating the animation is breaking it down into smaller steps so it's not just creating the animation but it's just to be able to conceptually understand what phases that animation has all right so sometimes when I'm trying to create an animation I stare at it for about 15 minutes so if someone creates Adobe XD or something they give me some animation and they say can you do this in flower I just stare at the animation just like a crazy person for a long time and that's simply because I'm trying to break it down using the tools that we have in flutter for instance transform stack as we'll talk about it soon actually not in the city I think in the next video we'll talk about stack and its importance in creating animations in flutter but you need to know the tools that you have and then you need to understand how those tools that you have are going to come come in handy when you need to create an animation so breaking down the entire animation into small steps and then delivering on those steps so when someone looks at an animation they think oh my God how do they create this animation it's magical but most of the times it's just a series of small phases connected to each other okay as is this particular animation okay and which we had a look at just now so it's just 200 animations connected to each other all right so without further Ado let me just start creating actually we could start creating the projects I'll bring up the terminal in here okay so let's say uh I'll increase this a little bit so I'm going to go here and say flutter uh flutter create example two and I'm going to say org is se.pixelity like this so you don't have to and you shouldn't probably specify the org as I did because that's my reverse domain name so you probably want to specify your own reverse domain name so let's go to example two in here and we do the normal dancing here I'm gonna say workspace settings as zoom level which is five and we don't have any third-party libraries in our animations but I'm going to go to main Dart and add my FSA which is flutter scaffold application which I explained in the previous example let's say select device in here then I'll say iPhone 14 pro and then let's see if we can run our application on that okay so as soon as we run this application on example two unfortunately we're not going to be able to see the previous one okay but just keep this in mind how this animation look like I can always run the previous example to be honest with you so that's not a problem so we can always bring up the you can see all the examples that we're going to do but example two unfortunately is going to be overwritten by this one and now that I'm thinking about it maybe it's actually a good idea to keep example 2 alive like the way it was because right now what I did is that I ran this code example two on this iPhone 14 pro Max and then we can't see the previous example or not the previous example but the actual animation that we're going to develop because this new application overwrote the previous application so I have a solution for that so what I'm going to do I'm going to stop this I mean you don't have to do any of this but I'm gonna bring up the example um code I'm going to run that on this simulator and at the same time I'm going to go and open a new one and I'm going to say open an iPhone 14 pro and so this is going to be what we're gonna develop and on the left hand side we're gonna have our current application and see how it progresses into creating this animation on the right hand side okay so I'm going to go here in this code and says iPhone 14 pro instead of the pro Max so this one is going to be the model that we're going to develop and this one is going to be the current application all right so let's see how things progress while these are doing their build so actually this is finished now I can see so this is our model I'll get rid of it here and this is going to soon finish as well so while these are ongoing and happening I think we need to go into a explaining the basics of how we need to achieve this so there are so many different parts to this animation I think we need to break them down all right so as usual I'll just bring my iPad screen so you can see when I write on the screen here we go okay so that's that then I will go ahead and start drawing the different phases of this animation for you okay so the first thing that you need to understand when it comes to animations is as I said it is made out of smaller steps so you have to break this down and the first thing you need to break down is how is this guy even drawn on the screen like what is the what is the components that are making up this animation all right so the first thing you need to look at is the shape all right how is the shape created you can see two half circles so then the question is how do we draw two half circles or half circles for that matter okay so you could say okay well half circles are easy to do you just take one widget and you break it into two but how do you do that how do you break a widget into two well there is an interesting widget in flutter which is called row okay so if you could place your components inside a row that would be really good so let's just draw a row in here I'm gonna do some reshuffling a little bit on the screen okay so let's say that you have a row good this is your row and then you divide it into two parts so what would be really good is if we could then draw two half circles in this row so the left part which is let's say this is a container equal to 100 points in height uh sorry width and 100 points in height same thing in here okay so something like this all right so let's say that these are two containers place inside a row so this is a row okay and this is container one cons one and cons two and let's say that's um that we want to draw two half circles so on the left hand side if you look in this component right here let's say that we want to draw a half circle in which we assign to the left hand side so what do we have to do if you then take your mouse or how do you say take the pointer of drawing to this point to the farther right most that you can go and the Y position because remember the canvas in flutter goes like this X and it goes like this in y just keep that in mind so that we don't have to repeat that fact over and over again okay so keep that in mind and so given that fact on this in this example in this container if we take the pointer go from so this point zero and zero and say go to the width for the X part go to the entire width which is a hundred okay here with the Y position of zero so take the width and the height position at zero move the pointer there and then draw an arc from that point to this point down here okay and the radius of this Arc should be half the width so this is half the width which is a radius okay so this is 50. so if you say take this point go from this point and draw an arc counterclockwise from point 1 to 0.2 then you end up with this half a circle okay so there are some Messes in flutter that you can take advantage of to draw these arcs so you specify the radius you see if it's clockwise or counterclockwise and then you say from which offset to which offset it should draw the arc for you okay and it doesn't necessarily have to be this kind of Arc like this is a perfect half circle but an arc could be like to say that you have a point in here and a point in here and your radius is like 10 which is right here then it would draw an arc that looks like this so it doesn't have to be half a circle sorry it doesn't have to be a perfect half circle if you know what I mean okay so let's go back to this note that we were drawing so that's one thing so that's the left hand side of the animation or the shape now the right hand side would be to say okay we're working now with this container in here okay so given that container let's stay at this point let's stay at the top left point which is the default point then what we want to do we want to take the radius again it's 100 divided by two okay which is in the middle and we go from this point which is right here and to this point which is right down here so we want to draw a half an arc with the radius of 50. from that point up there to this point down here and we say okay start doing this but do it clockwise this time because remember if you say from this point to this point down here counterclockwise with that radius it will draw a line back here where this component doesn't even exist remember this component takes this space in here okay so you want to draw your arc on the right hand side of the circle clockwise so it will then go like this all right so we've now broken down the component that we're going to draw on there on the screen so we need a row with two containers why don't we just do that why don't we just create a row with two containers in it okay and we'll specify a width and height and colors for it so that it will start already looking good all right and then we can make sure that that rows components are in the center of the row okay because otherwise your row like this if this is your screen then your rows components will probably just be here depending on their width and height we kind of want it to be in the center okay because if you remember our animation I'll bring it up let's see where it is uh here it's in the center horizontally all right so let's not complicate the animation at the moment more than it has to be and start actually creating uh these two components all right let's go back to our code and I'm gonna get rid of some stuff on the screen let's get rid of our app bar here and then I'm going to say the body of our scaffold it's a how should we say should we just say it's a row perhaps yeah let's say it's a row and we say it's main axis alignment is Center all right and we say it has children and we just create two containers basically all right so let's say we have a container and let's say container container and I'm gonna say it has a color and we say colors.blue and we say it has a width of 200 and a height of 200 like this and then I will create another container because remember in the beginning of that animation the blue container is on the left hand side it's difficult to see it because we have to restart the animation but to begin with the blue part is on the left hand side and the yellow part is on the right hand side okay it doesn't really matter the colors but I just want to create the exact same animation all right so blue part on the left and then we say the second container has yellow and then it has the width and height of 200 as well I can see that here we have some problems and we because we're running on a smaller screen and so it is looking like this as you can see all right so let's let's just change this and um we need to perhaps say that it is a hundred by a hundred I mean it doesn't really matter 100 by 100 also works did I just change it to 200 again like this all right so this is I would say this is fine right and it would be really good if you could put this in some sort of a safe area so it doesn't take this Dynamic Island and draw us on top of it or under it so let's say that the row is behind a safe area let's see if we have safe area here no safe area boom good so you see it is it the colors don't match so let's just change those colors so let's say it colors that blue and for the blue color I'm going to take 0x let's just say color const color 0x ff0057 uh where am I typing uh here 57 B7 oh my God 57 mb7 all right so the blue matches and let's just go to the yellow and say colors sorry const color and let's say x x 0x and we say FFF d700 actually I think it is right or four F's I think it should be all right so now colors match so we have the exact same blue color I think the blue color still doesn't really look exactly the same uh 57 B7 just fine yeah it is probably the same as just my eyes because this one is a little bit bigger okay so you see this is the first step I know it's baby steps but it is still important to understand that animations don't happen just like that you need to break it down you need to make one step like you should progress one step at a time all right so what is the next natural step well we have to clip these guys we should say that this is a container with a width and height of 100 but we want to clip it okay so the Clippers are very important part of animations so what we want to do is to say that hey we have a container and let me get rid of this annoying animation we have a container but we kind of don't want a part of it and that is like in on the left hand so we don't want this left hand part and on the right hand side we don't want the right hand part either so let me let me draw something on the screen so you see what I mean let's go back to our iPad screen uh here I'm gonna get rid of this node deleted and we could delete this node as well here and let's create a new node so let's say that this is one of our containers on the left hand side okay so at the moment it is completely filled all right so it is filled with a color and it is was it the yellow one no I think it was the blue one on the left hand side okay so let's say this is the blue container and we want to draw and basically from here to here and like this all right so this is the center of that container so what is happening is that we've colored this entire container but what we want is to clip this part out so this part that I'm drawing on at the moment should be clipped out of the picture okay so in order to do that we need to use uh Clippers and there is a component that does this in a flutter and it's called clip path right so the important thing to understand about clip path is that you specify the shape that you want to behold sorry that you want to hold on to so you wanna you wanna uh basically from let's go back I'm gonna delete this and let's go here so you want to keep this part that is here on the left hand side but you don't want to keep this part okay so with clippers your job is to define the shape for what you want to keep which is this guy right here okay so don't think that oh it's a Clipper so I have to clip out something so I'm going to clip out this thing okay that's that's not how it works so you need to clip you need to ensure that you're keep keeping onto this component right here okay so I'm going to show you how that how that code is going to look like and if it's the first time that you're working with clippers it could be a little bit maybe difficult to understand them to begin with but I think I think we need to break that part down as well so what I'm going to do is to create a little enum in here so let's just say we have an enum so let's define the two parts of the circle we say the left part and the right part so let's say Circle side and we say left and right all right so now given the circle side let's go ahead and create a path using which we Define the part of the circle so the left part has this thing right and the right part you know has that other thing which is on the right hand side we've already talked about it that's why I don't explain it so much all right so let's say we create an extension extension uh on I would call a two path on Circle side like this and we want to create a path all right a path object don't worry I'll explain it all so let's say pass and say two path and we give it a size as well because it is important that we specify the size to this function because otherwise this function doesn't know the size of the container that it has to clip to all right so don't worry about it let's just create a path in here we just say let's say VAR path is a path like this all right and then we need an offset basically a point to start our drawing from so in this case we say the drawing has to start from this point up here and it has to end up at this point down here and it should draw an arc counterclockwise okay so let's say we say an offset we have an offset parameter in here and not parameter but variable and we say also a Boolean that should say whether it's clockwise okay then we switch we say switch self like this and like this or sorry not self this and let's add the missing cases in here so all right let's start with the left hand side so for the left hand side what we want to do is to say that in this path the pencil remember in every path there is a pencil that is like you literally drawing on the screen the pencil should first move to this point what is this point I mean where does it exist remember the x-axis is here the y-axis is here this points X Point sorry this point is x coordinates is the width of this container where do we get the width from it is the offsets sorry it's in the size okay so let's say that path move to the x coordinates is the sizes width and what is the Y well the Y is basically nowhere it's it's in zero y hasn't even gone down we're right here okay so the Y is zero okay so we say okay we've moved the pencil there now we want to basically say where we want to move to it is down here what is the coordinates for this guy remember the origin is here so here is literally its x coordinate is equal to the width because we've gone all the way from the left to the right it's equal to the width and the y coordinate is the entire height okay so we say we want to move the offset is let's say size width and size height okay and then we say it is this clockwise no because it has to move from this point here like this so it is counterclockwise remember clockwise goes like this okay it is like a clock so this is counterclockwise it's going the opposite way so we say clockwise is false all right so we've calculated that part let's do the same thing for the right hand side and let me just draw a little bit on the screen for how the right hand side looks so I'm going to move around here a little bit on my chair to bring up the iPad screen so let's just delete this note actually maybe I shouldn't delete this node maybe I should create a new one okay so let's say that right hand the right hand side which is this container we need to ensure that we start from this point so I say start and in here we say end okay and then the center or the radius is going to be half the width so this is our radius and we're going to draw a an arc clockwise through that okay so we say start from this point which is 0 0 okay this is zero and zero and this point and is what 0 and its y position it has gone all the way down to the height so it's equal to zero and height that's our offset and the radius is half the width okay because if this thing is the width radius is width divided by two and width usually in in case of circles we're basically talking about diameter so this is either with or your diameter okay with or diameter maybe I should actually remove that because mathematically that doesn't look so good how do we how do we Erase here I wish I had my okay Somehow Here eraser like that okay so uh now we have this uh so let's start actually defining these variables so I'm gonna go here and let me put my pen back also on my iPad it makes a little bit of a clicking sound so I just want to avoid that so the path we just say do we have to move anywhere by the way no because the pencil on a normal Canvas OR in a normal path in flutter by default is in zero zero so you don't have to move it in this case when you're drawing the right hand side of the circle so let's say we don't have to do move two but we say offset is equal to we want to move here remember the x coordinate is 0 and the y coordinate is the height so we say is an offset equal to zero and size height all right and then we say well the arc should be drawn using a clockwise motion so let's say clockwise is equal to True like that all right now that we've done that what we need to do is to draw an arc so we say path Arc two point okay you can see it has some parameters and it says Arc end which is your offset then let's just say move to this offset then it has a parameter for radius it says okay what is the radius and we say it is a radius it's a elliptical all right and it says okay what is the width sorry where where is the center of your circle using which I need to derive the uh the radius then we say okay you need to create this Center at width divided by 2 and Heights divided by two remember okay I think that part do you understand I have to explain it okay so the center we're specifying the center so we say size width divided by 2 and size dot height divided by two okay so we specified the center okay and basically using this Center and flutter will understand the the radius then we say clockwise is the clockwise parameter all right so now we've defined that path so now that you've done that you need to also close your path all right because if you don't close your path the pencil is here but it doesn't understand that it has to go all the way to the top to close the path so a lot of students actually have problem understanding how path close works and the way it works is very simple so let's just say I draw a smaller container here so what we did is they said okay go here and take this Center and take this endpoint draw an arc here but okay how about this line down here let me actually undo this somehow let me let me bring up my Eraser and basically clean this so this is what we have specified at the moment to flutter literally we said that go from the top left to the bottom right but then we didn't close the path so there is a function on path that is called close which specifies that okay you've done this line now here now close it so go from where the pin is right now which is we left the pen right there remember we took we took basically the circle we went like sorry half the circle we went like this so there's where the pin is at the moment then we need to tell it to close this path like this okay who looks like a car flipped on its head so that's what close means we need to close that path in order to ensure that we've actually created a complete path otherwise the path is uncomplete all right so let's go in here and say that the pass needs to be closed now so we say path close and then we say uh return path like this so we return it also I noticed that we created a VAR in here I wonder if you should say it's a final because we're not actually changing the value of that path we're only mutating it internally okay so now we have that part okay how do we apply this guy now to our containers well you need to create some sort of a widget that turn turns this past to life right we're creating a path object but path isn't a widget okay so somehow we need to turn it into a widget so how do we do that well there is there is a trick to doing that and um you need to create something called a custom Clipper okay so let's go ahead and create a widget in here and we're going to call it half circle Clipper okay so I'm going to say that this is let's just say class half circle Clipper and we should we should say it extends custom Clipper and it's a custom Clipper of path all right so in here we need so this is widget remember custom Clipper is actually a widget so if you go to let's see if you can find it listenable add listener oh wait a minute actually sorry about that um I'm sorry about that the custom Clipper is actually not a widget we're gonna place this inside a widget okay custom Clipper is going to go into a widget and I think actually that widget was called clip path all right and clip path requires a custom Clipper so first we Define our path then we place it inside a custom Clipper and then we put this custom Clipper inside a widget which I think was called clip path or something like that we'll we'll find it out don't worry but this guy's job right now is just to embed this path into itself all right so let's go ahead and program this guy so there are a few functions that we have to implement so let's just get help from Visual Studio code and say two missing overwrites okay you can see that it says give me the clip and we say okay it requires a path and we know that we have the path in here but in order to get this path we need a circle side so let's get a circle side first into this so we say final Circle side is a side and then we create a Constructor for this guy like this all right and we say that it is a required required like this okay I'm not sure if you can create this a const actually it seems like we can good and so now that we have that in in this guy in the path let's just say that we say side uh two path and we pass the size to it you see how easily it plugs and plays a lot of people also prefer to have like this code the path creation right here okay I just thought so that we can separate every bit of the code into smaller bits so we don't get confused how things are working together but if you feel like it is better for you to move this code which is here uh down there into this function be my guess just do that if you want to okay then we have to implement this function and a lot of people also get confused about this function so how this guy works is that it tells you of changes that are happening to the parent widget and it says something happen do you want to redraw your paths all right and in this case we're just going to make our lives easier and say yeah whenever you say something has changed we're just going to redraw our path because the changes to the parent widget might change the size of the of the clip area so let's just redraw everything okay not everything actually about this clip path okay we have this custom Clipper so let's just go ahead and create the embedding widget for these containers and that guy is going to be a clip path okay so let's go to the left hand side container remember the blue one here it has to be inside a clip path so I'm just going to say embed wrap it with Widget and we say clip path and it says okay it's actually interesting that it doesn't complain that the Clipper isn't specified I mean you have always a cloud path because you want a Clipper okay and you can see it's Clipper is a half circle Clipper with the left hand side and we do the exact same thing for this container so we say wrapper with Widget and we say clip path and this guy's Clipper uses the right hand side so what I'm going to do is I'm going to change the screen like this and then bring up our simulator and go here and I'm just going to press save and then all of a sudden you see we got that circle shape all right so that is pretty much what we wanted from our application you see we basically got this uh down right now so the shape we got working now we need to start working on the animations all right so what we need to understand is that this animation looks a little bit complicated and um the calculation for this could be a little bit difficult to understand but is in fact very very easy okay so what I'm going to do is I'm going to restart this animation just have a look at how it starts one more time one more time blue on the left yellow on the right and then it just rotates it rotates counterclockwise one more time I'm just going to keep restarting it so you see the first part okay rotate counterclockwise like this okay that's really good so I'm just gonna keep repeating this as I said I usually look at these animations quite a lot of times and also there is a little bit of a bouncing effect right it bounces so how have we achieved that guy well I'll I'll explain that to you as well because in the previous example we looked at animation but we didn't actually look at curves for animations all right and also one more thing um just let me just restart the animation a few times you can see in here that the rotation is happening around which axis is the z-axis right it is happening with the z-axis that starts from the screen and goes into the screen okay so we need to keep that in mind so what I'm going to do is or what we're going to do is to turn this guy homepage into a stateful widget first okay so let's just say we turn it into stateful widget and then we're going to go ahead and create the animation or animations but we're gonna start slow and we're going to start with the counterclockwise rotation animation okay so this little effect that goes like this so let's go into the state of our home page and I'm gonna change this like this so we see the full screen and let's say we have a late animation controller and we say it is a counter clockwise rotation controller so this is our controller and also and we want an animation as well all right remember the counterclockwise rotation controller will go from 0 to what one zero to one but every time we rotate this guy you can see we're rotating by 180 degrees right so just let me restart this you see blue on the left and yellow on the right and then is blue on the bottom so it rotated 180 degrees right so like that you see 180 degrees not a full circle because if it was a full circle it would just go around one more time and the yellow will end up exactly on on the side it started okay and so for those of you who have a little bit of difficulty imagining how that actually works I'm going to draw on the on the screen and I'm going to delete this note that we have in here actually I decided not to delete so let's just go here and create a new notes okay so here is where we are starting so this is the blue part like this okay so I'm going to say blue and we're going to say this is the yellow part like this in the first part of the animation if we go and have a look at it let me just bring it like this and I'm going to restart the animation you see yellow ends up on top okay yellow ends up on top so we're going from this shape on the left hand side to this shape yellow on top so yellow like this and blue like this and we know that the animation is happening counterclockwise like this okay so if you take this shape right here and you rotate it counterclockwise so that this yellow goes like that and ends up on top counterclockwise then you're actually rotating 180 degrees right because if you rotate it 45 degrees so this is zero degrees let's say zero degrees if you rotate it 45 degrees then you end up with this shape like this yellow right so I'm just trying to break down this animation for you so this is 45 degrees right and then if you rotate it to 90 degrees then yellow will be here like this okay yellow and blue and that's what we're trying to achieve so when I said earlier that we're going to rotate this guy 180 degrees that was actually that was incorrect we're going to rotate this guy 90 degrees okay so that is going to be you can see in here because this line if you imagine this line in the middle right here okay so we first we start with this line and we're ending up with this line down here so start and then end all right so how does this line line go like that and ends up like this so it's just it's 90 degrees right so it's moving 90 degrees so sorry about that if I mention that it is rotating by half a circle it's actually rotating by a quarter of an entire circle so if half a circle which is this angle in here which is 180 degrees and this is half a circle and then we're rotating 90 degrees so if half a circle is pi then 90 degrees 90 degrees is pi divided by 2 right and also since this our canvas you remember when we're working with like counterclockwise movements in flutter then we're actually talking about negative angle angles so let me bring up the canvas again in flutter and this is something that we talked about quite a lot in the previous video so canvas starts right here and integonometry canvas starts here so this is trigonometry and this is flutter okay so intrigonometry if you want to go from this point here start and we want to end up in here then we say okay we're talking about positive angles so this is 45 degrees and this is 90 degrees right so we go like this but in flutter since we want to go since the canvas is rotated like this when we talk about going counterclockwise then your angles are negative all right so you're not actually talking about 45 degrees you're talking about minus 45 and you're talking about minus 90 or you're basically saying that the angle goes from zero all the way to minus pi divided by 2. right because that minus 90 is minus pi divided by 2 because Pi is actually 180 degrees so 180 degrees divided by 2 minus it's minus 90. so we want an animation controller that goes from 0 to 1 and then we want an animation hooked to that that takes the angle from 0 to What minus pi divided by 2. all right so keep that in mind that's the animation that we're gonna create in here and also remember our animation has to bounce a little bit right it is doing this little bouncing thing so we have to give it a little bit of a curve but don't worry we'll talk about that so let's just create an animation in here we see an animation of double and we call it counterclockwise rotation animation all right so let's go into init State here and then we say right after the call to Super we're going to create our counterclockwise rotation controller so we say in here counter clockwise rotation controller and we say it is an animation controller that let's just say it takes one second to do its rotation and we have to say vsync I've explained this before in the previous example so you please watch that previous video If you haven't and we say with single ticker single taker provider State mixing all right so this is our animation controller which takes one second and that means it takes one second to do this Z animation uh like you're seeing here okay and then now that we have the animation controller we have to create the animation itself all right so we say in here then we start easy we say counterclockwise rotation animation is equal to I'm not going to take the GitHub co-pilot suggestion let's just create the tween and we say we start with the angle uh We Begin it has two parameters right oops I don't want this okay we say we have a begin we start at zero degrees and we have to go to minus pi divided by two and remember Pi is in dark math so let's say import Dart math show pi like this and so I hope that now you're understanding angles uh a lot easier all right A lot of people will look at this and be like why why is it minus why is it like pi divided by 2 but we've already explained all this so and now that we've created the tween we also need to animate our controller so let's say we animate our controller so that we get an animation object back okay but before this I want to show you something you see whenever it does a z rotation it's bouncing it's like ding ding ding ding you see it's as of like you were dropping a coin all right so that's one curves into play come into play so a curve is a lot of people also get tripped on this I'm going to show you what a curve is it's very easy to explain I'm gonna create a little note in here so let's say that this is your animation controller like uh I'm gonna Draw Something in here so let's say that this is an animation controller and that goes how should I explain this one in here actually let's say let's say that an animation controller goes from zero to one like this all right so it has a very simple pass it goes like this all right it starts with zero goes to one now you want to create a curve out of this so you say okay let's just break this guy down let's say that this is the 50 sign of a 50 mark this is a 75 Mark so it's 75 complete and here is 100 complete that animation controller now I want to create a curve that at the 50 Mark of the animation controller it jumps a little bit down and then it goes up and then it jumps down in here and then it goes up that's that kind of drop effect that you just saw and this is a curve as you can see it's very simple it is a curve you can see it okay so a and a curved animation as it's called in flutter it takes the current curve or the current progress of this animation controller and it applies a curve to it and there's so many different types of Curves like you can find a curve that looks like this you can find like a curve that goes like this and comes down and then here and then here okay so there are so many different types of Curves and in this particular example I think we're gonna call and we're going to create some curve that is called Bounce out or something like that I think so what bounce out does is that it creates a curve that looks kind of like this it goes here and it almost goes to the top and then it comes down it goes almost to the top comes down and goes like this and also there's really good documentation on the web for flutter where you can see all these curves visually explained so I'm not going to tell you exactly where it is just go ahead and do some research and find the animation Curves in flutter they're very well documented they're all in just one document so you can see all the Curves in just one place it's very very exciting to look at so here what we're going to do inside this animate if you see look at this function it expects an animation so what we're going to say okay we're gonna animate this guy but we're gonna wrap our animation controller within a curve so let's say a curved animation here okay and it says okay what is the parent uh well the parent is our counterclockwise rotation controller and the curve is going to be from curves object curves and we say bounce out I think all right so that's our rotation animation okay we've created that now so what do we have to do before we actually start using this animation well we go ahead and we say that we have to dispose of our animation controller this guy this pose and also we have to start and basically doing our transform so let's go ahead and say this what should we do how should we actually transform this guy so uh what we could do is to ensure that this entire row here as you can see in here this entire row gets rotated around the z-axis in the center okay so we said the row needs to be inside a transform transform okay and let me bring the iPad again just to explain this part a little bit more so let me create a new note and you can see this is our screen okay and this is the row that we've created so let's say that it is here okay kind of and this is like our half circles like this now I mean it's not perfect drawing but you get the point now what we want to do is to rotate this entire row around its entire Center okay center is right here for the row and also for our half circles as well okay so we want to rotate it around the center so you know what I'm talking about I'm talking about those was it the offset of the transform it was something like alignment I think it's called so let's go in here and say to transform has an alignment around the center point and we say alignment center and then we say okay we want to do a rotation so we start with a transform parameter in here and we say Matrix Four so let's just reset Matrix Four we say identity and we've talked about this in the previous example and I'm just going to say rotation rotate Z like this okay and the angle is coming from our counterclockwise rotation animation it's not coming from the controller but it's the animation remember the controller goes from zero to one the animation goes from zero to minus pi divided by 2 which is minus 90 degrees which is pretty much 90 degrees counterclockwise Okay so that's good we have that but of course nothing is going to animate because we don't have an animated Builder all right so let's go ahead and say this entire transform should be inside an animated Builder so we say uh animated Builder somewhere around here so let's say I wrap it with Widget animated Builder and then of course we have to give it an animation which is our counterclockwise rotation animation we have the Builder function as well remember in here and let's just go and remove this child from here and say transform we get rid of it boom boom all right like this and we place it inside the Builder like this and we say we need to return it as well all right like that good so now that we have that you uh you will start seeing some life into our application soon because one thing that we've missed is to actually start our animation so let's go into the build function right here on top and we say counterclockwise counter clockwise rotation animation controller sorry not the animation but the controller itself we want to First reset it okay reset means that every time the build function is called start from zero okay don't start from where you are because then that might not work if you're already at if you're already at one for instance okay so we say we want to call the forward function in here but what I want to do is I want to put this guy inside some sort of a future delayed all right so what we could do is to say that when the build function gets called after one second start this name so what we could say is say future delayed and we say the duration is one second let's say one second and then do this code like this boom boom all right so this will this will be actually fine you can see in here did you see that bounce and then it stops right there so uh let's just see it one more time I'm gonna resize Visual Studio code so you see this I'm gonna restart the application there we go after one second there we go okay so it would be really good if you had a little bit of an extension for this guy so it'd be really good if we could just say forward in one second okay so let's just create an extension in here and we're going to say uh extension where should we create that extension on void callback and this is and to be honest with you this is a pure flutter so I'm not gonna I'm not gonna explain this so much all right so let's just say future void uh delayed delayed like this and we say duration is a duration like this and then let's just create an error function in here and we say that in future delete and then this okay good now that we have that let's just go ahead and use it so in here down there in the build function let's just take that and then we say forward and then we can call forward I would say with just dot delayed uh forward dot delayed did it delete the code uh no extension on void callback delayed uh to me that looks fine but that's simply because we're calling this function we shouldn't call this function this returns void so we just say it's delayed delayed by duration of one second like this all right so you see the code looks a little bit nicer we say reset and then go forward with a delay of one second all right so I'm going to bring up our simulator and let's change the size a little bit like this and then I'm going to restart the application boom and then if I press command s it starts from the beginning you see because it resets so for those of you who don't know why this is there let me just remove that and then we just say forward delayed let me restart the application from the beginning you see the first time it works but then if I press command s you see nothing happens simply because the animation controller has gone all the way from zero to one it has no nowhere further to go from this point and that's why we have this reset in here so we say every time the build function is called reset the animation controller go from zero and then go forward so command s goes from zero one more time goes from zero all right so we got that part working now so there are some optimizations that we could do in here and this is I mean I'm trying to break animations down to one step at a time but what we what we need to know is that if you look at the code that we've written in here this child which is this row at the moment at the moment really it doesn't change right like it is a role all the time there's nothing in this guy that changes so what you could do is to because you see we have a child parameter in here and the point of that is that animated animated Builder also has actually a child parameter that you can create like a child in here and that child will get passed down here okay but the reason we don't do that actually that's kind of like a an optimization and but we don't do that right now but because soon we're gonna change these rows as change this row as well on all these containers so hang on tight because we're we need to take care of those things so so what happened right now we took care of that animation uh the Z animation but we now need to flip these guys on top of themselves so this is the part that this animation gets a little bit complicated all right because if you let me bring up the iPad and look at this animation the way it is happening right now I'm going to bring up the iPad let's see if I can bring up the screen so you see it as well so what happens if you look at that animation just the flip animation so I'm just going to draw the blue half circle in here okay and then the yellow half circle so what we want is simply to flip this circle to this side around the which axis this is x in flutter and this is y right so half a circle this is a container that we've clipped half of it so what we're gonna tell flutter is that hey we want to flip this guy or this entire container basically that contains that guy around the y-axis in the middle and flip it to the side and we want to do the same same thing but opposite for this guy so we want to take like this guy on the right here okay we want to flip it around this point to the right to the left so there is a little bit of a rotation uh happening in here around the y-axis okay so it's the y axis about what happens when our other counterclockwise rotation happens so let me just create so you remember that this is our Circle it starts like this okay it starts like this and then we so this is blue and yellow and then we do the counter counter clockwise CCW animation and we end up with this shape where the yellow is on top and then the blue is at the bottom so what happens in this case now we have to do we have to flip this guy around the x-axis so that yellow comes here and blue goes there hmm But what happens then when this shape changes one more time and then it rotates counterclockwise again counterclockwise and then the yellow ends up here yellow ends up here and blue ends up here and then we want to rotate now all of a sudden we have to rotate around the y-axis so it seems like the rotation happens first in the beginning actually do not disturb became off so I want to set it to on so let's go in here and say focus is do not disturb everywhere like this so let's say that we go in here and say okay well the first time around the you know the first shape on the left hand side the rotation around the is around the y-axis okay then all of a sudden after we've done one counterclockwise rotation then all of a sudden we have to rotate around the x-axis and then again we when another counterclockwise rotation happens of 90 degrees we have to do what we have to do again the y-axis so is this really true do we have to do this or should we just say we always rotate around the y-axis but how would that work and this is where some people get tripped up when you have a canvas like this in flutter where this is your x-axis and this is your y-axis when you flip this with a transform and with a counterclockwise rotation to the left for instance basically counterclockwise 90 degrees all of a sudden this shape will be like that that it comes here and this will be that that comes here okay so your X will be here and then your y will be here so all of a sudden you flip the canvas I mean you're rotating the widget of course but you're actually rotating the canvas that holds the widget as well okay it makes complete physical sense in mathematical sense you're flipping not only the canvas sorry not only the widget but the canvas that holds the widget so now that you've done this now that you've flipped the canvas with the first counterclockwise rotation guess what where is the y-axis it's here it's not down it's not going down it is actually here it's where the x-axis was and then if you flip it one more time then your y-axis becomes where it was before and your x-axis where would that go it will go here okay so I think so at least so it's it's a little bit like at the moment populated on the screen so I'm kind of like losing track of how I'm drawing things on the screen but let's create a new um note in here so we say we start like this so this is X and Y okay X and Y then we say counterclockwise rotation of 90 degrees then what happens is that this is 90 degrees in here right 90 degrees y goes here so we say Y is all of a sudden uh here and X goes there so X will be where will that be so it will be Y and then X right so this will be our X and this will be our y then we say we do another counterclockwise of 90 degrees then y goes here so it will be if we draw a line like this y here and X will go like this so this will be our Y and this will be our X and then if we do another counterclockwise of 90 degrees then your y will be like this and your X will be like this so y and then X and then of course another counterclockwise of 90 degrees counterclockwise of 90 degrees then your y will go like this so it will be like this and your X will be like this so you've done 90 degrees and so 90 degrees which is one two three and four so if you do 4 90 degrees you end up with 360 degrees so you end up here where you started fun right this is pure pure just mathematics so this is how our animation is going to look like so for those of you who think that we are flipping first around the y-axis and then we're flipping around the x-axis I'd have to say no we're actually only flipping around the y-axis the difference between this shape in 1 and 2 is that two has the entire canvas rotated so that your X that was here before that was like this before X Y has been rotated so like this so if you're rotating around this axis you're actually again rotating around the y-axis which is how you started here okay so this was a lot of theory but I just wanted to show you that that part where you see that the animation is happening like here and then here in the middle it's only flipping around the y-axis all right so let's go ahead now and create our flip animation and that part is going to be a little bit complicated but don't worry about it so let's create first uh the animation and sorry controller and the animation for it so let's say late animation controller and we say that this is our flip controller and then we need a flip animation as well all right so inside in state we need to go and create this flip controller so we just say flip controller like this boom boom and let's go in here and we say flip animation and we say the flip flip controller is equal to an animation controller that has a v-sync of this and also a duration of one second that's fine as well but now we're going to get into trouble because you see we're extending now or we're actually conforming to a to this protocol in here or our mixin which is called a single ticker provider State mix and one is single ticker provider mix and simply means is that it only has capacity to allow one animation controller to sync its uh vertical a sync with this widget so you can't have two animations basically or two animation controllers syncing with the same widget we need to do is just to change this guy to a ticker provider statement so not a single one okay it's very simple so we have now the flip controller with the same vsync what we need to do is to go ahead and create the animation for it as well okay so the animation for this guy how how is that gonna work let's go back to the canvas in here if you remember what we need to do is every time we rotate this guy sorry around the y-axis we have to rotate the widgets by how much do you think it's 90 degrees or do you think it's 180 80 degrees well if you're flipping something completely horizontally or vertically around its Center you're flipping it by half a circle okay it's just half a circle uh it's a 180 degrees and to be honest with you this is very difficult to draw on the screen so it's difficult for me to show this on on the on an iPad screen but I will actually do my best let me let me see if I can explain this part how much to flip how many degrees it is so let's say that let me see if I can draw it so if you have um if you have boom let me see if I can draw with my pencil uh we have this uh half a circle in here and half a circle in here okay and if you think that this guy this point in here should end up here so it's a start and this is an N right so you have to flip this guy like that come here well if you look at this it is half a circle right because if it was a full circle it would come here and it would go back so this is 180 degrees flip and this is 180 degrees flip so if for this point to come here it needs to rotate around the y-axis y-axis and by 180 degrees and 180 degrees is equal to Pi all right so our animation the animation object should specify a 180 degree angle so we say flip animation flip animation is equal to a tween of double so it is a value between two values it goes from zero to Pi and we also give it a bounce out curve as we've seen in the previous example so I accepted this suggestion from GitHub co-pilot because it was very easy and it actually had all the values that we want to enter and I've already explained all of these okay so it shouldn't be a surprise for us okay so what we want now that we have these animations and the animation controller let's go back to our application let's see how we can bring up that simulator get rid of this and uh actually what I'm going to do is I'm going to bring this guy up and what I'm going to do behind the scenes is to change the animation durations so you see it a little bit slower okay so let me bring it up look at the animation what happens okay it bounces out and then when that bounce out finishes it rotates around the y-axis even though it looks like the x-axis but it's actually the y-axis because the entire canvas is flipped all right so let me restart the animation One More Time Boom you see first the counterclockwise rotation and when that ends we want to start the next animation so how do we do that well there's something in Florida called status listener okay so status listener is just a callback on an animation controller which will tell you when state of the animation changes all right so let's go ahead and say well we want to listen for when the counterclockwise rotation controller has finished its animation all right also before we forget let's go in here and dispose of our flip controller this pose pose like this all right so let's go ahead and in here and say status listener and we say when the counterclockwise rotation controller at status listener like this when it finishes so we say if status for our counterclockwise rotation is equal to completed like this then what we want to do is to actually create a new flip animation all right so we say the flip animation should again go from 0 to Pi and actually this one is going to be a little bit different I think because so what the flip animation needs to do is Ensure that it doesn't always go from 0 to Pi it needs to go from its current value to its current value plus pi so this is a little bit difficult to explain but let's just say that you've already done one animation so let's just restart this so what is the flip value at the moment zero degrees right but all of a sudden it goes from zero to what 180 degrees now the next time the flip happens after this rotation we want to go from 180 degrees to 360 Degrees boom okay so keep 360 degrees now we do a counterclockwise and once this finishes we want to go from 360 Degrees to 360 Degrees plus 180 right so this this animation needs to be continuous so whenever the counterclockwise rotation finishes we need to change we need to create a new flip animation all right so I'm going to create it and put it in here and we say it shouldn't go a bit between 0 and Pi it should actually go between flip animations current value to flip animations value plus pi which is basically the the first difference that we create in here so we always say we want to go Pi amount okay in the beginning we go from 0 to Pi but in here we say we go from the current value to Pi so we always increase by pi all right and then after that is now let's see where this ends okay and then we say and then we reset the flip controller and start the animation so the flip controller should always go from zero to one and then we reset it and then we just say forward without any delay all right good so let me restart our application let's just have a look at the console we don't have any errors and how does our application actually look like let's see let me just restart we do the flip all right but no one is actually doing any animation for the flipping so let's go and change that so what we want to do is to say uh I mean there are different ways of doing this but I'm not going to do the complicated way but just know that the way that we're going to handle this right now is not the optimal way but in the next example the more advanced we get we're gonna make this a lot more optimized okay because in this example we're actually going to use multiple animated Builders we're actually going to use three animated Builders okay but really to continue to create this uh effect that we want you just need one animated controller uh sorry animated Builder but just to make things easier for us I'm just going to use three okay and I'll explain the reason later in the later examples so what we want is to say okay the clip path in here uh for the first one what we want to do is we want to rotate this guy okay so remember this is the blue side which is you can see the blue color in here which is on the left hand side so let's say that this clip path wants and it wants to be inside an animated Builder so let's say we wrap it with a widget animated Builder like this and then we have the child so let's just remove this and put it in the Builder and build our function in here and we say return this okay and it says okay what is my animation all right we say your animation is the flip uh controller all right so this guy is happy all right but it has no animation really at the moment I mean it has the animation parameter but no one is actually transforming this guy and that's okay let's go to the second clip app clip path which is the half the circle on the right hand side and we say rapid widget and we say it's an animated Builder we do the same thing we take the child from here and then we say we have a builder like this and we return that child in here like this and it says okay where's my animation so your animation is also the flip animation all right and then if you run your application right now it just looks fine but really nothing happens after that all right so what we need to do our job right now is to say okay apply the transforms around the y-axis remember we need to rotate these guys around the y-axis so we say the animation is there well let's go and wrap this clip path inside a transform like this transform transform and we say the alignment now it's important it's very important to understand the how the alignment of this animation actually works so let me bring up the iPad screen again I actually explained this a little bit earlier but I'm going to do my best to explain it one more time in here so let's go and say that we have uh we have this row so this is our row and these are two containers in here and this is half the circle here and this is half the circle in here so when this guy on the left hand side wants to flip to all the way to the right hand side it has to flip around the y-axis right but around which alignment should it flip around the y-axis here because remember this is also the y-axis this is the y-axis all of these are y-axis where should it flip around well we say it should flip around this point right so this entire thing should flip around the center right points now when it comes to this guy which is remember its container is here okay this same point that this guy has to flip around on is the center left Point okay in this container this point is in the center to the left but in this container on the left hand side this point is in the center right okay so remember center right for the blue one and Center left for the yellow one all right so let's go add to our code and we say the blue one the blue container is center right alignment so we say alignment is alignment center right and before we forget we go to this transfer oh actually we shouldn't maybe do that let's just do this one first and then we say it's uh transform is a matrix for identity and rotate around the y-axis with the flip animations value all right great so let's take the same thing uh and let's just go in here in this clip path and we say this clip path also needs to be inside a transform so we say transform and we say its alignment is Center left remember right center left for the right container because it has to flip around this point to the left and then we say it's uh transform is identity rotate y the same thing basically so before I start this application let's go to our simulator here and then I'm gonna just go here and then restart the entire thing one two three there we go did you see the flip so one more time like this boom boom good now what happened why is everything stopping well the reason behind it is that we said that once the first animation finishes then the second animation has to start but we never said that the second animations finish also have to Kickstart the first one again okay so let's take care of that so let's say exactly the same thing that we have up here for add status to the counterclockwise rotation controller we have to do something like that for the flip controller as well so let's go in here and say flip controller controller dot add status listener and then we say if status is completed and oops this is a lot of code I don't want to accept that because we need to write it ourselves okay boom boom add status listener good do we have extra stuff or no all right like this so we say if the status is completed then we we have to create the animation from scratch so let's go to and which animation is it is it is the counterclockwise animation all right so let's take the counterclockwise animation that we had here okay and you see we put it in here but this one as well it shouldn't go from zero but it should actually go from its current value so we say go from your current value and go to your current value again value okay plus that rotation you want to actually do so it's just a continuous animation all right and then we do similar thing that we did up here with the flip controller we say the counterclockwise controller counter clockwise rotation controller you need to reset it first and then we save forward okay and that does the magic for us let me just bring up our simulator which is here and then I'm gonna reset the entire application like this one two three see oh my God it's so funny I think we're actually rotating around the wrong axis so let's go in here and see what we're doing so now that we're getting this funky kind of Animation in here it could be a simple explanation that we've somewhere missed the status listeners implementation so let's go in here and have a look at how we've done the first status listener for the counterclockwise if status is completed then we have the code in here so I usually what I do I look at completed and ensure that all the code is inside that completed block so you can fold it and you can see yes it is inside completed but if you go in here and complete it and fold this code you can see this call the reset and forward is outside the completed call so let's take this and bring it up here okay and then we can reset our animation have a look there we go there there we go in there good fantastic now we're pretty much basically done with this animation so let's bring uh this this animation here and I'm gonna change that guy as well to have one second delay for its animation and restart it so you can pretty much see them side by side they're doing the exact same thing all right so I hope that you enjoyed this video as well it was very long it was you can imagine my how I feel right now after all this explanation and I can totally imagine how you feel after all this explanation but what I want you to take take away from this video is that you need to break animations down animations don't just grow on trees okay you need to break them down and ensure that you understand the basic blocks of these animations all right how they're interacting like is there different animation controllers are there different animations and how are they connected to each other break it down into a timeline all right and then your life will be a lot easier and also the second part of the mystery is of course solving which widgets you have on the screen how you have to organize these which is how they're rotating how they're animating Etc okay hope you enjoyed this video and I'll see you in the next one
Info
Channel: Vandad Nahavandipoor
Views: 16,752
Rating: undefined out of 5
Keywords:
Id: md1vrcHyxig
Channel Id: undefined
Length: 75min 50sec (4550 seconds)
Published: Tue Jan 31 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.