- Coding Videos/
- Angular /
- Hierarchical Routing Animations in Angular
Hierarchical Routing Animations in Angular

Download Video link >
Hierarchical Routing Animations in Angular
Use the @angular/animations package to animate whenever a user transitions between two routes.
Also check out my blog post on this at:
https://fluin.io/blog/hierarchical-route-animations
source
View Comments source >
Transcript view all >
00:00 hi my name is Steven Lewin and I want to
00:03 share a little bit about animating route
00:04 changes within an angular application
00:07 animations with an angular have a lot of
00:09 different powers and different
00:10 capabilities they're really awesome at
00:13 the way they take a state that exists
00:15 within your application and then convert
00:17 that into visual information that helps
00:19 your users understand what's going on
00:20 within the application one of the really
00:23 cool things that recently became
00:24 available is the ability to animate
00:26 across different routes of my
00:28 application so that as a user is
00:29 navigating within my application I can
00:31 reflect those navigation changes by
00:33 animations that show the user leaving
00:36 one page and entering another so let's
00:38 go ahead and take a look at a existing
00:40 angular application that I've built so
00:42 this is fluent I hope this is a blog
00:45 application that I've built entirely in
00:47 angular so this was built using the CLI
00:49 it looks a lot like most angular
00:51 applications you've got different
00:54 components that are loaded using the
00:55 router so for example when I click on a
00:57 piece of content here such as this blog
00:59 post that content is going to load and
01:01 render by a different URL and a
01:03 different component so as I move back
01:05 and forth everything is loading
01:06 instantly but I think we can make this a
01:08 little bit better by adding animations
01:10 that reflect the hierarchy of the
01:12 application in order to indicate meaning
01:14 as I'm moving about the application so
01:17 let's dive into the code so in this
01:21 application we have a lot of normal
01:23 things that you're going to be using
01:24 themes we've got an app component we've
01:26 got a CSS file we've got a set of
01:28 different routes corresponding to that
01:30 app and so we're really going to follow
01:32 a a small three-step process first we're
01:35 gonna dive into the CSS to make sure
01:36 that we're able to show two routes
01:38 simultaneously in a way that we would
01:39 expect then we're going to go ahead and
01:41 save all of our route data so we're
01:43 going to add this additional layer of
01:45 information about the routes that exist
01:47 in our application giving us basically
01:49 the depth that every route exists at so
01:51 that we know how we want to animate that
01:53 and transition that and then lastly
01:55 we'll go ahead and create the animation
01:56 itself so let's get started so as we can
01:59 see here in my app components HTML file
02:02 in the template we can see we've got a
02:04 router outlet and I've already got a div
02:06 that's wrapping around this outer outlet
02:08 router outlet so what I'm going to do is
02:10 because I want to style all of the
02:12 components that this router outlet is
02:13 loading I'm going to actually need to
02:15 create a class on the parent we need to
02:17 do this because components that are
02:19 loaded into an application and you're
02:20 next to a router outlet don't actually
02:23 go inside of the router outlet as I said
02:25 they go next to it and so what I'm going
02:26 to do is I'm going to say class equals
02:28 route container and this will give us
02:31 the ability to style both this box as
02:34 well as all of the components that get
02:36 loaded into it as the transitions are
02:39 happening and as components are being
02:41 loaded so they're entering the scene as
02:43 well as when they're leaving the scene
02:44 so let's go ahead and use this style and
02:46 now look for our router outlet and right
02:49 next to that I'm going to say we're out
02:51 container we're going to do two things
02:53 first we're going to go ahead and
02:54 position this relative what this will
02:57 allow us to do is is allow us to take
03:02 all of the children elements and
03:04 position them absolute and we'll know
03:05 that they are going to be absolutely
03:07 positioned according to the relative
03:10 parent that they've got and then the
03:12 next thing I want to do is I want to
03:13 take all of these components that get
03:15 loaded into this so any sub child of
03:18 this of the routes container we're going
03:20 to go ahead and display that block so by
03:22 default and your components are
03:25 display:inline
03:26 but we want to change that over to
03:27 blocks so that when we give it a size
03:29 and width and shape and things like that
03:31 those stick differently than they would
03:33 if it was just in line so once we've got
03:36 these two styles now we can go ahead and
03:38 start adding the metadata to our routes
03:39 that allow us to understand where
03:41 they're on the hierarchy that'll then
03:42 later be use as part of these state
03:44 transitions this should look relatively
03:46 familiar you've got things like my home
03:48 component being done at the empty path
03:50 and we've got specific blog posts that I
03:52 can view so what I'm going to do is I'm
03:54 going to add to the existing data that's
03:55 already here so I set up a couple title
03:57 attributes that are just custom that I
03:59 came up with that allow you to
04:00 understand what the title the page
04:02 should be
04:03 and now we're going to go ahead and add
04:05 a couple T's we're going to add a depth
04:06 of one here we're going to add a
04:08 of to here now this will be used by the
04:11 application in order to understand the
04:13 state of the app based on the current
04:16 route that's been loaded into the router
04:17 outlet I'm going to start doing this
04:19 right inside of our template here and so
04:22 I'm going to use our property binding
04:23 syntax with this special angular
04:25 animation syntax so you're going to see
04:27 this at fine I'm going to say route
04:29 animation and so this is not a directive
04:33 or property of a div this is just going
04:35 to be the way that we invoke and name an
04:38 animation that we're gonna be triggering
04:39 and then the expression here is actually
04:41 the state that the animation is checking
04:43 for those transitions and so the state
04:46 that we want here from our expression is
04:48 going to be the depths of the current
04:49 page now there's no actual way to get
04:51 this and so what I'm going to do is
04:52 create a method called get depth and I'm
04:54 going to use the router outlet itself in
04:57 order to get that depth and in order to
04:59 use the router outlet itself I'm going
05:01 to create a local template variable
05:03 called my list and I'm going to give it
05:04 access to the outlet so now that we've
05:07 got this get def method and I'm passing
05:09 in the outlet let's go ahead and define
05:11 that give depth method so I'm going to
05:13 jump into the Associated app component
05:14 here and what I'm going to do is I'm
05:17 going to define you Matt it's called get
05:18 depth I'm just going to take this router
05:20 outlet that we're passing in and here
05:23 I'm going to go ahead and use that
05:24 router outlet look at its properties and
05:26 figure out what data attribute exists on
05:28 it and then return that so I'm going to
05:29 say return outlet dot activated route
05:32 data and then I'm going to say depth
05:35 which is the property that we came up
05:36 with it we names we added in the route
05:38 now I'm just going to go ahead and
05:39 return that so that our animation has a
05:41 set of states now that we've got those
05:45 states and if I save this this should
05:47 rerun there by the language services so
05:49 that we know that we've got that method
05:50 right great
05:51 now I'm actually to go ahead and define
05:53 the animation within my app component
05:55 and so the way we do this is we add an
05:57 animation to our component and in order
06:01 to do this successfully we're actually
06:03 going to need a few additional imports
06:06 here so I'm going to import all these
06:07 methods that I'm going to be using from
06:09 the animations library so this is going
06:11 to do things like trigger transition
06:14 Rufe query style and animates we're
06:18 going to get all these from at and your
06:19 flash animations alright so let's go
06:23 ahead and descend into the hierarchy
06:24 that is the configuration used in the
06:27 animations so the first thing that we're
06:29 going to be doing is we're going to be
06:30 triggering animations for a specific
06:33 component for a specific element on our
06:36 page that we're doing this animation on
06:38 and so we came up with the name of our
06:40 animation so I'm going to say trigger
06:41 based on route animation and then what
06:45 I'm going to do is I'm going to pass it
06:46 in as an array that's what this array is
06:48 going to contain is all of the
06:50 transitions that exist and that should
06:53 be activated upon changes to the state
06:55 of that router animation so we're going
06:57 to create a couple transitions here but
06:59 we'll just start with one and so what I
07:01 would say is when I move from depth one
07:03 so that's two so our state one to state
07:05 two I'm going to go ahead and do all the
07:08 things in this array and there's going
07:10 to be four things in this array we're
07:11 going to have a style two queries and
07:13 then we're going to have a group of
07:14 animation so the style on the two
07:16 queries basically get us set up for the
07:19 initial state of animation and then our
07:20 group will do two animations at the same
07:22 time so the first style element set is
07:25 I'm going to set the height of the
07:27 component so if you remember we're
07:30 animating on the div here the route
07:33 container and so when I say style height
07:35 is equal to exclamation point here what
07:38 that means is let's go ahead and at the
07:40 beginning of the animation set the
07:42 height of the element equal to the
07:43 height that it would be at the end of
07:45 the animation next what I'm going to go
07:47 ahead and do is I'm going to say query
07:49 and what I'm going to query for is the
07:51 enter element so this is one of the cool
07:53 new features of angular animations that
07:55 allows you to actually take not just the
07:57 element that you're animating but also
07:58 children and you can do additional
08:00 things with them and that's something we
08:01 rely on heavily here and what I'm going
08:03 to do for the enter element is I'm going
08:04 to apply a style what I'm going to do is
08:06 say at the beginning of the animation I
08:08 want to transform this and I'm going to
08:11 translate its exposition to 100% and so
08:14 what this will should do for me is it
08:16 will take instead of placing the route
08:19 directly on the page I'm actually going
08:21 to have it a little bit offset so that
08:22 it's going to animate into the page
08:25 so that we know that it's visually
08:27 entering the scene and it's giving me
08:29 the information now that I want the only
08:31 other thing that I need to do in my
08:32 second query here I'm going to take both
08:34 my enter and my leaves routes I'm going
08:37 to go ahead and apply an initial style
08:39 that allows us to position these things
08:41 exactly as we want to and so I'm going
08:42 to make it position:absolute and then
08:45 I'm going to make the top position zero
08:47 I'm going to make it the left position 0
08:49 right 0 just so that it takes up the
08:52 full page and everything cascades
08:53 appropriately and now we actually want
08:56 to do now that we set this data up for
08:58 the initial animation now we want to
09:01 actually define what the animation does
09:02 so I'm going to make it groups that I
09:04 can do two animations at the same time
09:05 the two things I'm going to give it are
09:07 I'm going to take the item that is
09:09 relieving the scene so this is the
09:11 component that was previously the one
09:13 that the user navigated to and I'm going
09:15 to say let's animate and I'm going to
09:18 say let's give it zero point three
09:20 seconds to animate and let's use a cubic
09:23 Bezier curve and I'll just use some
09:25 pre-configured numbers here 0.25 and one
09:29 so what this will do is we'll give it a
09:31 little bit more natural curve as it's
09:33 accelerating out of the scene
09:35 and then I'm going to apply this
09:37 animation here and I'm gonna ply a style
09:40 and that style is going to be a
09:42 transform where the item that is leaving
09:46 I want to take it where it started at
09:47 zero the default and I'm going to move
09:49 it to negative 100 so I'm going to move
09:51 it kind of off of the seam here so I'm
09:53 going to say translate X property and
09:55 I'm going negative 100 percent and then
09:58 we make sure we close all these things
10:00 appropriately and now we're going to
10:02 want to do a very similar thing for the
10:03 item that is entering right I'm going to
10:06 make it a bracket there
10:12 I'm let's just go ahead and copy pretty
10:15 much everything here but instead of the
10:20 item that is entering being translated
10:22 to negative 100 I'm going to translate
10:24 it from the hundred that it started at
10:25 now a minute slowly over 0.3 seconds
10:29 animates into the initial position so
10:32 we've got the animation or the trigger
10:34 that tells us which piece were actually
10:36 animating I've got the transition that
10:37 identifies the two states I'm moving
10:39 between I'm setting up the initial style
10:41 of the parent element I'm setting up the
10:43 initial position of the enter element
10:45 and I'm positioning everything
10:47 position:absolute so that I can take
10:48 complete control where they are on the
10:50 page and then I'm going to use slowly
10:52 animate over 0.3 seconds both to leave
10:55 item leaving and the enter item entering
10:57 the scene alright so now let's flip over
10:59 to our application and see if this
11:00 worked we have our blog here I'm going
11:04 to go ahead and click on one of the blog
11:05 posts from the home screen great we saw
11:08 the original piece of content slide out
11:12 and we saw the new piece of content
11:13 slide in what happens if we go back
11:15 nothing because we don't have a route
11:17 defined or a transition to find from
11:19 state 2 to state 1 so let's go ahead and
11:21 copy everything we just did here and
11:24 take our transition from 1 to 2 I now
11:28 say from 2 to 1 and then instead of
11:34 going off to 100 we're going to say
11:36 negative 100 and then here we're going
11:41 to just flip these numbers so this one's
11:43 going to go positive and the entering is
11:46 going to end up at 0 high so let's go
11:48 ahead and take a look and see if that
11:49 added the corresponding animation when
11:51 you now leave so when I click into a
11:56 piece of content the piece of content
11:58 floats in and then when I return using
12:00 either the back button or navigation
12:02 both are equivalent from the routing
12:03 perspective we see the piece of content
12:05 slide back in so we have this very nice
12:08 kind of back-and-forth that really
12:10 corresponds with the content to tell the
12:12 user where am I within the application
12:14 so now we've set up a hierarchy within
12:16 our application we've added some
12:17 animations that give the user this nice
12:19 visual reflection of what's going on
12:21 with the application
12:22 we're finished with our hierarchal
12:24 replication thanks so much we'll see you
12:27 the next one
Leave a Reply