Motion Design for the Web | FREE COURSE

In this course,
you're gonna learn how to create animations like these,
and these, and these. Whether you're just starting out or you're
looking to enhance your skills, this course will help you bring your website
to life by learning about motion design. You see, in the world of web design,
every pixel, every line of code comes to life through motion, and
it's not just about making things move. It's about telling a story,
guiding the users, and creating experiences that are both
intuitive and delightful. Now, together we'll dive into
the principles of motion design, we'll explore cutting-edge tools and
techniques, and we'll learn how to apply them in
a practical real-world scenarios.

But hey, for just meaning, my name is Adi,
and I've been around the web space for over a decade now doing both design and
development, and I still remember how static
websites used to be, how lifeless. Occasionally, you would find
a website made in Flash, which had some sort of movement in it and
you would be like, whoa. Here's an example I found
on a web design museum. Apparently, this is the website
of Lenny Kravitz from 2003. The animations might not
seem amazing right now, but they were pretty cool back then. Today it's a different story. You can create amazing
animations with just CSS, and if you add a bit of JavaScript, then you
can take things to a whole new level.

So I think this course is perfect for anyone who wants to step up
their game in this area, and I'm here to share all my insight and
all my knowledge on the subject so you can transform your designs
from good to jaw-dropping. We're gonna start by learning about
videos, how to add them to a web page, how to set them as backgrounds, and
also how to load them in custom players. We'll discover how CSS transitions
can be used to animate simple elements like buttons and menus, but
also entire galleries or custom apps. We'll create some cool loading animations. We'll play around with illustrations,
icons, and LottieFiles, while discovering the best
ways of adding motion with these. We'll create animated logos, and we'll turn a static piece of
text into a dynamic headline. We'll create interactive animations
that are triggered by our own action, either that's hovering on a button or
scrolling up and down the page. We'll also add depth and
dimension to our projects with Parallax, and we're gonna create this
beautiful animated hero.

Now, this course features 19 practical
exercises, and if you wanna follow along, you can download a starter kit by using
the links in the video description. So if you wanna code alongside
me while watching this course, grab the kit and let's get to work. Before we do that, I wanna quickly mention that this course
is brought to you by Envato Elements. Envato Elements is your gateway
to unlimited creativity. A single subscription grants you
access to a wealth of digital assets like stunning photos,
captivating videos, ​beautiful fonts, and
eye-catching graphics. Supercharge your search with the power
of AI to find assets tailored to your project. For more information, check out
the links in the video description. All right, so
let's jump straight into it and learn the basics of motion design for
the web. All right, let's begin by talking
about motion design in general. Motion design is a creative
discipline that uses animation and visual effects to bring
static elements to life. It involves manipulating visual
elements like text illustrations and images to create engaging and
dynamic motion graphics.

This is used in many different
places such as film titles, user interfaces,
advertisements, and videos. Motion design plays a vital role in
visual storytelling and communication. For example, with motion graphics, you can create a really cool app
promo video just like this one, or a really nicely animated
video title like this one. And nowadays, with the abundance of video
templates available on Envato Elements, for example, it's really easy to add that
much-needed pizzazz to your visuals. But let's be honest, you're here because
you want to spice up your web game, right? We're talking about taking those plain
old two-dimensional websites and web apps and kitting them with
some serious movement and depth. So it's time to unleash
the power of the trinity. So it's time to unleash
the power of the trinity, and the trinity consists of,
surprise, three things, videos, transitions, and animations. And together, they're like
the Avengers of the web design world, ready to swoop in and
save your digital creations from boredom. Let's start with videos. These are like the Hulk of the group,
very efficient in delivering information
in a truly smashing way.

Well, we all know the saying,
a picture is worth 1,000 words, right? Meaning, a picture, an image can describe something a lot more
efficiently than written or spoken words. Well, based on that, we can say that
a video is worth 1,000 pictures. That's because videos have this magical
ability of blending visuals, audio, motion, and storytelling,
leaving individual images or written descriptions
feeling a bit inadequate. Now, prepare yourself for
a peek into Apple's world of video mastery as they showcase
their newest creation, the Vision Pro mixed reality headset.

They've got the perfect combo here,
written text for information and background videos to say, hey, this is
what you'll experience when using our new headset, and let me tell you, some
of these videos are out of this world. There's this one, for instance, that takes you on an intergalactic
joyride while watching a movie. It's like entering a whole new reality,
a whole new dimension. And watching that video will evoke
emotions in a way that's not really possible just by reading a piece of text,
no matter how detailed that text is. But videos are not the only
way to add motion to the web. Our dynamic trio would not be complete
without animations and transitions. Now, these are like the Hawkeye and
Black Widow of the group, sleek and precise in their roles,
but just like these two, transitions and
animations are similar, yet different. Transitions smoothly guide us
from one state to the other, adding an extra layer of finesse.

Take for example, the color and
position change on these links. See how smoothly the properties change
between the default and mouse over states? This is way, way,
better than a sudden change, and that's because it mimics real life. If I have my hand up and
I move it from side to side like this, you can clearly see the transition
between the two positions, right? In real life you don't perceive
movement like this, okay? It's unnatural. Now, of course you don't always
need to implement transitions, it really depends on
the style you're going for.

In this example, all color changes
happen instantly, which makes the UI feel very snappy, and there's
absolutely nothing wrong with that, in the end,
it's about personal preference. Now, animations, while similar
to transitions in the sense that they change from one state to another,
are also very different, and we'll explore the differences between
these two later in the course. But for now, just know this,
animations allow us to create much more complex movement
than transitions. Now, if we're gonna go back
to the Avengers analogy, I would say transitions are like Hawkeye,
capable, very straightforward.

But in the end kinda
limited in his skillset, I mean, the guy shoots arrows, right? Animations on the other hand,
would be represented by Black Widow, while still human,
she can do a whole lot more. She can shoot guns, ride bikes,
go Jackie Chan on you, she can zap you with stuff on her wrist,
and so on. Now, let's take a look
at some animations and we'll start with this one from Dogstudio, this is one of my favorite websites
because it's about dogs, except it isn't. But here you'll see this amazing
animation of the dog as we scroll up and down the page. This is definitely one of the more unique
ways of adding motion to a website, but I think it's mesmerizing
to anyone who sees it. But not all animations are flashy.

In his portfolio website,
Dennis uses some very tasteful animations in the hero area and
also when we hover on certain elements, like this button, or
these portfolio items. So quite a big difference between
animations and transitions, but they both have their purpose, and along with
videos they help us add motion to the Web. Now, why should we care
about adding motion? I mean, it looks cool, but
is it actually helpful? The answer is definitely yes. You see,
motion enhances the user experience. So for example, if I'm browsing a website,
I'm gonna have a good experience if I find the information
that I'm looking for quickly. But the experience is gonna be
even better If the information is delivered in a dynamic and
engaging way, and this is exactly what videos,
transitions, and animations do. With that said, motion has two main
purposes, informative and aesthetic.

It's informative because you can
use motion to show users how to interact with the UI or
even show them what actions are available. For example,
Dennis uses animated buttons, or rather they become animated on hover. This is telling users that
the element is interactive, that clicking it will do something, right? The animation can also be very subtle. In this example, we can see a short
animated element under the scroll text. This is telling us in
a very subtle way that, hey, you can scroll down
to see more content. Here's another great example
of an informative animation. The Dogstudio website plays music by
default, and the way we turn it on or off is by clicking this tiny
button on the bottom right corner. And to make that very obvious for
the users, the button has the simple ripple
animation that draws your attention, and so you immediately know, okay,
so this is an interactive element. Now, being informative,
motion also has the ability of focusing a user's attention
to something important. So let's say we have some product
features that we wanna showcase. To get the user to focus on those,
we can animate images like we see here, and this works great because
when I get to this section, my eyes are immediately drawn to the area.

So those are just a few examples
of how motion can be informative. Now, the second purpose is aesthetic,
that's for adding personality or
character to your web project. And a good example for
this would be a loading screen. Dogstudio does a great job with
this because it shows this loading animation of a dog running. This is great because it's
in tune with the brand and the rest of the website, and
it helps build that unique character. We can also see a great example of
aesthetic animation on Dennis' website. Notice how these two rows of
images shift position on scroll, this is a really nice effect. It doesn't serve an informative purpose,
but aesthetically it looks fantastic, it adds personality and
style to an otherwise standard layout. So in this lesson, we learned that
motion design is a discipline that uses animation and visual effects
to bring static elements to life. You can use motion design in a bunch
of places, like film titles, user interfaces,
advertisements, and videos.

When it comes to the web,
we can add motion by using videos, transitions, and animations. Videos can deliver information
in a very dynamic and effective way because they're a blend of
visuals, audio, motion, and storytelling. Transitions are effects
that gradually change the properties of an element
from one state to another and they're best used for
simple from-to movements. Animations are similar to transitions, but they allow for more complex and
continuous motion. And finally, we learned that
motion has two main purposes, informative and aesthetic. Motion is informative because it can show
users how to interact with the UI and what actions are available. It can even focus the user's
attention to something important.

Motion is aesthetic because it can
be used to add personality and style to a standard layout. But of course,
the most important key takeaway from this lesson is that Hawkeye is
not as cool as Black Widow. And with that, it's time to move
on to some practical stuff. So in the next lesson, we're gonna
learn how to add videos to a web page. Okay, so earlier, I said something about
videos being worth a thousand pictures. And that videos use visuals,
audio, motion, and storytelling to deliver
information very effectively. They're essentially the superheroes
of content delivery. Now, the beneficial effects of adding
videos to your website are well documented. For example, this article from
Insivia gives us some great stats, like explainer videos are capable
of increasing product sales by 20%. Cool, and since this is written on
the Internet, it must be true, right? Regardless, we all know that
videos are the future of content.

So let's see how other
websites are using video and then learn how to add
videos to our web pages. And by the way, if you want to
follow along with this course, you can download all the exercises. You'll find a starter kit that's
linked in the video description, along with any other resource
I used in this course. And by the way, if you're enjoying
this course so far, don't forget to hit that Subscribe button and turn on
notifications for more content like this. Okay, let's see some real world examples. Let's start on Apple's website, and
we're looking at the presentation page for their newest iMac. And as we scroll down,
we can see our really nice presentation video for their iMac, showcasing the seven colors it comes in.

And as we scroll even further down,
we can see another video. This is a type of
a slideshow where we can see the various use cases for this device. And it goes on further as we scroll down. Now we can see another
video being played here. And as we scroll down even further, we can
see another video that's showcasing yet another feature of the product, which is
the six speaker sound system in this case. And the examples can go on and on. So showcasing the characteristics or
the features of a certain product is a great reason for
using a video. Moving on to the iOS 17 page,
again, on the Apple website. And here,
we're not dealing with a physical product, but instead a digital one. And here we can also see videos being used
to display how that digital product works.

We can always click Replay, and
we can see that now the video was being actually displayed
inside this iPhone mock-up, which really adds to the whole
realism of this presentation here. And again, the examples can go on and on. We have some more videos here, again, showcasing other features
of the operating system. Moving on, we have the Timely website, and Timely is basically
time-tracking software. And again, they're using video right here,
and it's exactly in the hero section, but they're using it to show their app and
how it looks like, what it can do.

And this is using a really nice animation. Next, let's move on to
the InVision apps page. And if we go to Freehand and
we scroll down, we can again see a presentation
of their software. And they show you exactly
what you can do with it. And it's presented really nicely. As you can see, the videos can
have different kind of containers. I showed you one type of container here
where it's placed in this iPhone mock-up. On Timely's website, it looks a little
bit different, it has a rounded border. Here it's a little bit more square and
it has a shadow. So you can really customize the way
the video container looks like. And finally we go to Shakuro, and they are using video as background for
their hero area. Again, showing,
stuff related to their business, like maybe their portfolio,
items, stuff they worked on.

And maybe even, like we see here,
pictures of people working, I'm assuming, from their offices. Now, let's focus on the technical side and learn how to add videos
to our own webpages. So enter, Practical Exercise #1. So here we have a simple page,
I just have some feature, title, description, and some sub-features. And let's say we wanna add a video
right here on the right side. So if you open up Exercise 1, you'll see that we have a div
with an id of media, right? So let's say we wanna add a video there. Well, the easiest way is, let's say,
we have our video hosted on YouTube, okay? So I'm gonna grab this video
from the Envato Tuts+ channel.

And the way you embed it,
basically, or the way you load it onto your webpage, is you go to Share,
you click Embed and you copy this embed code, okay,
you can also hit this button. So you copy that, you come in here,
you paste it in, save. And now we have video that's running,
that's loaded directly there. And because it's a YouTube video, we have all the play options that you
would normally expect on YouTube. And that's the easiest way you
can add a video to your web page. But what if you have a custom video? What if you have one that's
hosted on your site? So, for example, in my source files here, I have a video called video1.mp4,
which looks something like this. By the way, you may not see this in
the starter kit that you're downloading because this is taken from Envato Elements
and I cannot redistribute it, it's a copyright thing.

So in the starter kit you'll most likely
find some kind of replacement video. But for the purposes of this demo, that will work just as well. Me personally, I'm gonna use some assets
from Envato Elements in this course and in the other demos as well. But if you can't find
those in your starter kit, you would have to download them yourself
or just find a replacement on your own. Okay, so let's assume that I have
this video1, and I want to load it. Right here, okay? So let's comment this. We can use the video element. So we're gonna say video src. We're gonna go to videos,
video-1, and we can hit Save. So now, if we refresh, yeah,
we can see that video being loaded on the right side of my content,
but it's like super big. How do we make this smaller? Super simple to do that.

We have some attributes we can use on
the video element such as width, height. So we can say width, let's do 640 pixels. We can do a height of like 320 pixels. And now the video is displayed
properly at a much better dimension. But it doesn't play or actually it
doesn't show us any kind of controls. Well, the thing with the video
element is we can right-click it on any browser and we can have
the option to show all controls so we can play, we can pause we can scrub. We can make it fullscreen and
we have some additional options here.

And we can also choose to loop it. Which means, when it gets to the end,
it's gonna go back to the beginning, right, iIt's just gonna keep
playing over and over again. Now, what if I don't want to have to
right-click to display those controls. Very simple,
we have another attribute called controls. And that's gonna display the controls
I showed you earlier by default. And if your video has audio,
it has sound, and you don't want that playing,
you can also use the muted attribute. And that's gonna play,
as you can see here, it has crossed speaker icon,
so it's gonna play muted. Something else you can do
is you can add a poster. So by default, if the video is loaded and
it's not playing, it's gonna show probably like a still
image from the first few frames or even the first frame of the video.

But if you wanna add,
like a separate image, a standalone image, you can do that by using
the poster attribute. So you can see here poster equals and
you would give it a path to an image. In my case I have an image
called video poster.jpeg. So now that image is displayed instead
of whatever it was before, really cool. Now, in case the browser you're using
doesn't support the video element or the video tag, you can actually put
some text in here, something like this. Your browser doesn't
support HTML5 video type. So, if the browser doesn't support it,
it's not gonna show the video, instead, it's gonna show
this piece of text. This is just a fallback really,
but nowadays, all major browsers support video so
you shouldn't have this issue.

Now, how exactly do you customize
the way this video container looks like? Well, the answer is with CSS. So in here, I'm using by the way for
all of these demos I'm using internal CSS,
it's just a little bit easier. So to style that,
you would say the following. First of all, we have a div id media,
which contains all of this. So you would say media video,
and you can do a lot of things. You can add, I don't know,
a border-radius, for example, let's say 1rem. And that's gonna round it off,
I'm not sure if you can see it here. But you can also add a border to it,
right? So let's say, border:,
if I can type border, 1px solid, and
let's give it a color like 5521db, right, and
that adds Nice purple border around it. What about this poster image? It doesn't fill up the entire
video container because of the of the aspect ratio of the image. So to get around that you could say, object fit, cover, save and there you go.

Now the image fills up
the entire video container. And by the way,
this also works for the iframe. So if you don't have a video here,
and instead you wanna use the iframe instead,
you can do that as well just add, The CSS there as well, the selector. And now the iframe or
the stuff that you got from YouTube as an embed has the rounded corner and
the colored border. On top of that,
if you want to customize this further, you can use a library called Video.js. So you basically go to videojs.com,
and you can see some of the examples of the players or
the player themes that you can use and you'll find all the instructions
on how to customize things.

In here, we're not gonna do
that right now but videojs.com. And you can make your video
player look any way you want. Now, let's take a look at another exercise
where we have a simple hero area with a header, some text, a little icon here,
but there's something missing, right? How about we add a video as
a background to this entire section? How exactly would we do that? Because we can't just go into CSS,
go into the hero, and say, okay, background image, and we'll just load
the video, it doesn't work like that.

So we kind of have to work
around that limitation. So here's what we do. Let's take a look at the structure first. We have the section with an id of hero. This is basically the container for
everything we have her on the top. Then we'll have the header, the h1,
and the image that's one here. Now to add a video as a background,
we will create a video elements and then we're gonna absolutely position that
and stretch it to fill the entire hero. And we're gonna position it
behind all the other elements. Here's how we do that. First of all,
let's create the video elements. So in here, and by the way, you can create
this anywhere you want inside the hero, but I'm gonna put it right
here as the first element. So we're gonna say video. So let's go to videos and
I'm gonna load this mp4 video2.mp4. And here I'm gonna set
two extra attributes and we're gonna set autoplay and also muted.

And let's actually do one more,
we'll set the loop so that it just keeps on repeating itself. And as you can see the video is now
displayed although it's the wrong size and it's positioned incorrectly, but
we can easily fix that from CSS. So, let's go and target the video element. We're gonna set position to absolute. And by the way, for this to work,
We first need to set a position relative on the hero element,
which I've done like right here, okay? So, just keep that in mind. So, we're gonna say video
position absolute, and we're gonna set top 0, left 0, okay? So, now it starts from
the top left corner and let's set a width 100%, height 100%, okay? And now for the magical stuff,
object-fit cover and that's gonna basically fill up
the entire available space.

It's gonna clip the video on the top and
bottom and now all we got to do is move
it behind everything else. So, we'll just set a z-index of 2,
sorry,- 2, and that's gonna put it
behind everything else. Now, I already made some
preparations beforehand and those preparations look like this. So, on the hero,
I have a before pseudo element defined that has a background
of 80% of this color, right? And it also has a z-index of- 1,
z-index- 1 basically puts it under all the content inside the hero
because that's by default z-index 0. So I'm adding this color overlay. So what I did with the video is I
did basically the same thing, but I set a z-index of -2. So now the video goes behind
that color overlay and the rest of the content goes on top. All right, so now we know how
to load videos on a webpage. So we're done, right? But not so fast, you see performance is all also
something that we need to consider.

Let's take a look at the file size
of the first video we loaded. If we go to VS Code here and we open
up the first video, we can see that it has a whopping file size of 59.80
megabytes, so about 60 megabytes. That's massive for a 10 second video. Now, this loaded just fine for
me because I'm working locally, but imagine this video
was hosted somewhere and I had to download it with a slow
mobile connection, right? It would take forever. And personally,
I'm not gonna wait for that. I'm not gonna wait a minute,
two minutes to download a video, well, unless it's a funny cat video. But anyway, most people will not wait for it to download, so
performance really is critical. Now, what can we do in this situation? What can we do to lower that file size? Well, first of all,
we can use a different file format, a different video format, okay? And so far in this course,
we used the MP4 format, which is like the gold standard for video.

Most of the time, this uses the H.264
codec Which offers great quality and is supported by all media players and
browsers, even older ones. Now, the MP4 format is like the Batman, reliable and versatile but
a bit slower at times, and just like Batman,
MP4 files are a bit on the larger side. But MP4 is not the only format
supported by modern browsers, WebM is also a really good. It's an open source format developed
by Google, specifically for web video.

And the WebM format is like The Flash. Super fast, very lightweight,
but not as reliable. So, when comparing WebM to MP4,
the WebM files tend to have smaller sizes at
similar quality levels but they're not as reliable in
terms of browser support, because they're not supported
by some older browsers, okay? Now, let's say you have a bunch of
MP4 files that you want to slim down, you want to convert them to WebM to reduce
their file size, how do you do that? Well, let me show you. You can use an app called HandBrake, and
HandBrake looks something like this. You can get it by going to handbrake.fr,
you can download it here for Windows and for other platforms,
it's free, it's awesome, go and get it. So, let's work on this
second exercise here. Let's say I want to convert
this background video from an MP4 to a WebM, right? And our background video is video2.mp4. As you can see,
I already converted it here. But let's take a look
at a file size of this. So it's 5.26 megabytes and the way
we convert it is we open the source, we select the video, and
here we select the format, WebM.

We can select the preset here for
the resolution and we can save this in the same folder and
you click starting code, okay, and that's gonna do its thing. And now we are done. So now we have this WebM file here, of course VS Code cannot load it properly. But now if we look at the file size,
it's about half of what we had here, 5.26 megabytes, 2.54 megabytes. So now, with the video converted,
how about we add it to our page? In here, I actually wanna show you
a different way of adding videos, and that's by skipping
the SRC attribute here. And instead,
using this source and then src, and we're gonna go to videos,
first let's load the MP4, and I'm gonna set a type of video, /mp4.

And then I'm gonna duplicate it, and I'm gonna select the WebM version and
choose webm right here. So now, if we take a look and actually,
let me comment this put the MP4 source. Now the WebM video is loaded and
it looks just fine but it's a lower file size which is great for
us. The reason I'm using this approach
is that if a browser cannot or doesn't support WebM,
it's gonna use MP4 as a fallback. But by default browsers
will generally prefer WebM. Also, when working with video,
please pay attention to the resolution of that video because that plays a huge
part when it comes to the file size. A higher resolution video will of course
have a bigger file size than a lower resolution video, but in most cases,
you will not need a 4K video. Like for instance, in the example that
I showed you here, with the background video you don't need a 4K video there
are 1080P will do just fine, right? So, also think about the resolution when using videos onto your webpage because.

You'll most likely be in a situation
where you're gonna bog down your page. You're gonna make it load super
slowly just because you're using a high resolution video
when you don't have to, okay? So keep that in mind. So in this lesson, we learned that videos
are superheroes of content delivery. Loading videos from external sources
is a breeze with simple embed codes, making it easy to add them to webpages. If you're self-hosting the videos, you can use the video HTML element
to add them anywhere on the page.

You can fine-tune the video
functionality by using attributes like, autoplay, muted, loop, and controls. Controlling the appearance of the video
player can be easily done by using frameworks like VideoJs. You need to always
optimize video format and size to ensure faster page loading times. in terms of video format, MP4 is a reliable option that is supported
by all browsers and media players. WebM is also viable and
while it's not as widely supported as MP4, it offers smaller file sizes
without sacrificing quality. To compress a video or
convert it to a different format, you can use the free app Handbrake.

All right, that's a wrap for videos, and we've officially tackled the first
member of our dynamic trio. Now, it's time to shift gears and dive
into the amazing world of CSS transitions. CSS transitions are like
the smooth operator at a party, guiding elements through changes and making your website look sleek and
sophisticated. CSS transitions are a functionality
provided by CSS that enable smooth and gradual changes in element properties
over a specified duration. They provide a way to add animation and visual effects to elements without using
JavaScript or other complex coding. Now, do not confuse CSS
transitions with CSS animations. We've talked about this before. Remember the Hawkeye dude. So CSS transitions are pretty limited
in terms of what they can do, because they basically animate
a property from point A to point B. There's nothing in between. It's like shooting an arrow if you want. The arrow goes from the bow to its target. It doesn't do anything in between, it
doesn't stop for coffee mid-flight, okay? The same goes for transitions.

There's nothing in between,
they go from point A to point B. So let me show you how you
can create some in CSS. Let's work on
Practical Exercise exercise #3, where we have a simple header
that has a logo and navigation. The navigation has a button that's
it kinda looks like a button, but it doesn't behave like a button. So we're all used to a button
being an interactive element. Meaning when we get the mouse
cursor over it, it does something. It changes color, or it gets bigger,
or something along those lines. But this doesn't do anything. So, let's fix that. Let's go to our CSS in exercise 3,
and let's say the following. Sorry, btn, so
we have a class defined here, unhover. We can do the following, background-color. We're gonna change it to 151618 and
we're gonna change the color to white.

So now, if we hover on it,
it changes color. Pretty cool, right? How about we add a transition to that? And the way we add a transition is
we target the original element. So btn, and we say transition-property. What are we changing? We're changing the background color,
right? How long should this transition be? Let's say 400 milliseconds. So we can say transition-duration, we can do 400ms or 0.4 or
0.4 seconds, okay? So now, The same thing happens,
but it's now very smooth.

It's transitioned, right? It's animated from the purple
color to the dark color. It's not as abrupt as before. Now, we can do a lot more with this,
we can specify a timing function. So we can say transition timing function. Let's do an ease-in-out, and that's gonna basically change
the curve of the animation. So it looks just a little bit different. It's actually kinda hard to
see on a color change, but as the course progresses, we'll talk
more and more about timing functions. And we can also give it
a delay if we want to. So we're gonna say transition-delay,
let's say 2s.

And that's gonna basically start to
transition after two seconds, okay? So I hover one, two, and
then it does the transition. And it does the same when I hover out. One, two, and
it does the transition in reverse. Now, these properties can be
condensed in a shorthand notation. So instead of doing all of this, we can simply say transition and
we specify the property. In our case, background-color,
the duration, the timing function, and if we need to, the delay,
2s, like that, okay? And you'll see that it now
behaves exactly the same. And let me just remove that delay,
we don't need it for this exercise. So instead of using these four
properties or these three properties, we can use just one called transition and
we place the values in here.

Now, if we want,
we can transition multiple properties. So let's assume that instead of this,
instead of this, we're gonna change
the background color to white. I'm gonna change the color to
that dark one we had before. And I'm gonna change the border
color to the same value, okay? So now it looks like this. But notice that the background
is transitioned, but not the other properties. So we get a really weird
effect where the border and the text color is changed instantly
while the background is transitioned. So to fix that, we can add a comma here. And then, again, color 0.4 seconds,
ease-in-out, or whatever easing we want. We can specify different easings for
different properties. And we also want to
transition the border color. We can put a different duration
if we want here, although, it's not necessary in this case. 0.4s ease-in-out, okay? So now, everything transitions at the same
time and we get a really nice effect. If we want, we can also specify
a transition, all properties, 0.4s ease-in-out, and that's We
don't have to worry about anything, any property that can be transitioned
on this element will be transitioned.

And even though this is easier and
more convenient, I don't recommend you do this because it's
not very good in terms of performance. Now you're gonna give
the browser a lot of tasks and you're gonna be animating some properties
that don't really need to be animated. Now, before we wrap up,
let me anticipate one of your questions. And that is, Adi, why does
the transition need to be applied on the element itself and
not the pseudo class, for example? Well, two reasons for that. When you're attaching the transition
to the element itself, okay, you have more control
over how the animation behaves. And reason two is that when
you're applying it here, whenever the properties change,
the transition will be applied, regardless of what triggered the change,
right? So it's either hover or press or focus.

If you were to specify it on
the pseudo class, like we have here, you need to do it for all of them, for
the hover, the press, whatever it is. It's much easier to specify it
here on the element selector. In this lesson, we learned that
CSS transitions are a CSS feature that allows for smooth and
gradual changes in element properties. CSS transitions are different
than CSS animations, mainly because they go from point A to
point B, with nothing in between. Applying transitions in CSS is done
by using the transition-property, transition-duration,
transition-timing-function, and transition-delay properties.

You can also use the shorthand
notation of transition. You can transition multiple elements
at the same time by separating them with commas. The browser can be instructed to
transition all available properties at the same time by using the value all. However, this should be avoided due
to possible performance issues. All right, so in this lesson, I showed
you the basics of working with CSS transitions, but I haven't really
focused on creating motion with them. So how about we do that next? In this lesson, we'll dive into
the realm of CSS transitions and see how they can transform static
elements into dynamic visual experiences.

And before we do that ourselves, I think it's only appropriate to see
how others are using transitions. And we start with the portfolio
website of Simon. As you can see,
when we hover on these cards here, have a really nice effect,
we get a shadow added behind the card. And also the background image,
if this is a background image indeed, it kind of shrinks a little bit,
creating this very smooth transition. And of course,
the same thing happens on the others. And I think the card itself
actually scales up just a tiny bit.

So yeah, a really simple transition, but one that adds a lot of style
to a relatively simple layout. Let's move on to Marie Weber's website. And here, we can see that when
we hover on these titles, there are a number of things going on. First of all, the text or
the small badge on the top-right of each title changes to
reveal a bigger text. And it's doing so with a very simple,
a very smooth transition. And also, the images on the right
side reduce their opacity, they scale up or down, and
it's another great example of how to use transitions
to add motion to a website. Moving on to Miti Navi. If we scroll all the way down to
the footer, we can see these links. And when we hover on each link,
we can see a nice transition. The original text kind of scrolls up or
slides up and then another text slides
in from the bottom.

Very simple effect, very cool, and again, one that adds just a little
bit of motion to this website. And finally, we go to Vool Studio,
which has a lot of transitions here. And we can see the first one,
if we scroll up and down, we can see the sticky header
just popping down, yeah? So it changes position,
it goes from the top to the bottom, and it also transitions
the opacity of that element. Again, when we hover on these cards,
they kind of scale up, they change their background, and
all of these properties are transitioned. And then when we scroll down from the top,
actually, you can see that the entire
page background changes from this dark blue to this white,
and that's also a transition. Not to mention,
the buttons also transition, right? And they have this cool
mouse cursor follow effect, which we'll actually replicate
in one of our future lessons.

But inside the button, yeah,
you can also see a transition. It's kind of a wipe effect for
the background color of the button. So that's how other websites
incorporate transitions to add motion. Now these transitions are not
used just for buttons and links, they've got a much
broader role to play. And to show you that,
I've created a couple of demos. So let's start with
practical exercise number 4. Let's look at a simple drop-down menu,
like this one here. So when we hover on the Services link,
we get a submenu. And then each submenu link has
a different state on hover. We change the background, we change a little bit of the padding
here, and we show this arrow. But as you can see,
everything happens very suddenly. There is no transition, there is no
animation, it's just there or it isn't. So let's go ahead and fix that. Let's start by, first of all, adding
a transition to the color of these links, because they go from this lighter gray,
or sorry, from this darker gray to a lighter gray.

So, in here, in exercise number 4,
let's do the following. We're gonna target nav ul a, because that's currently our structure,
we go nav, ul, and then a. All we gotta do here is say
transition-property:color. And then, let me just copy this,
right at the end of our style sheet, we're gonna do the following. Transition-duration, and
here, I've actually defined, A variable called
def-transition-duration and transition-timing-function, ease-in-out. Now the reason I'm doing this, the reason
I'm separating the properties like so is that I want to apply the same
transition duration and timing function to multiple elements.

So to keep the code a little bit
cleaner and to not repeat myself, I'm gonna add the rest of the elements
here, meaning the rest of the elements that share the same
duration and timing function. And then for each individual element, I'm gonna just specify which
property to transition, okay? So by doing this,
we now have a simple transition for the link colors, what about this arrow? This also needs to be transitioned. So if we look in the CSS code, or
actually, let me show you, in the HTML, each list item that has a sub menu
receives a class named has-submenu.

And in our CSS,
we are actually using an after pseudo-element to load up that icon, and we're also setting an opacity of 0.6. Except on hover, right here, we are setting that opacity on
the after pseudo-element to 1. So that's the thing that
we have to transition. So back here in our CSS,
we're just gonna say, has-submenu after, we're gonna transition
the property of opacity.

And, of course, we want the same
duration and timing function, so we're gonna add that to the list. So now, that link changes as a whole. >> Great, now let's see about
the actual submenu, right? If we look in the code,
the submenu itself is this ul, which we've styled previously
in CSS with has-submenu ul. You can see it has a position,
absolute, top, left, background-color, and so on and so forth.

And, to show it, on hover, initially, we're setting a display to none. And then, on hover, we're setting
its display property to block. So, let's go ahead and
add a transition to that. But in order to make it
work the way we want it, we're gonna have to change its
properties just a little bit. So let's start with this. has-submenu ul, by default,
we're gonna change its display to block, so
it's always visible, yeah? We're gonna change its opacity to 0,
so now it's hidden, but also notice that
even though it's hidden, if I hover my mouse where it is,
we still get a cursor change, because we can still
interact with those links.

So to fix that, let's change
the visibility to hidden, okay? So I can now no longer interact
with that invisible menu. Now to animate it, let's use a transform. Let's move it initially to the left by,
let's say, 1rem. And when it's opened, we're gonna move
it back into its original position. So we're gonna do the following. We'll say transform: translateX(-1rem),
okay? And then let's specify which
properties we need to transition, so we're changing the opacity,
we're changing the visibility, and we're changing or
we're working with transform, okay? So now, to show it,
we're gonna say, has-submenu, hover ul, so when we hover on the submenu,
we target the ul. And we're gonna change its opacity to 1,
we're gonna change its visibility to visible, and
we're gonna reset the transform. So transform: translateX(0). Let's see how that's going, so hover, And it's working, but we don't get
the transition just yet, why is that? Because all we specified here
was the transition property, we don't have a duration,
we don't have an easing.

So let's go ahead and add it right here,
we're gonna say, has-submenu ul. So now this receives the duration and
the timing function. So now, aha, different story, right? Now that's a nice animation,
very smooth, very simple. So the animation basically
goes from a translateX(-1rem), which basically means that we're
moving the element 1rem to the left. And then on hover,
when it should be visible, we move it back into
its original position, so the effect is that it
slides in from the left. And also,
we are transitioning the opacity of it. So it goes from opacity 0 to opacity 1
when we hover on the parent link, simple.

Now, let's move on to
the links inside the submenu. So what exactly is changing
here from default to hover? First of all,
the color of the link, right? But we already have that covered, because
we've done it here in the top level. Then it changes the background-color,
right? It goes from nothing, from transparent,
to this lighter gray. And then it also changes the padding. Notice that the hovered link has
a slightly bigger left padding than the ones below. And of course, we have this icon, which we'll get to in just a little bit.

But let's see about the other properties. We're gonna do this, has-submenu, we're gonna target ul a, right,
so the anchor tags inside ul. And all you're gonna do here is say,
transition-property, we're gonna change
the background-color and the padding. Of course, we also need to add this
right here to get the duration and timing function. So now, Look at that. The background color has transitioned and the padding has also transitioned,
it's a much smoother effect. Now let's fix this icon.

How is this applied? Because we just have list items and
anchor tags, we don't have an actual
icon being displayed here. But if we look at the CSS, right here,
has-submenu ul a, we're using, again, an after pseudo-element and
we're loading this svg icon. And the way we're displaying
it is by default, opacity is set to 0 and then here,
we're setting its opacity to 1. So, in our CSS,
we need to do the following. We need to say, has-submenu, ul a::after. So we're basically targeting that icon,
and we're gonna say
transition-property: opacity. And then of course,
we're gonna get this copy it, paste it in here to give it
the duration and timing function. And that should be it. Now, the change in opacity for
this purple icon is also animated. And with just a few lines of code, you saw how we turned this
sub-menu from just appearing or disappearing into an element that adds
some nice motion to our header area.

Let's move on with our next practical
exercise, number five this time. So, we have an image gallery
that currently looks like this, so it's basically a list of destinations. And when we hover on each image,
we get some information about that particular destination like how
long the trip is gonna take, where it is, or what it's called,
where it is on the globe, a little description,
and the starting price. And of course, we have a little
accent icon going on here. Of course,
this gallery is perfectly functional, we see all of the images and
we have all the information on hover. But it's static, it's boring,
so let's add some motion to it. Let's have a look at
the code actually first. So there's quite a lot
of things going on here.

Let me walk you through each image or
each gallery item. So we're basically using a figure element,
and then inside we have an image,
the actual image wrapped in an anchor tag because we want
it to lead to somewhere else. And then all of the content that you see,
all of the text content, and of course,
the icon here is placed in a fig caption. And that fig caption is further
divided into a main section that basically has the first three elements,
and then it has a footer. And the footer contains the price,
and the the arrow. In terms of the CSS, there's a lot
that I've already written here. But the one thing that
we're interested in or the main things that we're interested
in are the interactions, right? How are we getting them to show up? So, the dark background
is actually created by using a linear gradient
on the fig caption. The main and the footer, by default,
they have their opacity set to 0, and when we hover on the figure,
we set their opacity to 1.

So that's a good starting point. But now let's add some motion. And we'll start with this background,
right, the dark color overlay. Now traditionally, you would say, okay,
so we want to transition that background. Let's do this. Let's do figure figcaption, and we'll set transition-property
to the background. Maybe a transition duration, let's say, the default that we're using and
the timing function and ease in and out. Save that, refresh, and nothing happens. That's because we cannot transition
the background property or the background image property. Let's say this was, I don't know,
a background image and we wanna transition the background image,
right? It doesn't work because that's
currently not supported in CSS. So instead, let's replicate this
color overlay in such a way that it can be animated, and
that's with the help of a pseudo element.

So let's do the following. Let's comment this bit, and
also let's comment this bit. And we're gonna say here, not supported. Okay, so
now we're actually missing that overlay. Let's create it by using a pseudo element. We're gonna say figcaption::before. Let's give it a content blank. Let's set position absolute
because I want it to span like the entire width of its parent. Let's make sure the figcaption itself,
okay, so it does have a position, absolute. So any position that we
apply to the before will be relative to that figcaption,
that's good. So we're gonna set insert to 0. This basically makes the pseudo
element full width, full height. And then here's the cool part. We're gonna say background and we're
actually going to copy this entire thing. So we're essentially applying
the same background, but to the before pseudo element
instead of the figcaption. Let's set a z-index of -1 so it sits
under the all of the other elements.

Let's set an opacity to 0. So it's hidden by default. And actually,
let's see if we can see that. And we cannot see it just yet,
and that's because we need to set a z-index
of 1 on the figcaption. So it sits a little in front. Okay, so now we can see the before
pseudo element, the color overlay. So now let's set its opacity to 0, and let's set the transition
property to opacity, right? So we're transitioning the opacity.

And then at the very end, we're gonna
say figcaption::before just like we did in the previous demo, we're gonna set the
duration and timing function separately, because we're gonna apply
those to multiple elements. That color overlay is gone, so
we need to show it on hover. So we're gonna say figure on hover,
and then we're gonna target figcaption::before, and
we're simply gonna set an opacity to 1. And there we go. That's how you add a simple transition
to a color overlay like this. Great. Let's move on. What else can we do here? How about we scale up the image
because the images inside each figure, let's see if I can find that, yeah. So basically, all the images
have object fit set to cover, so they're gonna expand,
fill up the entire available space.

Which means we can scale them ourselves,
and they will still be displayed within
the boundaries of their parent. So to do that, we're gonna say
figure a img, transform: scale. Let's scale them to 1.2,
so 120% or 20% bigger. And then we'll set
transition-property to transform. And then of course,
we need to copy this, add it here, and we can actually just remove that,
figure ing is more than enough. So now our layout is totally broken. [LAUGH] Why is that? Because If we set the scale, right,
we scaled up the images, but we actually forgot to set overflow
to hidden on the parent element, which is the figure. So let's just target the figure and
set overflow to hidden, okay? So now the images are scaled up but
they don't show up or we can't see the overflow because
they're cut off on their parent element. So now let's actually
create the animation.

We're gonna say figure on hover, AIMG. Transform, scale back to one. So now it looks like this,
pretty cool effect, isn't it? So again, how we're doing this? We're initially scaling up
the image by 20% and then on hover. We scale it down back to its
original position, back to 100%, and we're just transitioning that
transform property, that scale. Nice, now let's animate the rest
of the elements as well. And we're gonna do this in two parts. We basically have the main,
which has these three elements, duration, name, and description.

And then we have the footer,
which has the price and the arrow. So let's set some initial styles for
those. We're gonna say figure main. Let's do this. Let's apply a transform. Let's do a translate 3D and
translate 3D is good option if you want to force browsers to use browser
to use hardware acceleration. They're gonna use the GPU to render
that animation which in most cases will make the animation a lot smoother
as opposed to a regular translate.

So translate 3D this receives
this three properties XYZ, we're gonna animate the y, so we're gonna say -6 rems and
0 for the z-axis. And then we'll set transition
property to opacity and transform. Because if you remember,
figure main and figure footer. By default, have their opacity set
to zero, and then on hover, or when we hover on the figure element,
we set their opacity to one.

So we want to animate
that opacity as well. And actually, let's move this up just
to be a bit neater with our code here. And let's add figure main and
figure footer to this list so they both receive the transition
duration and timing function. All right, so now we set its
initial position, which is -6 rem. So we're moving the main element above. Now, let's do the final position or
the position on hover. So we're gonna say figure hover,
main, transform translate 3D, 000.

So now on hover,
we have a nice transition, a nice animation that goes from
top to its original position. And also back when we hover out. Okay, so now let's see what
we can do with the footer. I want the footer to come in to
slide in from the bottom, right? So we get the top just
slide in from the top and the bottom to slide in from the bottom. It's kind of a symmetrical thing. So, let's talk let's copy this and I'm gonna say figure footer
transform translate 3D. This time, by default,
we're gonna set its initial position, 6 rems to the bottom, okay? And then transition property is
again opacity and transform. So then here, we can copy this
we can apply it to the footer element as well because It's
essentially the same transform, so now the animation looks like this. One half or actually two-thirds of
the content slides in from the top, and the other third slides
in from the bottom. Nice, right? But I'm actually not happy with
the image here, with the arrow. Let's do something to that as well.

Let's have it slide in from the left and
also do a bit of rotation, right? So down here,
we're gonna say figure footer image. Because it's only one image in the footer
so we can target it like this no problem. We're gonna say transform
first of all translate 3D and we're gonna say let's see -3 rems,
should be enough 00. And also,
we're gonna add another transform and you can chain these no problem just leave
a space and do the other transform. Rotate, let's do 360 degrees. And also, let's set the opacity to 0. So now, to show it,
we're gonna say figure on hover, footer image,
we're gonna transform translate 3D, just reset the values and
also reset the rotate. And we're gonna set the opacity to one,
okay? So now it looks something like this. The image here,
it comes in from the left and we also animate its opacity. But the thing is we don't actually
see this effect very well because it's happening kind of at the same
time with the other elements.

Plus it's because the icon is contained
within the footer of this gallery item, which is also animated,
by the time the animation here ends, its animation ends at the same time
as the animation for the footer. So how about we add a delay? So the idea is we animate the footer and
after the footer has finished animating,
then we start animating the actual icon. And to do that,
we're gonna go back here to the image. And we're gonna set a transition delay, meaning how long before
the transition starts and we're gonna add exactly
the default transition, the duration of our default transition, because that's what the footer is using,
right? So let's see if that works any better.

Hover, there we go. So by adding the delay,
the footer gets animated, and after the footer
is finished animating, then the icon starts its transition,
pretty nice. So that's yet
another example of how you can use simple transitions to add motion to a website Now, let's turn our attention
to practical exercise number 6, where we're gonna work on
this really cool accordion. So this is a fictional weather app
that displays The weather forecast for a given city and
each accordion item can be clicked on and it's gonna expand to show more information
along with some really cool graphics. And all of these graphics are taken from
Envato Elements so if you don't find them in the starter kit that's why you're
gonna have to download them yourself. But essentially, on the default state or on the collapsed state,
we're displaying day, date, a smaller version of the main graphic and
then day and night temperature. On the expanded version,
we add the weather conditions. We move the day and night temperature
under that and we're displaying some additional information, wind speed,
humidity and chance of rain.

Now let me start by saying
that this accordion was inspired by this pen from Zed Dash. Here's a link you'll also
find it linked in the code. So let me show you how this
works in terms of CSS, it actually starts with JavaScript,
right because when we click each of the accordion items we're either
removing or adding a class of opened. And if we take a look at the CSS here, we can see that the accordion
has a display of flex. So this is the parent element, okay? Each accordion item gets
a background color and image. And then on the opened one,
right so on the open class, we're basically changing the background
size and the flex basis.

This is how we're going from this size, from the collapsed to
the expanded version. This right here is 32 rems in width,
so let's see what kind of animations we can add to this to
make it a little bit more lively. First of all, let's start with
the with each accordion item. And let's transition this this change
in width, in background size and in padding because there is also
Just a minor change in padding here. So down here we're gonna do the following
we're gonna say accordion item and we're gonna transition the properties of
flex basis, background size and padding.

And, of course we need
to add the duration, just like we did in
the previous two demos, and I'm going to be using my CSS variable
there and then the timing function. Let's do an ease and
out just the simple one. So now you'll see that
just with those three lines of code we added some motion. We added a nice transition
to the background size and to the size of the actual card that's
being displayed and also to the padding. Now let's add a transition on hover,
let's say that when we hover on one of these items that are not opened,
we wanna increase the background size. We wanna make this image bigger, okay? So we're gonna say,
accordion-item on hover, and we're gonna target the ones
that are not opened. And this should actually be a class here,
so for the ones that are not opened, we're gonna change the background
size to 32 rems, and we're gonna change the padding block.

Padding block basically
means padding top and bottom in a regular or
in a layout with a default direction. So padding block,
let's set that to 3 rems so now, We get this,
right the background changes and the padding block, right? That pushes the content on the top,
it pushes it down and it only works on the stuff
that's not opened okay. Now let's try and make this animation
a little bit smoother because there are certain elements that
are not animating properly for example this temperature, right? So when we click on it,
it just disappears, right and when we collapse it,
it just shows up. So let's see what we can do about that. First of all, let's target it so
we're gonna say accordion item, unhover and also not opened and
let's target bottom-temp. By default, let's add a transform and
we're gonna move it down. So translate 3D 0, -1rem and 0, so on hover, yeah we push it up. I think I said we move it down no we
actually push it up we say y-1rem so we move it up.

Now, of course let's do this bottom-temp,
let's add a transition to that. So transition property,
what are we transitioning? The, sorry transform okay, and
let's also add the duration and timing function,
now let's actually move these down just so they're right at the end so
we can find them a little bit easier. Okay, so now both of these elements are,
animated correctly. But now, on opened I want this
bottom-temp to kind of move down, to fade down, because what happens is, on opened if we look at the original code,
opened bottom-temp, it has its opacity set to 0, so
it basically disappears from there.

So let's actually add the opacity here, let's transition it as well and we're gonna say opened bottom-temp, let's do a transform,
translate 3d, 0, 2rem and 0. And the 2rem is just to
push it down like so. So pay attention to it here, when we click
this or it's actually better visible here, when we click it, it's gonna move down and
disappear, like so. It's a very subtle fact, but
It's much better than for it to just disappear all of a sudden.

Okay, so
far we have a nice transition on hover, and we started to work
on these elements for when the accordion item is opened or
is expanded. But we still have a bit of work to do
because we still have the temperature which needs to be somehow animated and
these readings, right? So let's get to that, first of all let's
start with the temperature here and that's positioned in a class of temp. So we're gonna say temp, let's transition
the opacity and transform, okay? Because by default we're
gonna set the transform to translate 3D to 0,-
4rems on the y axis so it's above and then 0 and
then actually let's do the same for the readings and
this time it's going to be +4rems Okay, so the readings are gonna
be initially positioned further down the temp, further up.

And in their original or in their final
position when the card is revealed, they're gonna be at 0, 0. So let's actually add readings
here as well to transition those properties as well. And now all we have to do is say,
opened temp and opened readings, transform, translate3d(0, 0, 0). Okay, so now, It's still not happening. That's because we did not add
a duration retiming function. So let's add temp here, and readings. Great, now,
[LAUGH] it should work, so click. There we go. So it's a subtle animation,
but you can see it, right? The temperature slides from the top,
the readings slide from the bottom,
the opacity is also animated. It's a very subtle effect, but one that
really completes this whole picture.

And one last thing we need to do here, as you can see, in the default state, the date here is shown
in full white color. But on the open state it's actually
a bit more subdued, right? We're actually changing the color here. So just to wrap things up,
let's add a transition to that. And let's take a look at the code here. We have ul class date, and
we have the second list item. So pretty simple in CSS,
we're gonna say, date, list item and child(2) transition-property: color. And then we're gonna take this and
add it here to our list, okay? Save. And now that change in color on
this element is also transitioned. So in this lesson we worked on
three demos with CSS transitions. And the first thing we learned is that not
all CSS properties support transitions, for example background. However, there are workarounds, one of
which being the use of pseudo-elements. We also learned that not all transitions
in a page need the same duration. Sometimes using a longer transition
among shorter ones can create a very satisfying movement. And finally, we saw that transitions
are not limited to hover states.

For example, they can be triggered when
an element receives a certain class. And by saying what I just said,
we can check off yet another member of our dynamic trio. Now let's do a quick recap. So far in this course
we worked with videos, we added motion with some CSS transitions. And I also made some very
clever superhero references. Now all that's left to do is to
talk about CSS animations for the rest of this course. And don't worry,
there will be demos as well.

Let's start with an introduction. Earlier in this course, we, or I,
compared animations with Black Widow. And that's not because I don't like
Hawkeye, he's a cool dude, but kind of a one-trick pony. Black Widow, on the other hand,
is much more versatile. Therefore, she received the honor of
being compared to CSS animations. Not that she would ever care about that. Regardless, the point I'm trying to make
is that CSS animations are much more versatile than transitions. So in the next couple of minutes
we'll define a CSS animation, we'll create a simple one,
and we'll finally explore the differences between CSS animations and
CSS transitions. Let's begin. A CSS animation is a way to make elements
gradually change their appearance or position over time. It's done by defining keyframes, which
are the in-between states of this change. The animation is then created by smoothly
transitioning between these keyframes. Now, there are two parts
to creating CSS animations. First, you need to define the keyframes, essentially describing
the animation step-by-step. Then, number two, you apply that
animation to the elements that you want.

To create the keyframes,
you type @keyframes, followed by a name of your choosing. Then, inside curly braces,
you describe the steps. The easiest way is by using the from and
to keywords. Then inside each step, you can add as
many CSS declarations as you want. In this example, I'm creating an animation
called moveRight, which has two steps. In step one, I'm setting a transform
property to translate X(0). In step two,
the translateX is set to 100 pixel. This animation will essentially move
an element 100 pixels to the right. Now that you have keyframes,
therefore you described the animation, you need to apply it to
whatever elements you want. And to do that, there are several
animation-related properties such as animation name, animation duration,
animation delay, and so on. But in most cases you'll be
using a shorthand notation, and the recommended syntax goes like this.

The property name is animation and
is followed by a list of values for duration, easing-function,
delay, iteration-count, direction, fill-mode,
play-state, and name. In this example, we're applying
the moveRight animation we created earlier to the elements
with the class of box. The duration is set to 3 seconds,
it uses ease-in-out as the easing function, it has a 1
second delay, and it runs twice. Notice how the code in this example did
not use every animation-related property. And that's because you don't have to. At a minimum, you need to specify an
animation name and an animation duration.

The rest can be used as needed. So now let's go to Practical Exercise
#7 where we have a simple image. This is an SVG, actually,
that I got from Envato Elements. Now, let's create a simple animation. Let's make this into a page loader. And to keep it simple,
let's make it breathe. Meaning from its initial size, it grows a little and
then it shrinks back. So let's see how we can achieve
that with CSS animations. So if you remember, what was the first
step to creating animations, defining keyframes, right? Describing the actual animation. So we're gonna say key frames. We're gonna call this breathe. And then inside we're
gonna say from transform, scale 1 to transform scale 1.2. So now we described the animation.

Let's apply it. Let's target the loading screen
which is our div basically, or actually let's apply it to the loader
icon because we have an ID set for that. So loader icon, let's set the duration, so we'll set animation,
three seconds for duration, easing, we can put something like ease in out,
how many times do we want it to repeat? Let's say, Infinite so
it goes on and on and on and then the name of the animation
breathe save refresh nice so the animation makes this
SVG element grow in size. Over three seconds from scale 100 to 120%. But there is a weird effect, after
the animation ends, it kind of goes back. To its original position. And it's not exactly a breathing effect,
right? Because the scale down, basically, so the scale from 120 to 100%
should also be animated. So the way we can do that is by adding alternate and let's reapply that. So alternate basically solves our problem. But what exactly does it do? Well, the animation, if you remember
from the slides I showed you, the animation has a direction, so
it can go forward or it can go in reverse.

By default,
the animation goes forward, so from 2. But if we set the direction to reverse,
let's actually do that right now, reverse, it goes from
scale up to scale down, so it goes from a 120% to a 100% in size. Now alternate, this is the animation mode alternate basically
does one iteration of the animation in forwards and
the other in reverse. Okay, so, this one is in forwards,
and when it reaches the end, alternate does the other
iteration in reverse, therefore giving us the breathe
effect that we're after. Now, let me preemptively
answer this question. Does the order of the values matter? Meaning does the code on the left do
the same thing as the code on the right? The answer is no. Each of those two code snippets
produces a slightly different result. And the answer is yes,
the order does matter. You see the order of
time values is important. So the first one that can be parsed as
a time value is assigned to the animation duration, and the second one is
assigned to the animation delay.

So the animation on the left will
have a duration of three seconds. In a delay of one second, while the one
on the right will have a duration of one second and a delay of three
seconds, so keep that in mind. Also the animation name should be used
last is considered best practice and the reason for that is very simple. If a value can be used for
something other than the animation name, it's applied to that property first. So, just to be consistent and
make your code easier to read and avoid potential future issues, just follow the simple rule and
use the animation name last.

Now, previously in the course,
I said that animations allow us to create much more complex movement, and
that's true, but what exactly is that? What is complex movement, and how are animations
different than transitions? Well, let's consider keyframes
to begin with an animation is basically a series of keyframes of
steps and you can have any number of those transitions can only have two
steps start and end nothing in between. The second difference is that
animations support looping, meaning it can be run once,
twice, 10 times, or continuously. Transitions, on the other hand,
run just once. The third major difference is direction. You see,
transitions have a fixed direction. Meaning they go one way. Animations can go forward in reverse, and
they can even alternate between the two. Finally, we have play atate. An animation can be paused,
transitions cannot. Once a transaction starts,
it runs to the end, but an animation can be paused or
resumed at any point. So they're both very useful techniques,
but they should be used appropriately. Animations for complex movements
that has more than two steps. That I know is repeatable,
that is also pausable.

Is that a word, pausable? That can be paused, right? And the transitions for
simple changes between two states. So, in this lesson we learned that
CSS animations gradually change elements by smoothly transitioning
between defined keyframes to create keyframes use @keyframes
followed by a chosen name. Then, inside Curly Braces,
describe the animation steps. You can use from and
to for the easiest setup. You can apply animations using
properties like animation-name, animation-duration, and animation-delay. You can also use a shorthand
animation property with values for duration, easing, delay, iteration count, direction, fill mode,
play state, and name. At a minimum, you need to specify
the animation name and duration. The rest can be added as needed. Adding alternate as the direction causes
the animation to alternate between forward and reverse at the end of each iteration,
creating a back and forth effect. If you're using the shorthand notation,
the order of time values is important. The first one is assigned
to animation-duration and the second to animation-delay. Finally, remember that animations
consist of multiple keyframes and support looping,
direction changes and play pause.

Transitions only have two steps,
start and end. And run once with a fixed direction. And those are the basics
of CSS animations. Don't worry, we'll also cover the more
advanced stuff as the course goes on, and we'll explore the various
use cases for these. Let's start with some loading animations. Loading animations are very
common in user interfaces because they're a great way of informing
users that something is happening. Occasionally showing
the progress of that something. Take this spinner animation, for example. It's very simple, yet
very straightforward, because when you see it,
you immediately think, okay, so there's something going on in
the background, something's cooking up. And this has a good impact on UX,
on the user experience, because it gives users confidence and
reassurance. For example, if I fill in a form and I
submit my data and that data processing or submission takes a while,
I would like to get some sort of feedback to let me know what's going on,
if my data has been received or is processing, and a loading animation
is perfect for that kind of thing.

And these can be of any shape or size,
they don't need to be a spinning circle. So they can look like this,
or like this, or like this. And by the way, if you go to
Envato Elements and you search for loading, you'll find tons of cool stuff, from video templates to standalone
graphics just like these. Ultimately, designers can
choose to design these loading animations to be in style with the overall
website concept or the even the brand.

So let me show you some
real world examples. The first one is Dogstudio,
and if we do a quick refresh we'll see this nice animation
of the dog running. Let's see that again. Really nice, it's, of course, in-line
with the rest of the website concept, having the dog and stuff,
but also the colors match. We get that kind of orange there, and
we also have these orange accents here. So, fantastic. Another example comes from
the Marie Weber website, where you can see this loading
animation here, really nice. This is actually a part of
the logo from Marie Weber. See that again. So, yeah, it's kind of a drawing
animation of the logo. Loading animations can also
be displayed like this, like a loading bar actually. And here we can also see the percentage,
really nice. We get a similar effect
here on the Moxion website. Again, we have a loading bar and
then the content just animates in. And finally,
let's have a look at the Sketch website.

And if we scroll a little bit
further down to the features here, we can see that we have some
loading animations right here. So the idea is when a certain
feature is being displayed, or rather the image for
that feature is being displayed, this gets highlighted and
we get a loading animation telling us how long that feature
will remain highlighted. Now the loading animations I
just showed you are used almost exclusively as a placeholder
until the page fully loads, and they are also known as site preloaders. But not all loading animations
should be used like that. And let me give you an example. If we go to MTB Riders and
we just select a new product, we click Add To Cart,
watch what happens inside the button. Saw that? It was pretty fast, but let's do it again. Yeah, we got a brief animation of
some dots running telling us that, okay, you clicked Add To Cart,
we're working on it.

And then at the end,
I also got this nice message that says, okay, we added the item to your cart. So that's considered as
another loading animation, but it's not used as a site pre-loader. Instead, it's used in
another part of the UI. Actually, just like this one from Sketch,
it basically achieves a similar result. Now, to create these cool loading
animations, we have two options. Either we create them ourselves,
which we'll do in just a bit, or we get them from somewhere else, right? Searching Google for CSS spinner will
give us plenty of results to choose from. I recommend SpinKit by Tobias Ahlin. Once you find a loader you like,
you simply copy the HTML, copy the CSS, and that's it. Now, apart from your typical CSS loaders,
you can also use Lottie animations. And Lottie is a versatile
animation file format.

It's open source, lightweight,
high quality, and infinitely scalable. You can easily incorporate Lottie
animations into your projects, and they can be manipulated in real time. Fun fact, Lottie animations
are super popular among the top 500 apps in the App Store. And they're super popular or they're heavily used by
some big names like Apple, Google, Adobe, Disney,
Netflix, and many more. If you're on the hunt for
Lottie animations, your first stop should be the official
website at lottiefiles.com. Here you can simply search for
something like loader, and check out all the cool animations
created by the community.

You'll find both freebies and
premium picks. And when you find one you like, just click on it to see how you
can use it in your project. And with an active subscription, you can download tons of Lottie
files from Envato Elements. For example, here are some really
cool animated technology icons. There is a lot to talk about when
it comes to Lottie animations, that's probably a separate
course on itself. So for now, let's focus on this course and
this lesson, which is about loading animations. And let's get to practical, let's create
some of these animations ourselves. Time for Practical Exercise number 8. And for this, we're gonna be
creating a site pre-loader, and we'll use one of our older demos,
this nice image gallery here. And the reason why we would need such a
site preloader is that there are a lot of images here, and
it might take a while to download, especially if we're on a slow connection. So it's a good idea to show some
kind of loading indicator while the page is loading in the background.

So if we go to the network here and
we do, let's do something like a slow 3G simulation,
and we'll disable the cache. You can see that the images,
once we refresh, right, it's gonna take
a while to download. And so the end user doesn't necessarily
need to see this, doesn't need to wait for the images to To load, but instead,
we're gonna show a nice loading animation.

And as you can see, it still takes quite a while because
I used large images here on purpose. And it's just gonna keep going. All right, so let's close this for now and
start working on our site preloader. And we're gonna start with the HTML. So we're in exercise 8 here. And the way I have the setup is,
I have all of the page content placed in a section that has
an id of page-content, right? We have the header here, the gallery, and there's nothing else on
the page apart from that. So let's actually create our
loader container here, and we're gonna use some CSS
to style that accordingly. So I'm gonna say div
class= "loader-container", and inside, I'm gonna create
another div with a class of loader.

Now, we're not gonna
use a pre-made loader. We're gonna create it ourselves. It's super easy to do from CSS. So right now, we just have two empty divs. Now, let's go in here in our CSS,
and we're gonna say the following. Let's start with
the loader-container first. So what I wanna do here is basically
have this fill up the entire page, and we're gonna give
it a background color. And we're gonna place it above
everything else on the page, okay? So the way to do that, very easily,
we're gonna set a position to fixed.

We'll set inset: 0, so
it fills up the entire viewport. We're gonna set a z-index of 999,
so it's really high. And then let's set a background color, and I'm gonna use #0c0603. And then I want the actual loader to
be placed in the middle of the page, basically. So I'm gonna use grid for that,
because I can do place-content: center, and that's gonna center everything
nicely without me having to do anything. So right now, as you can see,
I have this black screen almost. It's not exactly black, but
it's a very dark color screen, and it covers absolutely everything. Now, let's work on the actual loader,
the loading animation. So let's target the loader class, oops. And let's do this. Let's do with 4rems. And just so you know,
we're gonna do a spinning circle. Gonna do a height of 4rems. And let's do the following,
border, we gonna do .4rem solid. And let's give it color of f27541. Okay, so now, we basically have,
let me zoom in here, we basically have a box with a border,
right? So now what I'm gonna do is say this,
border-left-color: transparent, and that's gonna get
rid of the left border.

I'm gonna do the same for
the right border, so it looks like this. And now I'm gonna say border-radius:
50% to turn it into a circle. Pretty cool? So now, let's animate this. We're gonna rotate it, basically, okay? So let's create an animation,
let's call it spinner, and let's do this,
from transform: rotate(0deg) and scale(1). We're gonna say to transform:
rotate 360 degrees or 1 turn. And let's also scale it up a bit, 1.2. So now let's apply that animation. We're gonna say animation. Let's do .8s ease, as an easing, infinite, to just go on and on and
on forever, and the animation name.

And it looks like that. Pretty cool, except we get that
glitch when the animation ends. Because we have a scale, it doesn't
go back to its original position. So let's add an alternate here. So it looks like this. Nice. And by the way,
we can totally comment this bit and the animation will still work. Why is that? Because these are the default values,
right? It's a given that the browser will
start at rotate(0) and scale(1). So we can actually just remove this
entirely and have the two step. The reason even in the previous lesson,
I showed you the from and to is that so
you understand the starting position and the end position, but
this is actually optional. The animation will still work just fine. And now, let's only display this spinning
animation while the page is loading. After it's finished loading,
we're going to hide the whole thing. So how do we do that? Well, we need to write some Javascript.

So let's go right at
the end of our page here. And we're gonna start by
defining some constants here. First of all,
we're going to get the loaderContainer. And then we'll do a querySelector for
loader-container. And we'll do another constant for
the pageContent, right? And that's also querySelector for
the page-contents. If you remember,
we have that section defined right there. So this is super easy to do. We can say
window.addEventListener('load'), and then we're gonna pass
in an anonymous function. And we're gonna say
loaderContainer.classList.add('hidden'), and then
pageContent.classList.add('visible'), super simple. So basically, when the window
finishes loading all of these assets, it's gonna add the hidden class
to the dark loader container and the visible class to the page content. So now, we basically have to go back
to our CSS and create those classes. So we're gonna start with the
loader-container with the class of hidden. That's basically gonna say opacity: 0,
visibility: hidden. And then the #page-content,
by default, it's gonna have opacity:0. And let's actually do
a simple transform effect.

We're gonna say transform: translate3d. Let's do 0,- 1rem, so
we pushed up a little bit. And then #page-content
with the class of visible. We do what? We say opacity: 1 and
we reset the transform, like so. So let's see if that works. Now, let's open up a console here. Let's see if we have any errors,
and we do not. And let's go to Network. Let's simulate that same page reload. Okay, so
we're showing the loader until the page finishes downloading
basically all of its assets, which is gonna take a while apparently.

And there we go, once it finished
downloading, it took 25 seconds, it hid the loader, and it showed it,
and it, sorry it showed us our page. Now, of course, that just suddenly appeared because we
didn't add any kind of transitions. So let's go to the loader container, and
we're gonna transition here the opacity, let's do like 0.4 seconds ease-in-out, and also the visibility because
we're also animating that one. Ease-in-out, and that's for
the lower container, we also need to apply a transition to
the page content right here, okay. So we'll say transition for
what the opacity, let's do 0.6 seconds this time so
a little bit bigger, ease-in-out, and
we're also transforming, right. So transform 0.6 seconds ease-in-out, so the page content between it
being in its default state and being visible, yes we change the opacity,
and we change the transform. So those are the two properties
we're transitioning, so now, let's go back here and
we'll do basically the same test.

And last time it took about 25 seconds,
so it's probably gonna take exactly the same this time
because we disabled a cache, and we're using the same 3G,
Fast 3G preset. But yes, as soon as that's finished,
we get a nice transition. The page content kind of slid,
slid, slided, I think slided, the page content
kind of slided from the top, while also animating its capacity, so
pretty cool effect, very simple to do. And you saw how easy it is just to create
a loader with a couple of lines of CSS. This first demo was super simple, so
you can understand the whole process, but as you saw from the real world
examples I showed you earlier, loading animations can
be way more complex. So, time for
practical exercise number nine.

So, when I was working on the demos for
this course, I was wondering what I should do for
a loading animation. And I remember this website that I
showed you previously in this course, it's Marie Weber. And if you remember,
there is like a hand drawn animation of the logo as a loader,
which you can see right here. So that's pretty cool,
and I thought, okay, so I wanna do something like that, but
what if I want to do it with text? And thankfully,
if we're doing this using SVG, there's actually a pretty
cool technique we can apply, by using something called
stroke-offset and stroke-array. Those are properties
which can be animated, so let me show you how we can
do something like that. So we're gonna start
here in exercise nine, now we're gonna create our SVG and don't worry,
it's nothing super complicated.

And let's give it a view box,
and we're gonna say 0-0, we're gonna make this a text 400 by 160. And inside the SVG we're basically
gonna have two text elements, and the first text is gonna say graphics, this
is just a random, company name I guess. And this is gonna be our logo basically,
and we're gonna do the following,
I'm gonna set an x value of 50%. Same for Y, 50%, and
this is just gonna place the text, it's gonna give the text coordinates,
basically. And then I'm gonna say dy, and
I'm going to set that to 0.32 rems, and the dy is basically
an attribute that indicates, let's call it a shift along the y-axis. So we're basically just shifting it up or
down, and I'm doing this just for alignment purposes, don't worry
about this too much at this point. Also, we're gonna set text anchor middle,
that's gonna serve as a reference for the coordinates, and then I'm gonna
give this a class of text body, great.

Now, I'm actually gonna copy this and I'm gonna add a dot in here,
so if we check this out, now we can't actually see anything
because we need to set some CSS for it. So let's go ahead and do that,
right now, I'm gonna say SVG, SVG text, actually, and let's do the text body,
first, let's add a stroke. And I'm gonna use a variable
here called loader text color, and let's actually give this font size. Let's say five rems and
let's give it a stroke width of two so we can actually see something,
we can't see it yet. Let's also give the SVG size,
let's say with like 20 rems, so now we can start actually seeing
stuff and let's make it bolder, right. So I'm using pop-ins here as a font, and now let's position this dot
right here at the end, so I'm actually gonna do this right here. I'm gonna say dx,
which is the shift on the y-axis, I'm gonna set that to 2 rems,
and actually, let's use ems here instead of rems,
okay, there we go.

Because I want these distances to
be relative to the font size of the actual graphic, so
let's increase this a little bit. Okay, so for now, that looks just fine, let me actually make
this a little bit bigger. All right, so coming back to the CSS, I would like the letters here to be
just a little bit closer together. So let's actually add the letter
spacing of minus six pixels, so something like that.

And now let's create the animations,
right, so key frames, let's call this animate stroke, and we're
gonna add this to the text body, right. So I'm gonna say animation,
let's run this over four seconds, infinite, alternate, so it goes in both
the directions and animate stroke. Okay, so here's how we're going
to create this animation, basically, I want this SVG
text to be almost drawn, I want the outline to be drawn,
step-by-step.

So let's start with this,
instead of from and to, we can actually use percentages,
I can say 0% and that's the start. We're gonna fill this transparent or
we're gonna set the fill to transparent, I'm gonna set the stroke to
the loader text color, And now, I'm gonna say stroke-width: 3,
so this is what we got so far. And then the two properties that are gonna
make this happen are stroke-dashoffset. I'm gonna set this at 25%, and then stroke-dasharray: 0 and 32%. Now, let me quickly explain
these two properties. Stroke-dasharray, let's
start with this one. So this is an attribute that
defines the pattern of dashes and gaps used to create
the outline of our text. Okay, so for example,
let's hide this animation for now. If I were to set the stroke-dasharray
on the text body. Let's do the dashes,
let's say 100 pixels, okay? And let's actually do 10 pixels. I think it's gonna be easier
to illustrate like that. So, if I do 10 pixels here, it means
the dashes are 10 pixels in width.

And in between the dashes,
we have a 32% gap, that's 32% of the total width. But I can change this to 20 pixels, okay? So now I'm gonna have a 10 pixel dash and
a 20 pixel gap. And that's just gonna keep going along the
entire the width of the stroke, basically. So that's what these two
attributes are doing. Now, in my case, I'm setting initially the dasharray to 0 and 32%, meaning 0. I don't have any dashes. And 32% for the gaps, well,
that's just the width of the gaps. Now, stroke-dashoffset basically means
the starting point of the dashes. That's what it's defining. And right now we're offsetting the dashes by 25% of the total path length. So, if I were displaying
any kind of dashes, they would start a quarter of the way in. Now at 50%, I'll do this,
I'll maintain the fill to transparent, and this is important for
later, as you'll see. The stroke as well, I'm gonna
maintain it at loader-text-color and stroke-width is still at 3.

So I basically didn't change anything. And I'm doing this on purpose because
the actual change will be at 80%. And here, I'm gonna do this, fill, I'm gonna change the fill
to the loader-text-color. I'm gonna change
the stroke to transparent. I'm gonna change the stroke-width to 0. And I'm gonna change
the dashoffset to -25% and the dasharray to 32% and 0. Let me show you how that works. It works something like this. Well, of course, we have a bit of an issue here where the fill just kind
of blinks twice, as you'll see. So it fills up and
then back and then back. And the reason for that is we need to
specify what happens at 100% as well.

And that's gonna be exactly
the same thing at 100%. So now this is the end result. Pretty cool? So the way this works, I'm starting
at 0% by setting these defaults. So the fill of the text, transparent. The stroke is this loader-text-color,
which is the white basically. And then stroke-width: 3. And then I'm starting with the dashoffset
of 25% and the dasharray of 32%. And the endpoint, which is 80% and 100%, I'm basically changing the fill
from transparent to the white. I'm changing the stroke from the white,
the transparent, I'm changing the stroke-width to 0. And these two properties
are what makes everything work.

I'm changing the dashoffset to -25%,
so the ending offset of the stroke is in a different
position than what we started with. And that's gonna be animated, that's gonna
create the whole animation basically. And then the dasharray,
I'm setting it from 0 for the length of the dashes
to 32% length of dashes, and from a 32% gap to 0 gap. And that's basically gonna
create this full outline shape. And I can actually make
this a lot longer so you can see how everything works. As the animation is closing
in on the 100%, yeah, the gaps in the strokes start
slowly disappearing and in the end the stroke disappears all
together while the text fills up. And when it goes in reverse,
you'll see that the stroke or the dashes get smaller and
smaller until they disappear completely.

So I hope that makes sense. This is a real nice effect. And by the way, I got inspiration for this by a CodePen by this chap right here. So that's the animation for
the actual text but we still have this dot here, so
how about we animate that as well? And the dot is gonna be quite simple,
so let's create a keyframe for it. And we're gonna call it animate-dot,
and for the dot, it's quite simple. I want 0% and
60% to have the opacity of 0, and then 100% opacity of 1. And if you're confused as to why I'm
using these two different stops, it basically means that I want
the opacity of 0 to be applied both at the beginning but
also at the 60% point. So by doing this, I'm basically saying, okay, just animate the opacity
between 60% and 100%.

If I were to do just this,
it would animate the opacity between 0 and 100%, and
that's gonna be a longer animation. But if I'm doing this it's gonna be
a shorter animation because the animation itself will only happen when we're already
past 60% of the duration of the animation. I hope that makes sense. So let's actually go and
target that svg text with a class of dot. Let's actually fill that with.

The dot-color. And let's give it a stroke,
it's also gonna be the dot-color. And for animation, we'll, again, add 4s infinite, alternate animate-dot. So now the animation looks
something like this. You can see the dot there on
the left is also animated, and in the end, it's nicely displayed. Let's actually change
this back to 4 seconds.

Cool, and that's how you create
a loading animation based on text, based on SVG text to be exact. And that was another example of loading
animations, a bit more complex this time, but just like the first one,
it still served as a site preloader. But as I showed you previously, not all
loading animations should be used for that, they can be used in
other parts of the UI, as I'll demonstrate in
practical exercise number 10. And for exercise 10,
we have this very simple lo in form where we can fill in our name, our password, and
then we can click Log In. But just in case the login
action takes a bit of time, I wanna add some sort of indicator inside
this button to let the user know that, okay, we've got the data you filled in,
and we're executing the login process,
it might take a while. So I want to display some kind of loader
in this button while this is taking place. But of course, I don't have anything
running in the backend that allows me to simulate a login action.

So we're gonna use JavaScript just to
add a bit of a timeout that will give us the option to show that loader. So let's go back into our page here. You can see that I've declared some
constants here for the submitButton and the submitButtonText. And what I wanna do is
when we click the button, I'm gonna do, first of all,
e.preventDefault, and that's gonna just prevent the default
submit action of the button. And then I'm gonna add the loading class. So I'm gonna say
submitButton.classList.add('loading'). And then finally, I'm gonna use
the setTimeout function in JavaScript to set a timeout of 4 seconds
before I execute the following. We're gonna remove the loading class, so we're gonna say
submitButton.classList.remove('loading'). And we're gonna add the class of success,
so submitButton.classList.add('success'). And finally we're gonna
change the button text. So we're gonna say submitButtonText, yes .innerHTML is gonna be
equal to Login Successful. Awesome, so let's see how this works. Let's also do a quick inspect here.

Notice the button doesn't have
any kind of class apply to it, but when I click it,
It applies the class of loading. And after 4 seconds, yeah,
it changes the button text and it applies the class of success. So from a JavaScript point of view,
that's all we need to do, the rest is now gonna
be controlled from CSS. So let's actually add,
now let's create the loading animation. We're gonna start in HTML,
where I'm just gonna define three divs because I wanna do a dot animation with
three dots that are animated individually. So I'm just gonna create three divs,
three empty divs inside my button.

And of course, this doesn't do anything visually
because we need to apply some CSS. So in terms of CSS, actually,
let's wrap this in a div and let's give this a class of button–loader. That's gonna make it easier for
us to style. So in here,
we're gonna say button–loader. Let's use flexbox, as I said, display:
flex, and let's set a gap of .25rems. Okay, great, then let's target each div. So we're gonna say width,
let's do .8 rems, height, same thing. We're basically making them into circles. Let's make them white, let's make them
round, and let's see what we got. Okay, cool, so
now let's create the animation. We're gonna say #keyframes,
let's call the animation scaleUp. So for scaleUp, I basically want
to use scale(0) as a default, and that's gonna shrink
it all the way down, and then scale(1) somewhere in the middle.

So what I can do is say 0%, 80%, and 100%. I want transform: scale(0), and then at,
let's say, 40%, transform: scale(1). So now if we add this animation
to the button, let's say 1.2s, it goes on and on and on,
ease-in-out, and scaleUp. It looks something like this. So the dot basically is at scale(0), so it's basically invisible at 0%,
80%, and 100%. And it only scales up to 1
around the middle point, and that gives us this nice effect.

If I were to remove these,
it would look something like this, which is not what we want. So by doing this, we're saying that, okay, I want you to animate between scale(0) and
scale(1), right? That's my animation. So I want this animation to
take place between 0% and 40%. Then between 40% and 80%, I want you
to animate it the other way around, from scale(1) to scale(0), and
then the end point is 100%. I could also do this. Right, and it's still gonna work,
but the animation will just take a tiny bit longer, so it's really
up to you how you wanna do this. But while the animation works,
we can actually stagger the animation for
each of these dots by adding a delay.

So, well, we can do this. We can say button–loader
div:nth child(1). And I can say animation delay,
let's say, -0.32s. And then for the second one I can set an
animation delay to, let's say, half that. So now, the animation is the same for
each of these dots, but they're staggered. The nth-child(1) starts with
a bigger animation delay, nth-child(2) starts with
a smaller animation delay. So that gives the illusion that
they're kind of using a sort of timeline to be animated one
after the other, which is cool. So the animation here is
actually complete, but it's always present and
it's in the wrong position. So let's go ahead and fix that. I'm gonna target the button, and
I'm gonna set a display to flex, and I'm gonna align
everything to the center. So justify-content, align-items, center on both axes, so
it currently looks like this. And I'm also gonna give this button
a minimum height of 3.5rems, because we're gonna start
hiding certain elements.

And I don't want the button to suddenly
change its height when that happens, so I'm setting a minimum height. So now, by default, button–loader, I'm gonna set this display to none,
so we hide it. But then, when the button has
the loading class applied to it, I'm gonna target the button text and
hide it, okay? And the text disappears. But now, let's bring back the loader,
right, so button–loading, we're gonna
change this back to display: flex. So now when we click the button,
yeah, the animation shows up for four seconds, and then Login Successful. Let's also style that success class. So button with the class of success, we're just gonna change
the background color, really, to be var, and
I have a contextual success color here, so it looks something like this. And of course, if we want,
we can target the loading class, and we can say cursor: wait,
that's gonna change the cursor like this. And that's how you can add
a different kind of loading animation to a UI element with
a bit of JavaScript and some CSS.

So, in this lesson,
we explored loading animations, and these have the task of
keeping users informed and sometimes showing the progress
of a certain action. Most of the time, these animations
will be used as website preloaders. However, they can be used in other parts
of the UI, like for example, in a button. You can easily create simple spinners by
making certain borders transparent and then using a rotate or scale transform. To display a loading animation
while a page is loading, add an event listener for
the load event in JavaScript. Once that kicks in, hide your loader and
display the page content. To create an animated SVG text,
consider using the stroke-dasharray and stroke-dashoffset properties. The first one defines
the pattern of dashes and gaps, while the second one defines the offset
of the starting point for the dashes. When creating a loading animation
that has multiple elements, consider adding a different animation-delay to each
element for a unique movement pattern. All right, so
with the loading animations done, it's time to move on and talk about
animating illustrations and icons.

Now, some people would say that animated
illustrations or icons are just eye candy. But I disagree. I think that they can serve a practical
purpose, and if done right, these animations can actually enhance
the user experience in a number of ways. First, engagement, a good animation
will catch the user's eye, often making them more willing to stay and
explore. Let's look at stripe.com. When we get to the section
called Unified Platform, we immediately get drawn to this
content because it moves, it changes. Even if we were to just
randomly scroll down, the animations here will
definitely catch our attention.

Same thing happens further down the page. The spinning globe animation
looks super interesting, so most of us will stop to look at it and
even scan the text content on the left. Here's another great
example from feedly.com. You scroll down, and you're immediately
drawn to this robot-looking character that seems to be sorting stuff,
and you're like, okay,
this is interesting, what's his story? And then you explore and read the text and discover that it's about
this AI filtering feature.

But if it were a static image, you'd likely skim past it without
pausing to read the accompanying text. Animations can also be used to
guide a user through a process, or to draw the focus to
specific key elements. Let's look at Embassy IO,
where they're using some animated handwritten text to focus
the attention to certain links. The animation, combined with the arrows,
definitely gets the job done. Animated icons and
illustrations can also improve or enhance the user experience by providing
instant feedback to certain actions. If we go on Twitter, or X,
as it's called nowadays, clicking the like button
triggers an animation, instantly giving us feedback and
confirming our action was successful. Another great example is a menu icon. For instance, at Dogstudio,
hovering over the menu icon activates a subtle animation,
signaling it's clickable.

Clicking it then changes the hamburger
to a close icon, confirming the action. Finally, let's not forget
about entertainment, because, let's face it, a well-animated icon or illustration can make a static page
feel less boring and more entertaining. And I think the examples I showed you so
far have proved just that. Now, remember, moderation is key when dealing with animations because using too many animations can be distracting and
even annoying. After all, we don't want our websites to look like
they've had too much coffee, right? All right, so let's dive into
practical exercise number 11, where we'll create a simple animated icon.

And just as a quick reminder,
if you wanna follow along, you can download the starter
kit from the video description. And another reminder is that
the starter kit might contain different images than
the ones you see me use. The ones, I'm using in this
demo are from Envato Elements, and because they're licensed there,
I cannot redistribute them separately. I cannot give them to
you in a starter kit. So if you want the exact same
assets that are I'm using, you're gonna have to download them
yourself from Envato Elements. With that said, let's go. For exercise 11,
let's revisit one of our older demos. This is the one where we
used video as a background. And if you remember from
that original demo, we had an icon here, we had a mouse icon. So I wanna add that again,
but I wanna make it animated. I want to have the outline of a mouse, and then have a little dot inside
that just scrolls up and down just to signal that, hey,
scroll down to find more. Now, we're gonna be using LottieFiles for
this. And this is the only lesson I'm
gonna be using LottieFiles in, because I want the rest to be a little
bit more focused on using JavaScript and CSS to create the animations.

But I couldn't just pass the opportunity
to show you how to work with LottieFiles, so here we go. Now, I went to lottiefiles.com and
I searched for a mouse scrolling icon, you'll find a link to this,
and I found this bit, okay? And once you find it,
you can add it to one of your projects, you have to create an account,
which is free. But once you have it, you can open it in
this editor, you can see a preview of it, you can even show it on
a different transparent grid.

You can change the background color, and
you can also change the color palette. If you so desire, you can view
the different segments of the animation. And finally, the part that we're
interested in is Handoff & Embed. So you can go in here,
you can enable the asset link, which allows the animation to be
used on websites, app, whatever. And you would choose Lottie JSON or
Optimized, really depends on whether or not you wanna save some file size, and
then you get here to the Embed HTML. So all you gotta do is you can copy this. You go back to your code and
actually open exercise 11 there. And once you copy that, you're gonna
go right down here to the end of your page and you're gonna paste that in. Now, this pastes two things basically,
two scripts. One loads dotlottie, it actually
loads the dotlottie-player library. And then, it creates an HTML
element called dotlottie-player, where it specifies the src,
the address of the animation. And you can also use it to change some of
its properties here, like the background, the speed it runs, whether or not you
want it to loop or to autoplay, and stuff like that.

So all you gotta do is save, and
then you can come back here and you see the animation is loaded. It's running,
except it's a little bit too big. So all I'm gonna do is
change the width and height here from 300 to 80 pixels,
and that should be it. So now, you have a simple loading
animation directly running in your page. It was what? 3 kilobytes? Let's see, what was it? 3.1 kilobytes, you can go to 2.6 if
you are using the optimized JSON.

Or you have some more options,
this is the JSON route. You can also get the dotlottie, you have a lot of different
options to embed this. You can integrate it even with Webflow,
with Wix, WordPress, Elementor, and
a whole bunch of other things. So Lottie animations,
super simple to use, they're highly or super, super popular, and there are plenty
of sources for you to use them. As I said, this is the only
place we're gonna use it just to show you how it's done and how easy it is.

Now, what if you can't find
the perfect animation? What if you're browsing LottieFiles and
other stuff and you just can't find the one that
tickles your fancy, so to speak? Well, you have to create it yourself. So let me show you how you can do
that in Practical Exercise #12. So this is what we have in
practical exercise number 12, a simple header and a simple hero image. And the one thing that we're missing is
a menu icon right here on the left side. That's gonna toggle an animated menu. So let's actually create that ourselves. Let's create a menu icon,
a hamburger menu icon, that turns into an x when it's clicked. So let's start with the HTML, and we're gonna go all the way
down here in the header. And we're gonna create a button with a
class of button and an ID of menu-button. And inside, all I'm gonna do is
create three spans, that's it. We're gonna use these spans for
the lines of the hamburger icon.

So then, let's start writing some CSS. I'm gonna say #menu-button. Let's use flexbox, so display: flex, and let's set it as column,
so from top to bottom. Let's set a gap of 3.5px. Let's set a width of 2.5rems,
a height of 2.5 rems. And let's align the items
to the center and also justify the content to the center. And then, let's start styling our span
elements, our lines, basically, right? So I'm gonna set the width to 25px.

I'm gonna set the height
of each line to 2.5px. Background color, I have some variables
defined here, and there we go. Let me actually make this a lot bigger so
we can see what we're doing. Okay, just disregard the rest of
the layout, let's just focus on the icon. Let's also add just a tiny bit
of border radius to these lines. border-radius, let's do 2px, and
that's gonna make them nice and arounded. Okay, so how are we gonna animate these so that they turn into an x
when the menu is opened? Well, it's quite simple. We have three lines, but
an x only has two lines. So we need to hide the middle line,
that's one step. We also need to bring the top line and
the bottom line to the middle.

And from there, we need to rotate them
around their centers to 45 degrees, and that's gonna create an x. So let's start doing that. And let me show you what I'm doing
from the JavaScript point of view. When we click the Menu button,
I'm targeting the rootElement, which is the HTML. And I'm just toggling an attribute called
menu-open, and it can actually see that. If we do a quick inspect here,
and I click on, On the button, right,
you can see that it toggles the menu-open. And we can also see the menu,
because that's already made from CSS. So it just toggles menu-open on and
off, that's it. Now, going back to the animation here. I showed you that because that's how we're
gonna target the open and closed states.

So we're gonna say root with
an attribute of menu-open, menu-button, span, nth-child(1). This basically just targets
the very first line, the top line. So what do we wanna do is set
a transform to it of translate3d. And we're gonna push it down so that
it's perfectly overlaps the middle line. And I did the calculations, it's 6px, and
I also want to rotate it to 45 degrees. So now, if we click,
we briefly saw the transformation. But the color of the Menu
button is actually the same color as the background,
so we cannot see it.

But let's do that, let's target the Menu buttons span
separately when the menu is opened, and I'm gonna set the background
color to color-bg, okay? So the first line is now
positioned correctly, it overlaps the center line and
it's rotated. Let's do the same for
the bottom line, all right? So let's duplicate that,
let's target line number three. This time we're gonna move
it up instead of down, and the rotation is gonna be
the other way around. So now, it looks like this. But now, let's see what we do with
the second line, with the middle line. So we're gonna target nth-child, 2. And here on the transform,
let's just do a scalex(0). So we're basically shrinking
it to 0 on the x-axis, and let's set the opacity to 0.

So now, we just get an x. But that's not much of an animation,
is it? It's just a sudden change,
so let's fix that. Let's go to the span here,
and let's say this, transition: transform 0.3s easy-in-out. What else are we supposed to transition? The opacity of the middle line. So let's do opacity, oops,
I actually meant to do that. So opacity 0.3 seconds, same thing. What else?
The background color of the spans, let's do a 0.5s s ease-in-out. Okay, so now, click, And we get a nice animation. And that's how you can easily turn a hamburger icon to an x and vice versa. And what we just created here
is called a micro interaction. I'm just gonna introduce
this this new term for you.

And a micro interaction is
basically a brief moments of interaction between the user and
the UI, right? So for example, the Like buttons, right? If you click the Like button on
x like I showed you previously, that does something,
it creates an animation. Well, that's a micro interaction, because
it's super brief just like this one. It's just a simple animation that shows me
the original menu icon turned into an x. And this is now telling me that, okay, this is where you need to click
to close out that menu, right? That's a very brief interaction,
but one that does its job. And we actually created a micro
interaction before, if you can remember.

Was it in exercise 11 or 10? Yeah, right here, this one,
where we changed the text to the dots. That was also a micro interaction, and that's a very easy way of creating
this very popular animation. I'm sure you've seen it around. And at some point, you're gonna have
to create something similar to this. So I think it's a great one
to have in your toolkit. Now, there are a billion
ways of animating icons, and I invite you to discover
other ways of doing that. Using SVGs is also a very popular, but we could probably make an entire
course just about that. So for the time being,
we're just gonna stick to this one demo. Now, let's talk about
animating illustrations. And for that,
we'll go to Practical Exercise #13. And we're gonna use the exact
same demo as before, but this time we're gonna focus our attention
on a different part of the page.

In particular to this
animation right here, which can be downloaded
from Envato Elements. You can find the link in
the lesson description and in the video description as well. Now, how do we animate
an illustration like this? Well, the most important part is that
we have the layered version, okay? So this is an SVG that
I have here in Figma. And as you can see, it's layered. Each individual piece is a separate layer. Without this, if you wanna animate
the individual pieces of it, you're gonna have to cut it yourself,
if you had a raster image. But because we have it as a layered SVG, it's really easy for us to work with it. So I want to animate a couple
of different elements. And before we get to the code part, we're
gonna work a little bit here in Figma, because we need to group those elements
and give them some proper names.

That's gonna really help us later on. So first of all,
I want to animate the stars, right? You can see that each one of these stars
is a separate layer, it's a vector, okay? So let's grab this, this,
this, this, and this. We have five stars and we're gonna group
them up, and I'm gonna call them stars. Next up, I have this location pin here. And I'm gonna rename that to location pin,
and let's also give it a dash there. Next up,
I would like to animate this line, right, I wanna make a dotted line,
which gets slowly animated. But I can't really do
that with this vector, because of the way it's constructed.

So I'm gonna have to
recreate this line myself. That's not really hard to do. Let's grab the pen here, let's start here. And I'm just gonna create a few points,
trying to match the curve there. It doesn't have to be super perfect,
I'm not the best illustrator. Okay, but
that should do the trick for now. So let's actually move it up just a bit,
and what I'm gonna do is go to
the Stroke options here. And under Stroke Style,
I'm gonna select Dash, and I'm gonna set the dashes to be about 20. No that's too much, 16. Maybe 8 pixels.

And the gaps,
maybe a bit less, or actually, I think we'll leave it at that, 8 and 8. Let's round off the gaps there. And let's also change
the stroke to maybe 8. No, that's way too much, 2 or 3. I think 2 should do the trick fine. And let's also grab the color for
that, paste it in. All right, so
now I can bring it in like so. And actually,
I can hide that original one, or I can delete it altogether if I want to. Let's call this dotted line,
and that looks pretty good. It looks relatively close to
what we had before, great. So that's the dotted line. And then we have these icons for the
plane, the boat, the train, and the bus. I want to animate those as well. So let's grab, now let's see,
these should be together here.

So let's grab this. Let's call it icon, what is this, plane? Then we have this, that's icon boat. And then we have the next one,
group that up, that's icon bus. And this final one, that's icon train. Okay, so we've now grouped all
the elements that I want to animate. The next step is to select this SVG,
click on Export, make sure you select SVG from here, and then go to the three dots and
check, Include ID attributes. This is very important. So now you can export this as an SVG, but we're actually gonna go in here
right-click and select Copy as SVG. And then we're gonna go into our
code editor, all the way down here, in the HTML part, and
we're gonna paste that in. So as you can see,
it's a big, big, big SVG. But the important parts are that
because we checked this box here, we now have the correct groups
with the correct IDs with the layer names from Figma,
basically, right? So we can target those in CSS.

So for the time being,
let's just collapse that SVG, let's save. And now we can go back to our page and
everything looks like it did before, except we now have an internal SVG and
we have access to the layers that we're interested in,
and we can start animating. So, let's jump back to VSCode right here,
and let's start with the stars. So in our SVG, I actually have to expand
this again, we have our stars group. And in that group,
we have a couple of paths. So let's actually rename
these vectors to star-01, all the way to 05,
because we have five stars. So that's number two. Number three, I forgot to do this
in Figma, but that's fine, and 05. Okay, so now we can say the following, we're gonna use an attribute
selector in CSS. I wanna select all the elements
whose IDs contain star-, okay? And I want to do the following, I want to add an animation that lasts,
let's say, 6 seconds.

It has a standard timing function,
it goes on and on and on, alternate, and
let's call the animation pulse. So let's create that animation,
@keyframes pulse. So for the pulse,
we're gonna do something simple, 0%, 100% transform scale(1),
and also opacity: 1. And then at 50%, it's gonna be
transform: scale(0), opacity: 0. Very standard animation, right? So now let's check it out. And this is what happens. We can also set
the transform-origin to center, so that the animation will
start from the center or relative to the center of the element, but it's still not what we're after, right? Because these stars, these SVGs are,
sure, they're scaling up and down, but they're not scaling
relative to themselves, okay? They're scaling relative to
the middle of this entire viewport, to the bigger SVG, or
to the middle of the larger SVG.

And that's because these are using
a property called transform-box. By default, it uses a value of view-box, which uses the viewport of
the nearest SVG as a reference. So to get around that,
to make sure that the individual SVGs are animating in relation to their own
bounding box, we're gonna do this. Let's give the illustration or
this big SVG an ID of illustration, so
we can target it in CSS. And I'm gonna say, illustration, and
I'm gonna select all the elements. And I'm simply gonna say, transform-box,
and I'm gonna set that to fill-box. As I said, view-box is the default, but it uses the viewport of
the nearest SVG as the reference.

Fill-box uses the object's
bounding box as the reference. Okay, so now, after we save this,
you'll see that the individual SVGs, yeah, they're now creating
those animations or performing those animations in
relation to their own position and size, which is exactly what we want. And let's actually go and set a delay for these because I don't want them
animating at the same time. So right here, I'm gonna say,
star-02, animation-delay let's say, I don't know, 1.2 seconds,
and star 03, 04, and 05. Let's increase this, let's double
it in fact, so 2.4 seconds, 3.6. Sorry, not double,
just add 1.2 seconds on each. Each of these, so 4.8, okay? So now you see that these will animate,
but they're gonna be staggered, right? Not all at the same time, but one now, one
after 1.2 seconds, one after 4.8 seconds. So the effect is kind of random. Okay, so that's the first animation done,
that's for the stars.

Okay, let's see about the location pin,
right, it's this one. Now, what kind of animation
would I want to create here? Let me actually make this bigger. It's a location pin,
it shows a location, right? And it should draw the attention
to a specific location. So how about we do a bounce animation? So for the bounce animation,
let's do this. I'm gonna say location-pin,
I believe I called it, so location-pin. Let's do animation,
let's do 4 seconds infinite. And let's do a bounce animation. And then we'll say @keyframes bounce. And now, instead of trying to create
a bounce animation from scratch, which can be quite hard,
we can use an existing one.

So if we go to Animate.css, this is a CSS
animation library created by Daniel Eden, we have a bounce animation,
something like this. And we can actually check
out the source of that, if we go to the CSS and we search for bounce, quite simple, right? And actually, let's just copy
the entire key frames from here. And I'm gonna paste them right here. Just gonna do a bit of cleanup here,
we don't actually need the prefixes here. And as you can see, this is using
some custom timing functions. And it would have taken us quite
a bit to do it from scratch. So let's do that, and
finally that, and finally that. And of course, normally I would
leave these in, the vendor prefixes. But I wanna make this code as
clean as possible for you, so you can understand this better. So now, this is how animation looks like. Cool, let's move on. What else do we have? We have the dotted line, right, this one. And actually I think I'm gonna
recreate it with CSS, right? So we have a stroke-width="2"
stroke-dasharray here.

Let's actually remove this attributes, so
that I just have the line here, right? It's currently invisible. So now we can go to CSS,
and we can say dotted-line. So I'm gonna set the stroke,
we can do the stroke-width. I can do the stroke-dasharray,
which was what? 8 and 8. And to animate it, let's start with
a dashoffset of, let's say, 120. And let's not forget
the stroke-linecap: round, just to make those dashes round. And then let's create the animation. So I'm gonna say @keyframes dash,
and in here, I'm just gonna say to {
stroke-dashoffset: 0. And also, let's do 5 seconds,
linear, infinite, and dash. Okay, so now the animation just
keeps going and going and going.

And if I don't like how it looks like, I can always play around
with the values here. I can increase the stroke with the dashes,
it's a subtle animation. But if I were to make every single
animation here super big and obvious, I think it would be too much. So we're doing a little
bit here with the stars, a little bit here with the location
marker, a little bit with the dashed line. And finally,
let's do a little bit with the four icons.

So travel icons, I would like
these to have a breathing effect, where they momentarily scale up and
then scale back down. So let's do this. Let's target, what was it? icon-bus, icon-plane, and
actually, you know what? Let's add a class here. Let's add a class of
animated-icon to all of these, because it's gonna be a bit
easier to target, right? So, icon-, okay, let's add it here, let's add it here, and let's add it here.

Great, so now, back in CSS, I can
just target that animated-icon class. So what do we do here? First of all, I'm gonna set
the transform-origin to the center, because I want kind of the scale
to originate from the center. And then I want, let's set the keyframes
here, let's add a breathe effect. And here, very simple, 0%,
100% transform: scale(1), and then 50%,
that's gonna be a transform: scale(1.4).

So now let's add the keyframes,
and I'm gonna say animation. Let's go with over one second. Let's do an ease-in-out, and
breathe, and let's do infinite. Now let's add an animation delay for
each of these. So I'm gonna say
.animated-icon:nth-child(2), let's say, so it'll start get
the second one, so animation-delay: 1s. Let's actually do this, 3 and 4, and let's increase this by one second,
like this. Sorry, what am I doing? No, I was wondering why
this wasn't working. This is a class, so
what am I doing using nth-child on that? Here we can just use the ids. So icon-boat, icon-bus, and icon-train, okay, there we go. Sorry, I had a kind of a brain freeze
there, I don't know what happened. Okay, so we're kinda getting
to where we want, kind of.

It's not exactly the effect that
we're after, because I want these, sure, to repeat themselves,
but not like this. So I want the plane to scale up,
boat to scale up, bus, and then train. And then wait a bit,
and then go over again. If I'm using infinite here, the animation
here, sure, will go right the first time. But then it just keeps going on and on. So this is actually something
that we cannot do with CSS. I would like to find a way
to create this repeating animation with a delay at the end, but just like the way I specified,
so This animates than this, then this, then this,
not all at the same time. And for that,
we actually need to restart the animation. So let's do this,
let's remove the infinite from here, and you'll see the animation runs once. And that's perfect,
that's exactly what I want. So now, after a set interval I
want to restart the animation. Unfortunately, we cannot do that from CSS,
we need to use a some sort of JavaScript. So, let's do the following.

Let's collapse this svg, and in the
JavaScript part of our document, I'm gonna create a function called animateIcons
that basically does the following. Let's grab all of those
icons in a node list. So I'm gonna say const icons =
document.querySelectorAll and I'm gonna just going to target
that animated-icon class. After that I'm gonna do a forEach so
icon and I'm gonna say icon.classList.remove, and we're gonna use an animated class. Now the animated class is simply gonna
hold that animation property, okay? So how what are we doing? We're removing the animated
class from each of the icons, and then we're reapplying it.

So icons, again,
forEach we're gonna reapply it. So now let's run it once, okay? And then we need to repeat it every six
seconds, so we're gonna set an interval and we're going to run the animateIcons
function every six seconds, okay? So now it finishes 1, 2, 3, 4, 5, 6 and nothing happens. So why is this? Well, it has something to do
with the document reflow. You see, in order to restart an animation,
you have to force a document reflow. And one of the ways to do that, let's just say here force
reflow to restart animation.

And one of the ways to do that is
to just query like the width or the height of a specific element. So we can do a void here because
we don't actually need this value. We can say document.querySelector() and
let's get, I don't know, the hero section, although you can
get whatever element you want. And we're just going to set offsetWidth,
okay? That's gonna force what's called
a reflow in the document and this will essentially make
that animation restart.

As you can see here every six seconds
that animation just gets restarted. There are better ways of achieving
this with animation libraries, as you'll see in future
lessons in this course. But for now, I just wanted to show you
a pure Vanilla JavaScript approach. So, whenever you want to
restart an animation and removing a class and
then adding it back doesn't work, remember, you have to force a reflow. And something simple like this, like querying the offset width of
an element will do that for you. Just bear in mind that the DOM reflow
operation can be quite expensive, which requires a lot of CPU power. And sometimes it can cause
a bad user experience. So just make sure you use this wisely. Let's take a final look just
by doing that we've now successfully created
an animated illustration. And that's just one of the ways
of animating an illustration.

And we did that with an illustration
that wasn't probably designed to be animated
in the first place. Now if you're aiming for
more complex animations then it's probably a good idea to design your
illustration with that goal in mind. And this is particularly
useful when dealing with, now, let's say cartoon characters or
game characters, okay? So let me show you what I mean by that by
going to practical exercise number 14. Now this is what I want to create, so I've actually done most
of the styling here. Okay, so we're basically choosing
our adventure either It's LUNA or MAX or ZOMBO or RIBSY.

And the idea is that I wanted this
play these cartoon characters and by the way,
you can get these on Envato Elements. And when I select one of them,
I want to animate it, and these are actually animated characters. I have walking sequences,
for all four of them, right? You can see I have individual images,
there are eight items in the sequence. There are basically eight stages of the
walking process for all four characters. And what I did, was I opened
up the Adobe Illustrator file, I grabbed each of the SVGs and
I pasted it in a frame that has the same, the exact same,
width and height. In my case, it's 520 by 880, so all of these have exactly
the same width and height. And the same goes for
the other characters as well. And this is important because
I want these to be consistent when I'm loading them
inside the container boxes.

And then I took this entire group
of images and I export it as SVG. So now, if we take a look back in
the code, and we go to the illustrations, you'll see that we have
a luna-walking-sequence, a max, a ribsy, and
a zombo walking sequence in SVG. Now, how can we animate this? It's actually quite simple and
very, very cool. So let's actually open
up exercise 14 here. And as you can see,
I've already done all of the HTML, we have some card container that
basically has these four cards. And each white card here is represented
by a div with a class of card. And we have an h2 that has
the name of the character, and then a figure which is
gonna hold our image, okay? So let's start styling, let's do this,
let's start with luna, right? And here I'm just gonna set a background
image, and I'm gonna give it a URL, illustrations, and
luna-walking-sequence, save that.

Nothing happens just yet, we need to
select the card figure and give it. Some dimensions, right? Width, let's say 190px. Height, let's say 320px. And let's go with
a background-repeat: none, and background-size: cover. Right, so now our character
completely fills that figure element. Now, let's add the rest of the team. So we're gonna have Max,
we're gonna have Zombo, and we're gonna have Ribsy, cool. Now let's animate them. I want to run that walking sequence, or to animate that walking sequence,
when I select a card. So card with the class of selected,
figure. Now we're gonna set an animation,
let's say to 1s. Let's say linear infinite, and
the animation name is gonna be walking. So let's create the animation.

Here's how we do that. We say to background-position: 100%. [LAUGH] That's it, right? We can wrap it up? No, not exactly. It's still not walking. All this is doing, it's basically animating my
background-position from 0 to 100%. And because I'm displaying this
as a background image, right, it's gonna be confined within
the boundaries of that figure element. Now, this is the stuff that's not working,
it's the timing function. I'm using linear. So obviously it's gonna,
now let's increase this.

It's gonna slowly move that
background position, right? But I don't want that, I want
the animation to just switch instantly, To the next frame, so to speak, right? So I want to switch from this,
to this, to this, to this. That's how you create
the illusion of walking, right? That's how cartoons are made,
or the old cartoons. They were drawn frame by frame by frame,
and then they would quickly switch between those frames to give
you the illusion of movement. So, instead of linear,
we're gonna use steps().

Now, steps() is a timing function that
allows us to break the animation or transition into segments, right? Rather than using one
continuous transition, we're breaking it into segments. And the way to make this work
is you need to specify the total number of frames,
which in our case is eight, right? Because we have eight images, one, two,
three, four, five, six, seven, eight. So the total number of frames or
images minus one. So we're gonna set steps(7). And we're gonna bring
the duration back to 1s. So now,
We have a character that's walking. And it works on this one, and this one,
or whatever it is we selected.

Right, so as a recap, what we're doing here is we're
animating the background position. But instead of using a regular timing
function like ease or linear or whatever, which will create a visible
movement, we're using steps. And steps allows us to break
the animation into segments. Essentially, we're switching
between one of the images to the other without any kind of
visible transition in between. And this allows us to
create this walking effect. So, in this lesson, we learned about
animating illustrations and icons. These can enhance the user
experience if used properly. Animated illustrations and icons can
increase the engagement, catching the user's attention, and often making
them more likely to stay and explore. Animations can also be used for
guiding a user through a process or drawing the focus to certain key elements.

The UX or user experience is
also enhanced when animation is used to provide instant
feedback on actions, like for example changing a hamburger
icon to a close icon on click. Also, a well-animated icon or illustration can make a static page
feel less boring and more entertaining. But do this sensibly because too
much animation can be distracting or even annoying. On the technical side, we learned
that animating an illustration is easily done by first grouping
the relevant elements, then loading the illustration as an inline SVG and
then animating the individual elements. Another option is to set the illustration
as a background image and then animate the background position. This approach works best for
creating animated characters. The key part is to use the steps()
timing function to break the animation into segments. Now, time to move on. And it just occurred to me that I
haven't made a clever superhero reference in quite some time. So how about this? We all know and love Dr. Strange, right? But what's the one thing
that makes him stand out? It's the nose, right? No, I'm just kidding,
it's the cape, it's the red cape.

No other character has
a cool cape like that. Well, apart from Thor, Superman, Supergirl, Magneto, Batwoman? Anyway, Dr.
Strange's cape is way cooler, it can fly. It's almost like it has a life of its own. Now, the reason I brought
it up is that Dr. Strange's cape is an accent
piece in his wardrobe, okay? Similarly, animations can
be used to the same effect, to draw attention, right? You can use accent animations
to draw the user's attention to a specific part of the page. In web design,
accent animations are small, purposeful animations that
enhance visual storytelling and user experience without
being the main focus. They're like the spices in a dish,
not the main ingredient, but essential for the flavor. That's why I mentioned Dr.

Strange's cape. Is it the main thing? No, but it adds to his awesomeness. Can Dr. Strange be a powerful
superhero without the cape? Sure, but it's not the complete picture. Now, before we move on,
I just wanna make a quick note. The animation types we're
exploring in this lesson, loading, accent, interactive, They're not locked into
these unique categories. So for example,
a loading animation can also be accent, or a scroll triggered animation
is also interactive, right? So if you see a loading type animation
being used in the accent lesson, it's okay,
don't get too hung up on labels.

I'm kind of categorizing
these animation types based on their primary function,
but in the end, they all belong to this bigger
picture of motion design, got it? All right, now, we were talking
about accent animations, and here's what you would
typically use these for. First, to direct attention, to guide
users to important elements in the page. For example,
if we go to ShipDaddy's website and scroll all the way to the bottom, we can see this simple illustration
of the character just pointing up. And it's drawing our attention
to this area right here, which basically allows us to go
to the contact page or something.

Very simple, very cool. If we go to Feedly, and again,
we scroll to the very end, we have the robot-looking
character doing a very subtle animation that basically waves at us,
drawing our attention to this footer area,
which is basically a call to action. Next up, we go to the embacy.io website, where they have these cool
handwritten animations, and we also have a drawn arrow
pointing to some important links, like Behance here or
to the Figma link right here. Very easy to do, and
they have a great effect. Next up, let's go to Vool Studio,
where on the top left, we can see a simple movement, really, in the header,
where they dynamically change these words to probably
showcase their services. And also the Vool site has a cool
animation here in the footer of the logo, which changes periodically.

Again, drawing our attention
to this area right here. And finally,
we're visiting the liftoffcourse.com, where they are using a typewriter
effect in the hero area. Again, drawing our attention
to this H1 element. Accent animations can also be used for enhancing interactions
by providing feedback. As an example,
we're visiting Dennis' website, where, if we hover on a specific button, yeah, It gets a nice movement,
a nice accent animation. It's just subtle, but it's there and it's present on all of its buttons,
pretty cool. And then if we go to
the Moxion Power website and we scroll all the way
down to the testimonials, we can see we have some very
subtle effects on hover. So here,
it changes this background element. It also rounds off the corners of
the card just a little bit more, like so. And it also transforms this
dot into an arrow, basically. Pretty cool. Subtle, but very effective in
enhancing the user experience.

Finally, accent animations can
be used to improve usability. By visually signaling what
can be interacted with, they can make interfaces easier to use and
more intuitive. And we go back to the Dogstudio website,
where we see on the bottom right, a very simple ripple animation
on this dot here, and this is actually for
toggling the sound on and off. It's a very subtle animation,
but one that's very usable, or one that increases the usability. Because when you open the website and
sound is playing, you're like, okay, hold on, where is this coming
from and how can I turn it off? And by visually doing these
ripple effects, like sound waves, you can immediately see, okay,
this might be a toggle of some sort. And you click and the sound is off. All right, so we saw how accent
animations are being used out there, but how exactly do you create some of these? Well, let's find out, starting
with practical exercise number 15. For this demo,
I would like to animate this logo, right? And it can be used in
many different places.

I showed you a few examples
earlier where Vool, for example, had the logo in their footer and
it had a simple animation, or you could use this as a page loader. It really depends on the effect
that you want to get with it. For me, personally,
I would like to use this as a page loader, so I found this very simple
logo on Envato Elements, and I went ahead and
recreated it in Figma. So what I have here is
basically three paths. We have this middle path,
which is an elongated circle, if I may call it like that,
and then two halves, one on the left and one on the right. So what I'm gonna do
is simply select that, make sure it's exported as SVG,
and make sure this box here is checked to include the ID
attributes from the layer names.

And then I can simply copy as SVG, and I can jump into my code editor,
and I can paste it right here. And as you can see, we have a group here,
we can get rid of this. And then we have a rectangle with
an id of middle, path, right and left. And there are a couple of things that
we can do here to simplify this. So stroke,
let's actually change this to black, and I'm gonna remove the stroke-width. Let's do the same for the paths and also
the stroke-linecap, so let's remove those. So now all we're left with
is just the rectangle, the paths, with a black stroke. And if we want, we can also just
remove this, we don't need it. Okay, so checking our page here,
this is what we have. So let's animate this,
but, This time I'm gonna introduce you to one of
the coolest JavaScript animation libraries out there, and
that is GSAP, right? So with GSAP you can basically
do animations like this, and it's super powerful, super easy to use.

And in fact,
we're gonna use GSAP from now on for the rest of this course to
create the rest of the demos. Now, the way I want to animate
this is we have this middle piece. And I want to kind of scale it up and
rotate it and then from it, I want to start drawing
the rest of these shapes. I want to draw the left side and
then the right side, okay? And it's not just gonna appear,
it's gonna be drawn. It's like you would take a pencil and
draw it. So for that, we need two things,
we need the core GSAP library. So that, we can take from CDN. So let's grab it from here and
we'll paste it right here. Okay, let me zoom in here a little bit. And finally,
we need a plugin that's called DrawSVG. Now, DrawSVG is a paid plugin, so you would need to sign up to
use it in a real project. For this demo, we can use a trial of it.

So just use this link if you wanna use
the plugin, just to test things out. And then finally, we're gonna write,
oops, this is not CSS, so we loaded GSAP, we loaded the DrawSVG plugin,
now we're ready to start animating. But first,
let's write just a tiny bit of CSS, because I wanna target
the rectangle in that SVG and also the path to set a stroke color. And we're gonna use 100319 and also a stroke-width of 20, and also let's do a stroke-linecap round. Okay, so this is what we have so far, it's very, very similar to our logo here.

Now, let's animate it. So the way GSAP works is super cool. So you can use the GSAP object and
a couple of methods like from, to,
set, and a few others. So for example, I have this SVG,
let me give it, Or actually let's target this middle part,
yeah. Let's say, I wanna set
the middle part to scale to 0.5, and this just scales it down
to whatever value I set here, and this is the general syntax. You specify the target, and then you pass in an object with all
the changes that you wanna make. And you can do scale, you can do x: 20 and that's gonna move it to the right
20 pixels, and a few others. We'll discover this as we move on.

But here's how we create
an actual animation. Let's say I want to scale
up this middle part, right? So by default, I'm gonna set it to 0, and I'm gonna set its transformOrigin to 50%,
50%. So then I can say, gsap.to, again we're
gonna target that middle element, we're gonna pass in an object
with the following properties. I want the scale to be 1,
I want the rotation, is actually correct,
rotation, 360 degrees. And let's give it
a duration of 1.2 seconds, so now watch what happens.

That's gonna animate the middle
from whatever was set before, either with GSAP or just from
a regular CSS to these properties. To scale: 1, rotation: 360,
over 1.2 seconds. So it's that easy to animate with GSAP. And GSAP, what's really cool about
this is it has a bunch of easings. So if you search for easing, In the docs here,
you can actually see a visualizer, and there are a bunch of branches to choose
from, elastic is a pretty cool one, right? And you can click this
again to see a preview.

And if you want, if you like it,
you can actually copy this and you can paste it in your code. In my case,
I'm just gonna say elastic.out. So now, The animation looks like this. You can see that this is getting
a bit cut off because it scales a little bit past the viewport, but
we can easily fix that by saying, svg {overflow: visible}, Right? How easy was that? And now we can keep going and
animate the rest of the elements. But here's one of the coolest things
about GSAP, you can use timelines, and a timeline is basically
a sequence of events. So let's create a timeline ourselves. So we're gonna say var or let or
whatever, let's do let tl or whatever you wanna call it, gsap.timeline. Okay, and
we can pass in an object of properties.

For now, we'll leave this blank. So, here, we actually worked on the middle
rectangle, so we scaled up and we rotated. But instead of doing gsap.to,
let's use the timeline. So I'm gonna say timeline.to, and by doing
this we're essentially adding this tween, this animation to the timeline. Now, the events that are placed in
a timeline happen or take place in order. So this will happen, then the next event
will happen, the next one and so on. So now let's animate
the left handle drawing. Now, here we're gonna say tl,
the timeline, and we're gonna use something called a fromTo method and
we're gonna target the left one.

Now, fromTo receives two parameters. The properties that should be
set initially, that's the from, and the properties it should
be animated to, okay, fromTo. So I want this left
handle to go like this, drawSVG: '100% 100%'. And then to, drawSVG: '0% 100%'. And I'm also gonna set a duration,
let's say 1.2 seconds. As for easing,
we're gonna use power4.inOut. So let's see what we got. So the middle part animates and
then the next animation in the timeline happens where
we draw the left handle. Now, what exactly is up with
these percentages, right? 100%, 0% So, when dealing with drawSVG, these values describe the stroked
portion of the overall SVG element. So, in my case, 0% to 100% will
render the stroke between 0 and 100, so it will render the whole thing.

If I were to set this 20% and 70%, it will only render
the stroke between 20% and 70% of the total length of that stroke,
okay? Or if I were to do between 40% and 50% that will only generate it
between those percentages, okay? So the way I'm doing it
here is that I'm starting from the end because this
is on the left side and when animating a stroke,
it goes left to right, right? It goes like this. So if I were to animate this from 0% 0%, it would animate it from here, okay? But by setting it to 100% 100% it means
the starting point is at the end, okay? So it starts to animate it from here, it basically does the animation
kind of in reverse. Right, so the end position is to
draw the SVG between the 0 and 100% point, and
I'm doing that over 1.2 seconds, and I'm using a custom easing. So the effect is this, it goes from here
to here, so I hope that makes sense. Now, let's see about the right handle, and the right handle we're just gonna
duplicate this code, we're gonna animate the right handle drawing, so
we're gonna target the right side.

Now we're gonna animate from 0,
0 to 0, 100. Okay, so now we animate the left and then we animate the right,
that's pretty awesome. Now, how about we also change the color? Because in the figment design,
we have a different color here at the end. We can easily do that with GSAP, we have
a timeline, so let's change the color. And let's say timeline to and
this time, we're gonna select middle, left, and right, so
I can select multiple elements. And we're gonna pass in
the object that says stroke is gonna be equal to
A41FF6 with a duration of, let's say, 0.4 seconds. So now, this animates, left animates,
right animates and then I change color. And now finally, what if I want
to repeat this over and over? Well, we can go to the timeline, and
we can pass in some parameters there. I can say repeat, let's say two
times that's gonna repeat once or it's gonna execute once. And it's gonna go again and
again so it repeats two times if I wanted to repeat
indefinitely I can just say -1.

And now this will just keep going and
going and going. Now, what's nice about GSAP is
that you can add a repeat delay between these animations. So you can say repeat delay,
let's say 1.6 seconds. So now it's gonna run the animation, it's gonna wait 1.6 seconds and
then repeat it. But what if I want the animation
to run in reverse, like alternate between
forward direction and reverse direction, like we have in CSS? We can add another parameter called yoyo,
yoyo: true. So now,
it's gonna run the animation normally, and when it reaches the end,
it's gonna do it in reverse. And then it starts all over again. Now, one of the examples I showed you
earlier in this lesson was a typewriter effect, where you would dynamically
change one or two words in that sentence. So let me actually show you how to create, that typewriter effect with GSAP
in practical exercise number 16. Now, this is the stuff that
we're trying to create, we basically have this big title,
big headline in the hero area. And I wanna change the last word, right? You can see we have a cursor here, I
wanna change that at a set interval with, of course, a typewriter effect.

Where each letter at
a time gets deleted and then when it reaches the end,
it gets replaced with another word. So to do that,
this is what we have currently, in our page, and
if we take a look in our code here, we can see that the h1
has a span inside it for that word that is about to be changed. Now we're actually gonna comment this and
we're gonna change it with something else. So we're also gonna have,
or we're still gonna have an h1 however,
we're gonna have two spans, right? So one, we'll have the ID of typewriter,
and it's gonna be blank, and the other one is gonna
be have an ID of cursor, and we can just put like
a pipe character in there.

Save that and So
that's the HTML part taken care of. Now let's animate it, and
again, we're gonna use GSAP. So we're gonna click here, get GSAP,
we're gonna click get, from CDN, and we're gonna also use a plugin here,
the text plugin, right? So copy this and let's go down here, paste it in, and let's start animating. We're gonna define a constant for
the words, and that's gonna be an array
that looks like this, boldness, clarity,
originality, and precision.

Next, we're gonna create
the main timeline, so let mainTimeline = gsap.timeline, and let's actually make this
repeat indefinitely. Okay, so here's what we're gonna do. For each word, we're gonna create a new
timeline, we're gonna use the text plugin, and we're gonna append that timeline to
the main one, you can do that in GSAP. So we're gonna say words for each word, we're gonna create a new timeline,
we're gonna use the text plugin, and we're gonna append that timeline to
the main one, you can do that in GSAP. So we're gonna say words forEach word,
we gonna create the text timeline and that's gonna be equal to gsap.timeline and we'll leave this blank for now,
so now animating the actual word. We're gonna say textTimeline.to, we're gonna select the typewriter span and
we're gonna pass in the following.

I want the text of it to be the word so the one that we're getting from the array,
we can also set a duration, let's say 1 second, and
then we can say mainTimeline. .add(text) timeline. Okay, so it kind of works, but
it's not the effect that we're after. So let's do this. In the mainTimeline, or
sorry, in the textTimeline, I want this to repeat just one time. And I wanted to go back and
forth, so yoyo: true. Okay, so now it types the word,
then it deletes it. And I also want a repeat delay of,
let's say, six seconds. And these six seconds is the time between the word is typed and the word is deleted.

So GSAP types the word, like so,
it waits six seconds and then it wipes it, Like this. And that's really all
you have to do with it. Just by using the simple
approach with two timelines, you can create a typewriter
effect with GSAP. Now, there is still the issue
of the cursor, right? The cursor, typically,
whenever you're typing text somewhere, the cursor is blinking. All right, so let's add a blinking effect. Now, we can do that with CSS,
and it's quite easy to do. So in CSS,
we would do something like this. Let's select @keyframes: blink. So for the blink,
we're gonna set on start and end, opacity: 0, and at 50%, opacity: 1.

So then we're gonna target the cursor and
we're gonna say animation. Let's do it over 1.2s, infinite, and the animation is called blink, right? So that's what it looks like. But a regular cursor doesn't
just show its opacity, it doesn't just fade in and fade out. So instead of using a default timing
function, we're gonna be using steps(1). And this is basically just appearing,
disappearing, appearing, disappearing. Okay, that's an easy way to
create a blinking effect in CSS. But here's the thing that I don't like. The cursor blinks even when
the text is typed or deleted. And on pretty much any text editor,
the cursor is always visible when you're typing or
when you're deleting, okay? So how do we do that? How do we tie in this animation
with what we're doing in GSAP? Well, short answer, we cannot. So how about we ditch this
animation from CSS and we replicate the blinking
animation with GSAP? So that goes something like this. I'm gonna say, Blinking cursor.

So we're gonna create a cursorTimeline, and again,
we're gonna repeat it indefinitely. And let's add a repeat delay of,
let's say, about .8 seconds. So what do we do? We say cursorTimeline.to,
we're gonna target the cursor and we're gonna do the following. We're gonna say,
opacity: 1 and duration: 0. And then we're gonna chain
another to method on the cursor, where we're gonna set the opacity to 0,
duration: 0, again, this is very important, and
we can set a delay of .8. So now, we get the same blinking effect,
but with GSAP. So let's see what happens here. First of all, we have a timeline, right? So these two events happen in succession. First of all, we're setting the opacity
to 1 and the duration to 0. This basically removes any kind of
transition between the two states. And then the next animation
is to set the opacity to 0. But to simulate the time
between visible and invisible, we're setting this delay to .8 seconds. Easy enough, right? So now we replicated
the cursor animation in GSAP, but how do we tie it into
our original timeline? How do we make it that the cursor stays visible when typing or deleting a word? Well, that's when we can
go to the textTimeline, and we can tap into some events, for example,
onUpdate, and we can pass in a function.

We can say, take the cursorTimeline, restart it, so
the cursor remains visible, and then pause it, so it stays like that. And when the text timeline is complete,
so we can say, onComplete, we can say,
take the cursorTimeline and play it. So now, when the word is typed or deleted, the cursor will remain visible. After that,
it's blinking animation is resumed. How cool is that,
that you can do stuff like this with GSAP? I meant with JavaScript. And GSAP allows you to
do a whole lot more. And the fact that you can restart, pause, play a timeline anytime you want is super,
super powerful. Now, before we wrap up this lesson, there
is one more example I wanna show you. And we're gonna use the same demo. And this time,
it's just gonna be a CSS thing. So notice the element here,
we have Our Work and then an arrow down.

And let's say I wanna turn this arrow,
I wanna animate it, just to kind of bounce up and down and show me that, hey,
you can scroll down and see more content. This is also a type of accent animation,
right? So I wanna do that, but I also want to
simulate a delay between iterations. As we know, in CSS, if you've been paying
attention so far, I said that in CSS, you cannot add a delay between
the iterations of an animation, right? So if you have a breathe animation,
you can set a delay and it's gonna be executed on the first run. But after that, if you set it to infinite,
the animation will just keep running and running and running. Well, there is a CSS method of
simulating a delay between iterations, and I wanna show it to you right now. So let's start by going to
the CSS part of our page here, and I believe it's called #our-work, and I'm gonna target the SVG,
so this arrow here.

And I'm gonna say the following,
animation, I want it to run over 5 seconds. Let's do [COUGH] ease-in-out for
now, infinite, and I want the animation to
be called point-down. So now,
let's define @keyframes point-down. And let's create it in such
a way that it simulates a delay between iterations, right? So for example, let's do this,
0%, so the starting point, it's gonna be a transform: translate3d(0,
0, 0). And at 100%, I want this to be transform: translate3d(0, 1rem, 0), okay? So now, if we take a look at
the animation, the arrow is pointing down, it's going down, and
then it comes back up. But I want this to repeat at an interval,
right? I don't want the animation to start
right away after it's finished. So to do that,
we can say something like this. 10%, 40%, and 100%, and here let's swap this to 25%. So now, let's look what happens. See, there is a delay between when the
animation ends and when it starts again. So how does this work? Well, basically,
I said here that in the start and in the end, I want the arrow to
be in its original position, but also at the 10% mark and
at the 40% mark.

And then only animate it,
only change its position at the 25% mark. So what happens is, the animation
itself takes place between 10% and 25% of the total animation duration,
right? This is what it refers to. So the animation starts,
when it reaches 10% of its duration, it starts animating from this to this. It's gonna finish animating when
it reaches 25% of its duration. From that point between 25% and 40%, it does it in reverse, right? It goes from this to this. And then from 40% to 100%,
it's still in its default position, so it doesn't do anything, okay? So if we set this animation
to run over 10 seconds, right, you'll see the animation takes
place between 1 second and 4 seconds. And at 2.5 seconds,
it's gonna be down here. For the rest of the time,
it's in the default position. But let's change this back to 5s. So now,
just to spice this up even further, how about we add a custom easing to it? Because we have a couple
of easings defined in CSS, we can do stuff like a linear, which
will have no acceleration or whatsoever.

We can have the ease,
which looks something like this. Or we can add a cubic-bezier,
and there is actually a really cool website
called cubic-bezier.com, where you can actually
create your own curve and you can actually preview it, right? So the blue one is one of the standard
ones, you can select from here. And the purple one, or
whatever color is this, yhe pink one is the one you're creating. You can change the duration here as well,
okay? And the one we're gonna create
looks something like this. So we're gonna go all the way down here,
something like this, and we're gonna take this handle and
bring it all the way down here. So we're gonna say maybe
something like this, and a bit further down,
something like this, okay? So now, if we compare,
ours is the pink, Right, so when it starts, it actually backs
up a little and then accelerates, and then it overshoots a little bit, and
then comes back to its original position.

Right, so we can copy about and we can replace ease
with our custom bezier. So now, Our arrow will look like that. And it's just a minor touch, but it's yet another example of an accent animation. So in this lesson,
we learned about accent animations and how these are the thoughtful touches that make
a website not just usable but enjoyable. They're like the spices in a dish,
not the main ingredients, but essential for the flavor. We learned that accent animations can
be used for guiding users to important elements in the page, for enhancing
interaction by providing feedback, and for improving usability by visually
signaling what can be interacted with. We also learned about a really cool
JavaScript animation platform called GSAP, which stands for
GreenSock Animation Platform. With GSAP,
you can animate anything you want, but also create timelines,
which are basically animation sequences.

We learned that creating custom easings
is super simple with tools like cubic-bezier.com, which allows you
to create custom easing curves. And finally, we discovered
that you can create a pause in a looping CSS animation by
adjusting the keyframe percentages. This trick extends the time
an element stays still, giving a delay effect without extra code. So that wraps it up for accent animations. Next up, we're gonna delve into
what I consider to be the most popular type of animation,
and that is interactive. In a nutshell, interactive animations
respond to user input like clicking, hovering, or scrolling, and
they're not just for show. Here are four reasons you
should be using them. Number one, enhanced user engagement. Interactive animations capture attention. By responding to user inputs,
they create a dynamic experience that keeps users engaged and
interested. Let me show you some examples. We're here on Dennis's website, and I showed you this before,
but this still applies. Hover is an interaction, right? So when I hover on this button,
the button responds. And it actually follows my cursor around,
which is really cool.

And these do as well. And also, these,
the portfolio items, right, as soon as I hover on them,
they respond to my action and they create this really cool movement. Then let's go to Apple's website for
the iPhone 15. Now, as we scroll down,
we have the ability to switch here between the 6.1 In the 6.7 inch, and
this creates a nice animation. This is also an interactive animation
because it's triggered by a user action. And the same thing goes for changing the color even though this
is not necessarily an animation. Number two, better storytelling. Interactive, or more specifically, scroll animations can be
used to unfold a story or to reveal information in
a more controlled way. And the idea is as the users scroll,
they're taken on a visual journey which makes
content more memorable. Let's look at the runway website. As we scroll, things start happening,
they start animating. We can see some of the features in here,
we can see presentations of the product.

And as we continue scrolling,
as I was saying, a story unfolds. It tells us what Runway is,
and it takes us to the various chapters
of their presentation. And it's all animated,
which makes it super, super cool. Here's another example. As we scroll down the site,
besides the nice draw animation, again,
we can see a story unfold. Where the various sections of the website, all the presentation stuff is
revealed to us in a very nice, memorable way, and
it just keeps going until the very end. Apple is also doing a great job with this. For example, this is the website for or
the web page for Apple Watch Series 9. And as we scroll down,
you're gonna see a story unfold which is gonna tell us everything we need
to know about this new Apple Watch. And we get to see the various features of the watch in a nicely animated way. Apple does this for a lot of their
products, which is fantastic.

You see, interactive animations can
make a website feel more lively and personal which can be crucial for
brand identity. It also means that
websites stands out from the sea of static pages
we come across every day. And we're gonna look at the Dogstudio
website again because the interactive animations here made this website
instantly memorable for me. From the way the dog animation
reacts to my mouse movements, or the scrolling on a page, or the way it changes the colors
when I hover on these links. So everything,
all of these things combined, made this a super enjoyable experience for
me but also a super memorable one. If you ask me in a year's time,
how did the website look like, I can describe it to you with
80% accuracy, let's say. But yeah, it's gonna stick in my mind for
a very, very long time. Plus this created an emotional
connection with me because of the name, but also this beautiful animation
here because I'm a dog lover myself. So whenever I see something like this,
it hits a nerve, so to speak, in the best way possible.

Plus, this website ticks the other two
boxes as well with the user engagement and the storytelling, so overall,
yeah, really, really cool stuff. Using animations like this
truly goes a long way. Number four, increased time on site. This type of animation can increase
the time users spend on your site because they encourage exploration and
interaction. Let's take a look at
the Hyperframe website. Now, from what I understand, this is a
steel framing system that snaps together, and I got that from the text right here. So, basically, when we scroll down, we get a super nice animation that
shows us how this system works, okay? And of course,
as we scroll further and further, the whole story unfolds, it shows us
even more of how the system works.

And you also have this type of
interactive animation where we don't have to scroll but
instead we can drag, To see how those two pieces fit together. And honestly,
these features make me personally want to spend more time on this site,
playing around with them and seeing these awesome 3D animations. Okay, so we've seen how real
websites use interactive animations, how about we create some of our own? Enter practical exercise number 17. Now for this demo, we're gonna go back
to Dennis' website that was featured so many times in this course that
you're probably sick of it.

But regardless,
I feature that for good reason. It's an awesome website and
it has some pretty slick animations, like this one, for example. So in this demo, I'm gonna attempt to recreate this mouse
follow effect on hover. Now when doing this, I actually took a sneak peek into
the code that Dennis wrote, and we can find that if we go to the assets,
the JavaScript.

And if we search for magnetic, okay, these are what Dennis
calls magnetic buttons. And he got inspiration from
this codepen right here, okay, you can see the address right there. And I took a sneak peek at Dennis'
code now to see how he did it and then I adapted that to my own design. So if you want to, go ahead and
check out his code, otherwise, let's jump to our own exercise and
create our own magnetic button. So the first thing to do is
to create the button itself. And for that,
we'll go right here under the h1, and we're gonna add a button
with a class of magneto. I know, very original. And inside, we're gonna put a span, and we're actually gonna give it a class
of text, and we're gonna put the text. Our work, actually, not our text. And then below that I'm gonna use
a div with an id of debugger, and you'll see why we need
this in just a little bit.

So that's all the HTML
that we're gonna need. So taking a look,
we have a standard button. Let's go ahead and
apply some default styling for that. So I'll say magneto, and
let me zoom in here a little bit. Let's give it a width. 10rems, height 10 rems,
because I wanna make a rounded button. Let's give it a border-radius of 50%,
and let's remove the border. And let's set a background-color, and I
have a variable already defined for that. Let's set the color of the text to white. And let's set a cursor to pointer.

Great, so now the button looks like this. So basically, I want to achieve
the same effect as Dennis here. So the effect goes like this,
it follows or its response to
the movements of my cursor. And when I hover on it,
the button itself kind of follows my cursor at a certain rate,
and then the text inside the button also follows the cursor but
at a slightly higher rate. So the text moves a bit
faster than the button, okay? And when we hover out, the button kind of just snaps back
into its original position and it's using a sort of elastic
easing curve there, okay.

So for that, let's go to, right here,
and we're gonna use gsap. If you don't know how to install gsap, check out the previous
lesson I showed you there. We're not gonna use any kind of plugin,
just plain old GSAP. So, first of all, let's get our button. So, we're gonna to create a constant,
magneto, document querySelector. It's actually our class, magneto, okay. Next, let's get the text.

So, magnetoText, and
we're gonna grab that span. And finally, let's do the debugger. I'm gonna call it, dbgr, okay. So now let's do the Mouse move stuff. So what happens when we move
with our mouse cursor, yeah? We're gonna create a function
called activateMagneto and we're gonna pass in the event. And then, we're gonna work on
the Mouse leave stuff, or what happens when we mouse out, or the mouse cursor
leaves the surface of the button. And in this case, we're gonna do
a constant called a resetMagneto and that's also going to be event. Okay, so we have two functions. Now let's attach some event listeners. So I'm gonna say magneto addEventListener. For mousemove we're gonna activateMagneto,
and then for mouse, sorry,
leave we're gonna resetMagneto.

Okay, so now, let's see what happens
when we move over the button. And this is where the debugger comes in. So the debugger,
let me just go to the CSS and remove this display none property. So we can actually see it on the page,
right? The debugger is just a black
box here in the corner that's gonna display
some numerical values for the position of the cursor, the position of the left side
of the box of the button. The position of the cursor inside
the button, and a few others. Because here's what we need to do when
we move our cursor over the button, we need to shift its position relative
to the position of our cursor, okay? In both axes, both on the horizontal
axis and on the vertical axis.

And for that, let's first start
by defining some variables and some constants. So, first variable is
gonna be the boundBox, and that's gonna be equal to magneto or magneto.getBoundingClientRect. So this function gets
the position of magneto on the page along with its width and
its height. Then we're gonna create a variable
called magnetoStrength. We're gonna put it at 40 and one for magnetoTextStrength, and
we're gonna put it at 80. We're gonna be using these variables,
and we can actually, you know what? We can set these as constants. We're gonna use these to
define the rate of movement in relation to the position of the cursor,
right? We're gonna be using them as multipliers,
you'll see that in just a little bit. Now this is where it gets
tricky because when we move with our mouse cursor,
we need to calculate a new x position that the button and
the text will move to. And of course, a new y position. Now how do we calculate those positions? Well, this is where
the debugger comes in and is just gonna help me explain
things a little bit better.

So, let me just paste in some code, and let me show you what it's
doing on the page, okay? You'll see that when I
hover on the button, most of the numbers in
that debugger will change. Let me see if I can make this bigger,
okay. So first of all, it changes
the position of the cursor, okay? And this is the position of the cursor
on the x-axis on the page, okay? So right now the cursor is positioned
at 768 pixels on the x-axis.

The next value is the left
side of the box or the position of the left border of
our button in relation to the page. So our button is positioned at 688
pixels from the left side of the page. Then we have our third value, and our third value is the cursor position
inside the button and how do we get that? We subtract the position of the cursor,
the clientX, or sorry, we subtract the left position of the
button from the position of the cursor. And that gives us the position in
pixels of the cursor inside our button. So as you can see right now it's at
0 because I'm at the very left edge, and as I move it forward, we get to 160. And 160 being the 10 rems
width we set in the CSS, okay? So this works perfectly. Next up, we change that position
to be relative to the total width. So how do we do that? We do basically the same thing as above,
but we divide it by the total
width of the button.

So now if you look here,
it gives me a value between 0 and 1, okay? Of course, I can reach 1 if I
position it exactly at the edge here, but you get the idea. So that's how I'm doing this. I'm taking the cursor value, or the cursor position inside the button
that we calculated earlier, and I divided By the total
width of my button. And so this one is just to specify
how many decimal points I want.

And now the next one,
the one called shifted, basically does the same thing but
it subtracts 0.5. And what that's doing is it allows me to
calculate the position from the center. So as you can see, if my cursor is
right in the center of the button, the shifted position is 0. If I move to the left,
it's gonna get me to -0.50. If I move it from the center to the right, it's gonna get me to 0.50,
or close enough. Now, I told you all of this
because this shifted position is basically how we calculate the newX and
the newY. So let's go ahead and do that. Here, in the constants, let's define newX as event.clientX, so this is the position of
the cursor on the x-axis, minus boundBox.left, okay? We take this and we divide it
by magneto.offsetWidth, right? So by doing this, we're basically getting
the relative value of the cursor, or the relative position of the cursor,
to the total width of the button.

And then we take these,
and we subtract 0.5 to get to this last value,
the shifted position. And we do the same for the newY,
except here it's gonna be clientY- boundBox.top, and
the offset is for the height. Okay, so now we got the new coordinates, or I should say the new values for
X and Y. So now we can go in here and
we can use GSAP to move the button and the text to its new position. So we're gonna say move
the button to its new position.

So we're gonna say gsap.to,
we're gonna target Magneto. And we're gonna say the following,
duration, let's say 1second, and
I'm gonna move the x to newX, y to newY. And also let's add an ease, and
that ease is going to be Power4.easeOut. And let's do the same for the button text, magnetoText, newX, newY, same easing. So now let's give it a go. We can start seeing
a little bit of movement, even though it's super, super tiny.

And that's because the values that we're
using for the movement are super small. And this is where these
two constants come in. As I said earlier,
we're gonna be using these as multipliers. So now,
instead of saying move the button to newX, we're gonna say move it to newX times
magnitoStrength, same for the y. And then the text is
gonna be multiplied by magnetoTextStrength times
magnetoTextStrength, save. And now,
the movement is much more visible because we're using that shifted
value that we calculated, and we multiply it with what we had here,
40, 80, right? If I'm gonna change this to 400, that's
gonna be a much bigger movement, right? That's gonna follow our button even more. But for the purposes of this demo,
I'm gonna keep it at 40. Now, something weird is happening here,
right? Our button, sure, it moves up and down and left to right, but
our text moves along with it. And to fix that, what we need
to do is set our display to flex inside the button, and
then just center everything.

So justify-content: center,
align-items: center, save. And now, we get the effect that we want. So what was happening is that,
the text was not moving on its own. There were, right, transforms,
you can see them right here, there are transforms,
translate3d to be exact, being applied to the button
as well as the text. But before we applied display flex,
it wasn't working. And you could achieve the same effect if,
for example, you set the text to be
positioned absolute.

I'm not exactly sure why this happens, but I have a guess that it's probably
because display flex, position absolute, and stuff like that, just creates a new
stacking context for the elements. So by setting, in this case, display flex, we're allowing that text
to become a flex child, and we're allowing it to be transformed
independently from its parent element. So that's how this works, basically. We're calculating those new coordinates,
and they are being applied in real time as we're moving,
Above our button. They're being applied as translate3ds
on the x and the y-axes. That's great. Now, what about when we leave the button? Because currently,
it stays exactly as it was. So let's work on
the resetMagneto function. And this is pretty simple, we just need to
move the button to its default position.

So we're gonna say gsap.to magneto, duration:1, setting the x to 0, y to 0. And for the ease,
we're gonna be using Elastic.easeOut. Again, if you wanna learn
more about easings in GSAP, they have a complete separate section
in their documentation, okay? So that's for the button,
let's do the same for the button text. So magnetoText, same thing, duration: 1,,
x, y, 0, and the same easing. So now, save, and
as soon as we leave our button, oops, it pops back into place. [LAUGH] Adds a really cool effect,
I really like that. And yeah, it took a little bit of
calculation to get it to work. So I hope this made sense,
what I explained here. If it didn't,
please leave a comment down below and I'll try to explain it in a different way.

Now, earlier in this lesson,
I mentioned scroll animations and how they can help you tell a better story. Or actually tell the same
story in a better way. And I showed you some
really cool examples, but how exactly do you create
something like that? Well, let's find out in
practical exercise number 18. And this is the demo we're
gonna be working with, it's a simple page that has some
gallery entries, basically, or some portfolio items,
I guess you could call them. And, as you can see,
it's a totally static page, except for the occasional transition here and
there, but we just scroll, we see the content, and that's about it. How can we add some more life into this? Well, what I would like to do is have
these portfolio entries animate on scroll. So when I scroll down, I want
the image to slide in from the right, I want the text here to
slide in from the left. So, they will only reveal
themselves once they are into view. And when I scroll back up, I want the same
animation to run in reverse, right? This one, the image is gonna slide out and the text is gonna slide out
in the other direction.

Now, there are a few ways to do this,
and I'm just gonna mention two of them. CSS @scroll-timeline is
a great option that allows animation to be driven by
a container's scroll position. So it's a great addition to CSS
except it's not supported anywhere, it's an experimental feature
which can be enabled in Chrome. So this is out of the table for
now, right? In November 2023,
this is not yet supported. The other option which is
supported in a lot of, or in all modern browsers,
is the IntersectionObserver API. This is used with JavaScript and it basically gives us a way to
tap into the visibility and position of certain elements
relative to the scroll position. But we're not gonna use this either,
instead, we're gonna use GSAP because
GSAP has a plugin that's called ScrollTrigger,
it's this one right here. And that's gonna allow
us to perform actions to run animations that are based on
the scroll position on our page. But before we implement GSAP and
this very cool plugin, let's first talk about smooth scrolling,
and as you can see,
this page scrolls just in a normal way.

But that's not enough if we wanna create
a really cool experience for our website. We need to add some sort
of smooth scrolling, and to do that,
we can use a library called Lenis. So if we go to lenis.studiofreight.com, we can see that Lenis is
a new smooth scroll library. And you can see it being
applied to their website, of course, essentially this makes
the scrolling experience much smoother. I'm not sure if you can see it on video,
even though it's recorded in 60 fps, but if you see it in real life,
right, compared to this or compare that with this and the way
the scrolls, yeah, it's a big difference. I think you have to try it for
yourself to see exactly how it is. But let's go to GitHub, and
here it's actually really simple to use, you just copy the script and
you paste it in your code. And let's actually go to exercise 18 here, and let's go all the way down here. And I've actually already
included here Lenis, and I've already included GSAP and
the ScrollTrigger.min plugin.

Now, there are two other components
to make this work perfectly. First of all, you need to include
this basic setup, right, for JavaScript, so let's do that here,
let's say, Lenis smooth scrolling. And we're just gonna paste that in, we
don't really need this console.log thing. And then if we scroll down, there's also a recommended CSS we can use and
we can paste that in, we can say lenis.css,
and just paste that in. And also there is a GSAP ScrollTrigger
integration, the one that we're gonna use, so we're actually better off copying
this instead of the basic setup here. So in the JavaScript,
actually delete this and paste in the one that's
made specifically for GSAP. So now if I scroll on this page,
that's much better, I can already see the difference, I'm not sure if you can do it too. But there's sort of an easing
when the mouse wheel stops, it's like it's not coming to an abrupt
stop, it has an easing to it, and the whole thing is just much,
much smoother.

So whenever you're doing
animation projects, I highly recommend you get this library. It's pretty small,
it doesn't affect your performance in any significant way, so just get this. All right, so with that out of the way, let's see how we can implement GSAP
to animate those portfolio entries. First of all,
let's have a look at the HTML structure, each portfolio entry Is placed
in a div with a class of entry. And the text is inside entry__meta, the image is inside a figure
with a class of entry__media. So, with that in mind, let's start by
getting all of the entries, right? So we're gonna create a const entries. That's gonna be document.querySelectorAll
and I'm gonna select .entry and then for each of the entries
we're gonna do the following. We're gonna create a variable
called entryMeta that's gonna be = entry.query.Selector,
it's actually with double underscores so entry__meta and
then the entr_y_media here, okay. And we'll do the following. By default,
we're gonna set each image to move to the right side by 100% of its width.

So we're basically shifting
the image to the right, and we're setting its opacity to 0. And we're taking the meta, the text, and we're shifting it to the left
by using the same principle. So we're gonna say gsap.set entryMeta, so this is the text,
we're gonna say xPercent: 100, or I should say -100 to go to the left,
and opacity: 0. Okay, let's do the same for the media. This time the xPercent is gonna be 100. So now if we take a look,
everything is shifted to the, right, side of the page,
I just cannot see them. So now let's animate that into view. For that, I'm gonna say gsap.to(),
let's start with the entryMeta.

And here, I'm gonna be using
the scrollTrigger plugin. And I'm gonna pass in an object
with the following properties. I'm gonna set a trigger to entry, and the trigger is basically the element
that starts the animation. And entry is like the parent
element of my portfolio entry. And I'll show you how that looks like
in a visual way in just a little bit. Next, we can set a start position, and the end we'll set it to bottom 90%. And again, I'll explain that in
just a little bit because with gsap scrollTrigger, we can put down
something called markers.

And markers: true basically
creates these green and red markers at the start and
end of each of my elements, as well as the start and
end of my scrolled. So let's actually complete
the animation here. What I wanna do is I
wanna say the xPercent to be 0 and the opacity to be 1. So we're working with the entryMeta for
now, okay? But it's exactly the same for
the entry media. So let's actually see how this works. So then on refresh,
you'll see that as I scroll down, we saw a brief animation there of the text
coming in from the left side, right? There it is again, On this third project. But there is another
property we can use here, it's called scrub, and
we're gonna set that to true. And what this does is it ties the progress
of the animation to the position of the cursor. So, you'll see that as I'm scrolling up or down, that animation plays, pauses, and even goes in reverse. And let's do the same for the media,
So you can see this better, okay? So as I'm scrolling,
you can see the media coming in, On all three of these,
and as I scroll back up, it goes in reverse and
it even stops if I stop my scrolling.

How cool is that? Now let me explain a little bit how
this works, and let's actually work with the entryMedia because it's
a little bit easier to explain, and let's set the, let's do top center and
end, we'll do bottom center. We have two lines here,
one red, one green. One corresponds to the scroller start,
one to the scroller-end. And this is the position that I set here,
the center, center. This is basically a vertical position,
okay? So this code here says the following, when the top of my trigger
reaches the center point or whatever it is that I have set here,
start the animation. And you can end the animation
when the bottom of my trigger reaches whatever I have set here. So in this case, I set the scroller-start
and scroller-end both to the center.

So watch what happens. As I scroll down,
this is the start of my trigger, right? So when the start of the trigger
aligns with the scroller-start, then my entryMedia gets animated,
the animation starts. As I scroll down, yeah,
you can see the animation is running. And the animation will
end when the end of my trigger reaches or
aligns with scroller-end. And just to be a bit more specific here. Let's set these values to 20% and 80%. So now the scroller-start is
at 20% of the page height, the scroller-end is that
80% of the page height. And the same thing happens, right? When the start of my trigger
aligns with the scroller-start, the animation starts right there.

And the animation ends, When the end of my trigger aligns with
the scroller-end, just like this. Okay, and it happens the same for
the other elements as well, right? This is the second entry, and
now the animation starts. And now the animation ends,
because these two have aligned. This is basically how a scroll
trigger works, right? Now, the values that I have set previously were top, bottom, and bottom 90%.

And these are just the values that I
thought worked best for this case. But feel free to adjust them as needed. Now, finally, we've done the entryMeta. We've done the entryMedia, but we're
actually repeating a lot of stuff here. So how about we make this code
just a little bit more elegant. So let's comment all of this. We're gonna leave the two variables
because they're just fine. And let's write this entire code in
a more elegant, more concise way. So for that, we're gonna create
a timeline, gsap.timeline. And we're gonna apply scrollTrigger
to the timeline itself. So scrollTrigger, and the same thing, trigger is gonna be the entry,
start: 'top bottom', and end, we're gonna set bottom and 90%.

And the most important part scrub: true,
and if we want, we can also display the markers just for
debugging purposes. So now we can say timeline, fromTo, and we're gonna apply
first to the entryMeta. And being from 2,
we need to pass in two objects, right? The first one. It gonna say xPercent, so
we are start from -100%, and opacity is 0,
to xPercent 0, and opacity 1. And we're gonna do the same for
the entryMedia, except it gonna be from 100 to 0,
and from 0 to 1. So now, watch what happens, right? Same thing, hold on, from to, no, sorry, this is supposed to be tl.

Okay, so tl from to in both cases. Okay, so
now it does exactly the same thing, right? Except for the meta, so for
some reason, this doesn't work. So let's see why that is. Okay, I got it. It's because we're using a timeline and
events actually happen in succession. So we actually want to run these
animations both at the same time. And for that, it's really easy. We can pass in another parameter here in
the form of this, the less than symbol. And this basically means
that run this animation at the same time as the one before it, okay? So now, both animations, Run correctly. And we can get rid of the markers. We don't need those anymore. And that is our smooth
scrolling animation. Now, one thing that you
might have noticed, we're getting a bit of a scroll
bar here on the bottom. So to prevent that, we can go to our CSS. We can go to the body element, and we can say overflow-x hidden. Okay, and that's gonna fix this issue. This was being caused by the elements
being moved outside of our viewport.

Right, and
that's how you create a very nice, smooth scrolling animation with GSAP and Lenis All right, so in this lesson, we learned
about interactive animations which are triggered by user actions,
such as clicking, hovering, or scrolling. And there are a few good reasons for
using this type of animation. First being that interactive
animations grab attention and create a dynamic experience,
keeping users more engaged. These animations are also great for
better storytelling. Scroll animations, in particular,
can unfold stories or reveal information in an engaging way,
making content more memorable. Interactive animations can add life and
personality to a website, helping to strengthen brand identity and stand out from static sites by
creating an emotional connection. And let's not forget, these animations
can encourage users to explore and interact more, leading to improved
engagement metrics and longer site visits.

On the technical side, we learned
how to use the ScrollTrigger plugin from GSAP to create animations that
are tied into the scroll position. We also worked with a library called
Lenis, which is a great solution for creating smooth scrolling on your website. And it also works great with GSAP. Now interactive animations offer so much variety that we could probably
spend the whole day talking about them. But time is limited and
we're nearing the end of this course.

Before we do that though,
there is one particularly popular animation type that I want to cover,
and that is parallax. I'm sure you've heard about it before,
so let's check it out. Okay, so according to Wikipedia, parallax is the displacement, hold on. Parallax is a displacement or
difference in the parent position of an object viewed along
two different lines of sight and is measured by the angle or half angle
of inclination between those two lines. [SOUND] I have no idea what that means so let me explain it in a different way. Imagine you're sitting in
a car looking out the window.

You see the trees and the post signs and
the squirrels zooming by really fast, but the houses and hills and mountains
in the distance seem to move slowly. In fact, the further away from you it is,
the slower it moves. That's essentially what
parallax is all about. And when it's adapted to web design,
parallax is a technique where background elements move slower
than foreground elements. And this creates an illusion of depth. It adds a dynamic and
almost a 3D feel to a website. It's like having different layers
moving at different speeds. Pretty cool if you wanna add
a bit of flair to a website.

So let me show you a few real world
examples to understand what I'm on about. The first one is kooks.co.uk. And you will see that as we scroll down,
we get a little bit of parallax because we have
the background elements that are moving slower than
the foreground elements, right? So, in this case,
the pepper is moving a lot faster than the stuff that's behind it. And this kind of layered
animation is really, really cool. It really adds a sense of
depth to this whole page. Next, we have this bit, climb whales. And you see that as I scroll, it kind of feels like I'm seeing
this image from a lower perspective, because the elements here
move at a different rate. You can see the elements closer to me,
like the person and this rock here, they move a lot faster than
the elements in the background, like the mountains, right? So that creates a nice parallax effect. Pretty cool. Then we have this one, Firewatch,
which is apparently a game. And this has a really nice
parallax effect, all right? Notice as you scroll up and down,
it's a little bit buggy, to be honest.

Sometimes it works properly,
sometimes it doesn't. But the effect itself is amazing. You have this beautiful illustration,
layered illustration. And on scroll,
it's like you're changing perspective. Super, super cool. Now we also have this website. I don't know what it's about because
it's in a language I don't understand. I think it's from a movie or something. But yeah, this is yet
another type of parallax effect where the foreground content,
which is represented by the text, yeah, this just scrolls by and
the background content stays put, or it's scrolls at a much lower speed.

And this is another
implementation of parallax. You can probably see it here a little bit. And then we have Exercise 17. Wait a minute, this is one of our own. That's correct, we have what I
consider to be parallax here because if you remember on this button,
we are moving the text and the button itself, we're making them
follow the cursor at a different rate. And if we think about the text
as being the foreground and the button being the background,
yeah, they move at a different speed. So in my mind, I might be wrong, but in
my mind, this is also a parallax effect. Okay, so we've seen some real
world examples of parallax. Now we need to create our own, right? This is how it works in this course.

So for that,
we'll go to practical exercise number 19. Now, before we get started,
just a quick mention. Parallax websites can
be super complicated. So in this example,
we're gonna create something super simple, so that you understand the basics, okay? So here's what I wanna make. We have this fictional website
that has a big illustration here. This is an SVG illustration that
I got from Envato Elements. And further down,
we just have a bit of content. And it's basically about some books,
about nature, about exploration. As I said,
it's a completely fictional page. Now, I would like to animate this
illustration on Scroll, right? Because it has different layers and
I wanna give this whole page a sense of 3D,
a sense of depth, right? So here's how we're gonna do that.

For now, we have a section
with an idea of hero, okay. And we are loading that illustration as an SVG, as the background. But if we want to animate
the individual layers of that, we have to load them separately. So for now, let's uncheck that, and let's go ahead and
create the different layers. So the way we're gonna
do that is very simple. I have the illustration
open here in Figma, and I went ahead and
grouped the relevant pieces together. So we have a couple of layers and
let me just, Unhide all of them.

Layer 1, and we're going from the farthest
to the closest, layer 1 is just this, the night sky with the moon and
the birds and the stars, okay? Layer 2 is the furthest mountain range,
I guess you could call it. Layer 3 is a bit closer to us. It has the wolf, it has some trees. Layer 4 is again, even closer to us. It has a lot of trees. And then layer 5 is the closest. It has the wolf, it has a rock,
it has grass, and it has a tree. And if you look at the original
structure of this, it's of course, layered, but it's not layered in a logical
way that works for us, right? So for example,
the stars are kind of grouped together. We have a group 1, that's something. We have the birds,
we have the wolf, mountain 2, 3, 4.

So I wasn't gonna use this structure. Instead, I just picked
the elements that I needed and placed them in my individual groups. Okay, now, here's how you export this. You start by hiding all of the layers and
just leaving the first one. Then you select the image,
you export as SVG, and you export it in
the illustrations folder as wolves-bg-1.svg, of course,
so we'll save that. Then you hide that layer and
you bring up the second layer, just the second layer, okay? So the idea is to export
these layers on their own, let's do that, and
this is gonna be layer 2.

Hide that, show the third,
export again, that's gonna be layer 3. That's gonna be layer 4. And finally, that's gonna be layer 5. So now we can hide or
show all of these and we're done in Figma. Now, we are left with these SVGs, right? That's the first, that's the second,
third, fourth and fifth. And they both have the same size,
basically, because we exported the parent frame. So now, let's go ahead and
load these in our page. So I'm gonna go right here. Remember previously, we used
the hero to set a background image. Well, right now we're
actually gonna use some divs. So let's do this, div with an id of, we'll call it a wolves-wrapper, and inside I'm gonna create five divs with an ID of wolves-bg 12345.

And I'm also gonna set an attribute
called data-speed, okay. And data-speed will be used as
a multiplier to dictate the speed at which each of these layers is scrolling. So I'm gonna do 0.2 on the first one,
I'm gonna do 2, 4, 6, and 10. And you'll notice that as
we're getting to the layers that are closer to us,
we're increasing the data speed. This is essential for
the parallax to work properly. Okay, now let's go to the CSS part,
where as you can see, I've already included lenis,
both in CSS and in JavaScript, okay. And in JavaScript, actually, I didn't
include it, that was an oversight. Let me do that right now. We're including lenis for
smooth scrolling, yeah, and we're including the version that's
made for GSAP's scroll trigger.

And I'm also including GSAP and
the scroll trigger plugin, just like we did in the previous lesson. Now, if we do a refresh, yeah,
we get the smooth scrolling, but we don't see any image just yet. So let's go back to the CSS. And let's do the following. First of all, we'll target the hero and
we'll set a position relative. Because we wanna position
the wolves-wrapper, this bit, absolutely, yeah? So wolves-wrapper,
I'm gonna give it a width of 100%, a height of 100 dynamic
viewport height to fill up the entire height of the viewport,
position: absolute.

Save that, and
I'm also gonna set pointer-events to none, just so
that we cannot interact with those images. Or those images don't interact or
don't prevent us from interacting with any of the elements
that are positioned above them. Now, let's select all of these divs. For that we can use a clever attribute selector in CSS, where the ID basically contains the words wolves-bg-. So for these,
we're gonna do the following, background-repeat: none,
background-size: cover, and background-position,
this is important, bottom center. Essentially I want to set each of the SVGs we exported as a background
image to each of these divs. So I'm just targeting all of them and
setting some properties like don't repeat the background,
scale up the image to cover the entire picture and
set its position to the bottom and center. Okay, next, let's set width: 100%, height: 100 dynamic viewport height.

Position is gonna be
also absolute because I wanna stack them one on top of the other,
and I want them all to start from the top and
the left, cool. Okay, so
now we just need to load up the images. So let's start with this, wolves-bg-1,
which is the first div here. Let's say background-image: url(illustrations/wolves-bg-1). Save that, refresh, and there it is,
the image in all of its glory. However, it's covering
the contents of my hero. So let's actually add a z-index
of -1 on all of these containers.

All right, and
that's gonna place it right below whatever content I have in the hero area. So now let's start
adding the other images. So background 2, right, so
now the other images added on top. Nice, let's do the same for the rest. That's 3, 4, and 5, and there we go. We've just reconstructed
the original image we had by using five different images. We now have a layered image that we can
play around with GSAP, so let's do that. Let's go all the way down here in
our own script tag, we're gonna start by getting the wolvesWrapper, and
then let's get the five backgrounds.

So const wolvesBG =
wolveswrapper.querySelectorAll(). And I'm gonna target
the divs using the exact same selector that I did in CSS,
wolves-bg-. All right, next let's create a timeline. And we're gonna define scrollTrigger. And the trigger itself will be
the wolvesWrapper, so the main container. The start is gonna be at the very top, and I'm gonna set scrub to true. Okay, so that's our timeline. Now, for each of the backgrounds,
we're gonna do this, wolvesBG.forEach, and
we're gonna call this just bg.

We're gonna do const bgSpeed, we're gonna get this data attribute here,
right? So bg.getAttribute('data-speed'). So now, all we have to do is say,
tl.to, so timeline to, we're gonna animate the bg,
and we're gonna make it go y. So on the y-axis,
we're gonna do, I don't know, something like 60, times background speed. And let's set a duration of 2,
and let's see how it works. So now as we scroll, So something is working, but not quite right. And that's because we're using a timeline,
okay? And being a timeline,
the animations will run in succession. If I want them to run at the same time, I can pass in on a parameter
here which basically tells GSAP, okay, run all of these animations in
the timeline at the same time, okay? But this is a different story. Now, every single layer is
animated at the same time, and we get a super cool parallax effect. Look at that. And you can play around with this number,
you can do like 20. And that's gonna be a much
more subdued animation, or you can do like 120,
and that's gonna be a much more dramatic animation,
as you can see here.

But in my case,
I'm just gonna leave it at 60, because I feel that it works perfect for
me. You can also play around with
the different background speeds for each of these elements. So if you want the background,
like the first layer, to move a little bit faster,
you can increase the number here. Or maybe you don't like the third layer,
maybe you want to move at slower than decrease the number,
and so on and so forth. You can double the speed
of the front element, and that's gonna move at a much
higher rate than the others. All right, so that's super cool. So that's an easy way of
creating a parallax effect. Now before we wrap things up, if you
remember from the original image here, we had this kinda vignette
effect going on at the top. And let's go ahead and add that.

I'm gonna go down here and
say, oops, wolves-wrapper. And I'm gonna be using
an after pseudo element. Or I'm just gonna set just blank content,
position: absolute, insert: 0, to cover the entire Page,
z-index -1, and then we'll just do a background,
a linear gradient, going direction is gonna be 180 degrees,
and it's gonna go from just black, so 0, 0, 0, let's say with a 0.8 opacity. And that's gonna start at the very top,
and we go to 0, 0, 0 with 0 opacity at about half,
at the halfway point, kind of. So we're going from black 80% on
the top to complete transparent right about the middle size, or
the middle portion of the image. And if you are still unclear
about how the scroll speed, or the scroll trigger works,
you can always add the markers and
see exactly how that works. We basically have the start and
end of our trigger, which is the container that
holds all of these images. And I set the start of scroll
trigger here on the top, which basically means my animation
starts when the start here aligns with the scroller start,
which is right at the top.

So, it starts right as I
began scrolling the page. Wow, how cool is that? Okay so, let's comment these,
and we are done. All right, so,
in this lesson we explored parallax. So, picture this, you're in a car,
watching nearby trees rush by quickly, while distant mountains move slowly,
that's parallax. Closer objects seem to
move faster than far ones. This effect is used in web design
to make background elements moves slower than those in the foreground, creating a sense of depth and
adding a 3D feel to web pages.

One of the ways of adding parallax
to a website is to split up an image into multiple layers,
load them individually, and then animate them at different
speeds when scrolling. And with that we covered the final
animation type in our course. Now, before we wrap things up, there's one more thing we need to address,
and that is the interplay or the relationship between motion design and
responsive design.

Now, all the demos you've seen so far have
not been optimized for mobile layouts. Chances are if you open some of
these demos on your smartphone, the layouts will be broken,
and that's okay. This course is about motion design not
about how to make layouts responsive. And even though it would
have been an easy task, I preferred to focus on
the animation side of things. Now, with that said, when using
motion to enhance your web project, you do need to consider
responsive web design, and there are three main reasons for that. The first is a device limitations. Mobile screens are smaller, which means
less space for large, complex animations. Plus large and
complex animations can clutter your UI and they can confuse the user,
therefore, negating any benefit you might have gained from creating
those animations in the first place. Let's do a quick comparison between
the desktop version of DocStudio and the mobile one.

I've showed you this before in this
course, so I'm sure you're familiar with how the desktop version of
the website looks like, right? We have these fancy animations, they're
interactive, they look great, okay? Now, if we switch to the mobile version,
well, that's a different story altogether. We can still refresh and
we get the loading the animation.

But we don't get the main animations that
we saw on the desktop version, right? It's much more static here, because, you know of the performance reasons
I'll be mentioning in just a little bit. We still have some animation,
like for example, if we open up the menu we have
those nice transitions, but it's nowhere near the interactiveness
of the desktop version. Something else to consider is the
interaction, because on mobile devices, you rely on touch gestures like tap,
swipe, up, pinch, right? So, you need to design your animations
to complement those gestures. Let's take a look at the full
studio on desktop pan.

If we scroll down, the stuff that I
want to show you is a right here, it's the slider for the testimonials. Now, on desktop you're cycling through
the testimonials by using the before and after buttons, right? There is no other way of doing that or
with drag with anything. Now, if we look at the same
website on mobile and we scroll down to the same area,
yeah, we still have the two buttons which we can tap to
cycle between the testimonials. But in addition,
we also have a swipe gesture, we can swipe left or
right to cycle between these. So, great example of how
the animations here have been adapted to the medium
they're being displayed on. Now, a reason number two for considering
responsive web design is performance. Generally, mobile devices have less
processing power than desktops, so using heavy animations can cause lag,
they can drain battery, and they can also negatively
impact the data consumption. Imagine you're using a lot of heavy
assets like unoptimized videos, right? Those are all gonna take a really
long time to download, and will definitely impact
the data consumption.

Now, here are a few basic principles
you can use to create motion while keeping performance in mind. The first one is about file size. You should always make your files as
small as possible, either as videos, images, Lottie files, or
any kind of file Used for animations. Then you should be using CSS transforms, because CSS transform properties,
including translate, scale, and a rotate, are designed for
efficiency using less system resources. These are ideal for smooth
animations on the low power devices, because they leverage
hardware acceleration, which means they use the GPU for
better performance.

Next up, you should use JavaScript only
when necessary, because while JavaScript provides more control, it's often less
efficient than CSS for animations. So, you should always
reserve JavaScript for complex animations where
CSS can't do the job. For simple things, stick to CSS. Finally, let's look at the reason number
three for considering responsive design. And that is accessibility and
this is a topic that can be debated for hours, but
essentially it boils down to this not all users can interact with web
content in the same way. Some might have visual or
motor impairments that make navigating standard layouts or even animations challenging, right? So keep it simple,
use relatively simple layouts, and make those layouts
consistent across devices. And that will definitely help users
with disabilities navigate and understand the website more easily. On top of that, keep in mind
that some of your users can have vestibular emotion disorders for
them animations such as scaling or panning large objects
can cause discomfort. And I remember having
a similar issue many, many years ago when I had
an inner ear problem.

And besides the usual loss of balance and
all that, I remember that any flashing or sudden movement on the screen would
give me headaches and make me dizzy. That's why in most
operating systems nowadays, you have some sort of setting for
reducing motion. So for example, in iOS,
you would go to the Settings, you would go to Accessibility and
then to motion and right up here, you have this
toggle that says reduce motion. And in the case of iOS 17, which I'm
using here, it says that it reduces the motion of the user interface,
including the parallax effect of the icon. So this is what it looks like if,
for example, I swipe up to reveal the homepage, right? It looks something like this,
you get a nice scale down, parallax effect for the icons. And again, when you open up an app, it kind of scales from
the bottom to the screen. But when I tap in a reduce motion, yeah, those animations are kind
of replaced by a fade.

I hope the animation is captured
here on the screen recording, but yeah,
this is basically how you do it in iOS 17. And the same thing can be done on Windows,
on Android, on Mac even. And I think even on Linux,
I remember seeing or hearing about a setting like that. Now apart from the obvious effects
that you get on an operating system, this type of setting can be
used by website developers, and here's how you do that. There is a CSS media feature
called Prefers a reduced motion, which looks like this.

Essentially, you create your
animations as intended, and then inside the media feature you can
specify what changes you want to make for users who opted for
the reduced motion on their device. In this example, we're switching
from a bounce animation to a fade. And how you want that reduced
animation to play is really up to you. You can replace it with something else,
you can remove it entirely, or you can do something like this. Where you basically set the animation and transition duration to
a 1,000th of a second. And change the animation repeat
count to one, so it only runs once, and you will do this for
every single element on your page. So in this lesson, we learned that
responsive web design should be a major consideration when it comes
to creating motion for the web. First, think about device limitations and
keep animations neat and complementary to mobile interactions
like tapping and swiping. As mobile screens have limited space and
different interaction methods, then also think about performance. You need to create smooth,
very efficient animations on mobile by minimizing file sizes and
using CSS transforms, while reserving JavaScript for
complex tasks.

Finally, for accessibility purposes,
create designs that are both simple and consistent to cater to
different user preferences. And implement the prefers-reduced-motion
media feature in CSS to provide a comfortable experience
for users who are sensitive to motion. If you do these things, you'll be one step closer to
providing a great user experience for all of your users, which is something
we should all be aiming for. And that concludes this mega course
on motion design for the web. Now, question for you, what's the biggest challenge you're facing
when implementing motion for the web? I would really like to hear from you and
hopefully this course helped you with that particular problem and
maybe answered some of your questions. Either way,
let me know down in the comments, and if you like this video,
don't forget to hit the Like button and subscribe to the Envato Tuts+ channel for
more Free content like this. And before I go, just a quick reminder
that you can download a starter kit for all 19 exercises, so you can code
alongside me while watching this course. Well, it's time for me to sign off.

Thank you very much for watching and until next time, take care and be safe..

Website Setup Service

Leave a Comment

Your email address will not be published. Required fields are marked *