Continuing with our animation exercise from the previous part one.
We'll add in some more animations to our angular application.
In particular, we will add in an animation that will be triggered
when the route changes occur within our single-page application.
We will also add in an animation which enables
a view to be displayed when the data is fetched from the server side,
so when you're dismissing the spinner in your view and then rendering the view,
we want the view to be projected onto the screen
rather than simply just appearing all of a sudden.
So, a couple of new animations that we will add in this exercise.
Along the way when you have multiple animations in your application,
it may be better to refactor the code in a way that is more
manageable rather than including piecemeal
every little bit of a trigger into each of the files
within our components of our angular application.
So, let's do all these steps as part two of the animation exercise.
The first thing that I'm going to do is that we will refactor
the code that we have already done as part one of this animations exercise.
This approach that I'm illustrating to you here is just my suggested approach.
You don't necessarily have to follow exactly this way,
but I feel that this helps organize the code much better.
So, what I'm going to do is just like we had a separate folder for services,
we had a separate folder for the shared resources and so on,
I'm going to create a new folder named animations.
We will store all animation related code there and then make use of it by importing it
wherever required within our components in our angular application.
So, going to our code,
within the app folder I'm going to create a new folder and name it Animations.
Inside this Animations folder,
I'm going to create a new file and for lack of a better word I
will call it app.animation.ts file.
Then inside this, I'm going to import
the various classes from angular animations that I did in the DishDetail component.
So, going to the DishDetail component,
you will recall that the first thing that I did
was I added this line into the DishDetail component.
I'm going to cut it out from the DishDetail component and
instead paste it into the app animations,
so that wherever this app animations is
included by importing it into our other components,
this will automatically come for the right there.
Now, within this app animations,
I'm going to create some factory functions that will export the various triggers.
The first factory function that I will create
this export function and call it visibility.
This visibility function will return the code
corresponding to the trigger that we have done in the DishDetail component.
So, going back to the DishDetail component,
I'm just going to cut out this entire code for the trigger from here and then go back to
app animation.ts file and then paste it into
place right there in the function here.
This now becomes a function that is available for import from my DishDetail component.
So, going back to DishDetail component.
Now, in place where I imported the trigger and other classes,
I'm going to now import the visibility
from animation's app, animation,
and so that function will now become available to me within my code here.
So, once I do that inside my animations,
I can just simply call that function so I can say
visibility and then the trigger code now becomes part of my component here.
Now, this I find is a better way of organizing the code for my animations.
Now, if I need to use the same trigger in another component,
I can simply follow this approach to include that into my other components as well.
Let's save the changes and then go and take
a quick look at our application in the browser.
Go into the browser, you see that when I go to the disk component,
the disk component is right there and then
it'll have the same animation behavior as before.
So, by refactoring the code,
I have managed to get the code better organized and
still work exactly the same as part one of this exercise.
If you had just one single animation used in one single place,
then the previous approach works just well but if you have
multiple and especially if you're reusing the code in many components,
then this refactored approach is a much better way of implementing the solution.
The next update that I'm going to do is to add animations on route changes.
So, when I go from one view to another view, so, for example,
from the home to the about or about to menu or menu to contact or vice versa,
then I want to be able to animate these changes within my application.
So, to do that,
I will introduce yet another function into the app animation.ts file.
So, going into the app animation.ts file,
I will export another function which I call as FlyInOut,
you will see why I use this name here.
Then this would return a function which is a trigger with the name FlyInOut.
So, inside was trigger,
I'm going to define the code for what this trigger is going to do.
So, in here, I will define a state here with the name star,
so it doesn't matter what state it is,
this is applicable to any state and then I will define
some styles here and the two styles that I
will define is opacity is one
and transform is translateX(0),
so which means that it is in its normal position in this case.
Now, when I define transitions,
I can also define transitions in this way.
So, if I say enter transition,
the enter transition is a shorthand for saying going from
void state to one of the existing state.
So, which means that the view is coming in into my application.
So enter, meaning that now when I route into
a particular view in my single page application,
that view will be entering into the view.
So, that's why I can apply the colon enter transition in that case.
Now similarly, there is another transition called colon
leave which I can apply when you transition out of
this view and then you're taking the view out from the router outlet of your application.
So, we're going to do both enter and the other one which is leave.
So, two functions that I'm going to define here,
transition enter and transition leave here.
So, for the enter,
what do I want to define?
For enter, let me define the function in here,
and similarly, for leave also,
I'm going to define the functions in here.
So, creating this scaffolding here.
Now, I can enter the information that I want within these transitions.
So, when this transition occurs,
I will start with a style of transform,
translateX minus 100 percent,
which means that the view is completely out of the view here.
So, you start there from minus 100 percent at this moment.
So, when you are entering,
you will start with that,
and then also at this point,
I will animate, and animate in 500.
So, when I specify 500 like this,
you can even do it this way.
Alternately, you can say, within quotes,
"500ms", and then you can even use ease-in or ease-out.
So, let me modify this into
500ms ease-in because this view is coming in.
So, we will ease-in the view.
So, for leave, I will apply the transition as animate,
and then I would say 500 milliseconds, again, ease-out.
So, this view is leaving.
So, we want to ease-out that view.
Then, in this case,
the style that I apply
is transform,
translateX 100 percent.
So, this view will completely disappear from the screen there.
TranslateX 100 percent.
Also, I will set the opacity to zero.
So, completely disappears from the screen.
So, this animation will add in a good new feature in here.
Now, for this one also,
I can add in, starting with an opacity of zero, if you prefer.
Let's add that in and see how it looks like.
So, this is the flyInOut trigger that I've defined here.
Now, you are obviously wondering,
how do I make use of this flyInOut and then apply
this to route transitions in my application?
So, to do that, we will go to, first,
starting with menu component.ts file.
I'm going to import
the flyInOut
from app animation.
Then, going to the component,
I am now going to introduce a new property called as host.
I'll tell you what goes into host in a short while.
Then, we'll also include the animations property,
which is an array here.
Then, inside here, I will use the flyInOut that we have just imported.
So, this animation trigger will be applied for this media component.
Now, within the host,
so this is how I ensure that this particular animation happens when route changes occur.
So, within this host here,
I supply this as saying,
@flyInOut and say true,
and this should be enclosed in quotes also,
@flyInOut, true, and then style,
display block.
So, this two should be applied inside the host property here.
Now, when we do this, my menu component will now start animating
when I route into the menu component,
and then also when I leave the menu component.
Now, I will apply the same thing to the remaining components of my Angular application.
So, what I will do is,
I'll just copy this,
and then we'll apply this to the about component.
So, I'll go to the about component.
Within the component decorator,
I have included the information here,
and you see the red squiggly line which reminds me that I need to import
flyInOut from animations, app animation.
So, the same approach, about component,
then within the contact component also, the same thing,
and then apply the host and animation properties to the component decorator,
and then what else do we have?
The home component. Let's go to the home component and repeat the same thing here.
I will add in the host and the animations property,
and then go ahead and import
flyInOut, from app animation.
Did we miss out any? Oh, we need to also update the dish detail component.
So, let me go to the dish detail component.
Since we already have the visibility there,
I'm just going to import the flyInOut.
Then, since we have already set up the remaining parts here,
I'm going to go in and paste that code,
and obviously, I have two animations here.
Let me cut the visibility out from here and then add
it into the other animation,
and then cut this out so that I have single animation property with
both flyInOut and visibility functions both being included and called there,
and then the host property.
Now, let's save the changes and then take a look at
the new animation that we just applied to our components.
Starting out with the home view.
So, we have the home view being rendered here.
Let me now quickly go to the About view,
and then you see that the About view just slides in while
the Home view slides out into the screen here.
Similarly, when I go to the menu,
you will see that the Menu view slides in while the About view slides out.
It's so fast that you don't notice it as such.
Similarly, for the Contact view,
you see the contact view sliding in.
So, this kind of animation can be added by using
this approach that we just illustrated for your Angular application.
We're not done yet. We'll do one more animation within our application.
To illustrate what I would like to do in the next animation,
let's take a quick watch on the menu component.
So, you see that when the menu component,
when the spinner is spinning and then gets replaced by the view,
the view suddenly appears on the screen,
and it is a little bit jarring to the eye.
You may not notice it.
You may be quite happy with that.
But we can add in a way of easing in
that view when the data is fetched from the server and the view is being rendered in.
So, when the dish's variable in my menu component.ts file becomes not nulled,
then the spinner will be hidden and then the the dish's view,
the menu is constructed and then laid out.
So, we want that to ease into the screen.
So, let's add in one more animation to effect that both in the menu component.
We'll also apply the same thing in the dish detail component.
We'll also use the same in the Home component also and the About component,
where we're fetching the data in order to show the list of leaders.
So, wherever you are fetching data from the server and then laying out the view,
when the view appears,
we want to ease the view in by using this new animation that I'm going to create next.
Going to the app animation.ts file,
I'm going to add in another function here,
and let me call it expand.
This function will expand the view that is being laid
out after the data is fetched from the server side.
So, this view, again,
I will return a trigger here.
I will name the trigger as expand,
and this trigger will create.
How do we define this trigger.
So, inside this trigger we're going to include a state with star in there.
So, it doesn't matter what state it is.
All the states will be rendered with the style as
opacity one transform translate x 0.
So, it is displayed right and center in my application.
That should be a brace there.
I was looking at it and said,
Why is it showing a red squiggly line.
So, when you're typing very fast you often make mistakes there.
So, instead of a square bracket,
that should be a brace there.
So, that is the state.
So, any state that it'll be completely visible and centered where it should be centered.
Now, let me trigger a transition.
Now, this transition will be triggered only
upon the enter when the view is laid out on the screen.
The exit part we're already doing it in the route animation, so we don't need that.
We only need the inter part for this view because
the view is rendered onto this screen there.
So, in the enter,
I'm going to define the transition appropriately.
So, in the transition what do I want to do?
I want to apply the same approach that I have used with the enter transition here.
So, I'm just going to copy this and then make some minor adjustments to the code there.
So, for the enter transition here also,
I want to apply the same thing.
I will say translate Insta from 100 percent.
I'm going to just use 50 percent and then I will do the translate Y.
So, which means that this view will drop down from the top 50 precent starting with
opacity zero and then I will ease it in a bit faster time,
200 milliseconds and will ease it into our application.
Now, so, you see the minor adjustment to the code here.
So, translate minus 50 percent and opacity zero and
it is eased in 200 milliseconds and then at that point,
I can apply this style as this same style.
I'll apply there. So, I will just copy that style and then apply that style there.
So, when it is eased in,
it will come in and be completely visible where it should be.
So, this is the expand function that I have defined here.
So, where do I want to make use of this function?
We will go first to menu component and within the menu component,
I will now also import that,
expand and then add it in into my animations and then how do I apply this expand?
So, going to that menu components template file.
In the template file,
I'm going to apply the expand to
the grid list where I am applying this.
So, let me copy that and then also we will go
to the home component and within the home component also,
I'm going to include the expand and then add the expand to the animation,
and then go to the home components template file and then I will apply
that expand to the dish components MD card,
to the promotion components MD card and also to the leader
components MD card here because all these
three will be fetched in the future from the server and then rendered.
So, the dish components data is already being fetched from the server.
Now, the same thing going to the DishDetail component.
I'm going to add in the expand to the imports and then add
an expand into the animation's going to the DishDetail component's view.
Along with a visibility,
I will also apply the expand to
the card div there and then to the comments div also here.
This is in the DishDetail component.
The contact component doesn't have anything that is being fetched from the server.
So, I'll just go over to the about component and in the about component also,
I will include the expand and also in the animations.
Going to the about components template file here this test
here which shows the leaders is being fetched from the server side.
So, I'm going to apply the expand over this.
Let's save the changes and then go and take
a look at our angular application in the browser.
Going to our angular application.
Now, when you go into the home template,
you can see that the cards when they were fetched,
they slided in to my view there.
Now, similarly when you go to the about component,
you see that once the data is fetched from the server,
then the rendering of the various leaders is being
slide in ever so slowly into position in this view here.
Similarly, going to the menu component,
we will see a same behavior here.
So, once the menu data is ready,
the menu component slides into place right there.
Same thing with the dish detail components.
So, let me go to the DishDetail component and you will see that
the view slides into place there but the
other animation which was
disappearing and reappearing that part still works just like before.
So, you see that we have introduced yet another animation into our Angular application.
Now, whether you like this or you want to do a more elaborate way of doing animations,
certainly, you can go crazy with
doing many different kinds of things with your animation.
Changing many different properties within the styles as in which way you like and so on.
But I felt that a few subtle animations here and there will
help enhance the user interface for my angular application.
So, I've added in two more new animations to my Angular application.
With this, we complete the second part of our animations exercise.
I hope that with these two parts exercise,
you have understood better about how to make use of
animations within your Angular application.
This is a good time for you to do a git commit with the message, animations part two.