Animated elements on a webpage play a critical role in creating an amazing user experience. Creating custom animations, particularly for Javascript frameworks, has long been engaging. As a result, it has provided room for animation libraries such as react-spring, Animie.js, and AnimXYZ, to mention a few.
AnimXYZ differs from the rest by being lightweight and extremely easy to use. With AnimXYZ, you only provide a few CSS variables to elements, and you will achieve a wide range of complex and unique animations. Additionally, it gives you control over the animation, as you can customize it to your needs. If this seems too good to be true, hold on; we are getting there.
This article will give you a comprehensive look at AnimXYZ and conclude by creating this React landing page.
What is AnimXYZ?
AnimXYZ is an open-source animation library that makes it easy to animate components on your page with a few lines of code. It supports basic HTML and CSS, ReactJs, VueJs, and SCSS. AnimXYX utilizes utility classes and CSS variables to achieve many animations without writing keyframes. Once the animation runs, it's compiled down to native CSS keyframes, giving you smooth transitions between elements.
How does AnimXYZ work?
Instead of creating keyframes for every animation on your page, AnimXYZ creates keyframes to perform a specific animation, leaving you to provide the parameter through the xyz
utilities.
Under the hood, we have lots of keyframes like the one below:
@keyframes xyz-keyframes {
from {
opacity: var(--xyz-opacity);
transform: translate3d(
var(--xyz-translate-x),
var(--xyz-translate-y),
var(--xyz-translate-z)
);
}
}
Setup and installation
To get started, we'll create our React project using Vite. Vite is a build tool that helps you set up your app in seconds, but you are also free to use create-react-app
. Then we will install AnimXYZ as a dependency.
First, create an empty folder that will host all our project files. Next, start up VS Code and open the created folder in it. Next, open the VS Code integrated terminal via the Ctrl+Shift+
shortcut or by clicking the
Terminal` UI menu at the top of the VS Code navbar. Then, to initialize Vite, run the following command:
bash
npm create vite@latest
The Vite's installation wizard will ask you for the name of your project and package name and then ask you to choose your preferred framework, as shown below.
Navigate to the React option through your keyboard's up and down arrow keys, then press enter
. It will prompt you to choose the variant you'd like your React app to come with, as shown below.
For our case, we will go with Javascript, the first option, but you are also free to use Typescript. Press enter
for the first option, and Vite shall be ready to install. You will receive the below prompt for your project setup.
As stated in the picture, Enter your project directory via the cd command, then run the following command on the terminal.
bash
npm install
Completing all of your project’s installations may take a few seconds. Now let’s install AnimXYX.Run the below command, which will install AnimXYZ as a dependency.
`bash
npm install @animxyz/react
`
bash
Once finished, you can start your development server via the command below.
`
npm run dev
`
It is still the command that you will repeatedly use when you want to start the server. Once the server is started, on the terminal, you will provide a URL link to your locally hosted application. Open your favorite browser and visit the URL to see your application.
XyzTransition
Component
AnimXYZ comes with the XyzTransition
provider component that you wrap around the elements you want to animate. The "XyzTransition" is an extension of React TransitionGroup, a React library dedicated to implementing visual transitions.
Now, open the app.css file and insert the following code.
`css
root {
width: 100%;
margin: 0;
padding: 0;
text-align: center;
box-sizing: border-box;
}
.card {
background-color: rgb(234, 255, 0);
width: 10rem;
height: 10rem;
margin-top: 3rem;
border-radius: 1rem;
}
.hero {
width: 100%;
background-color: cyan;
align-items: center;
height: 100vh;
display: flex;
flex-direction: column;
}
`
javascript
You can clear out all the styles in index.css then add the following code on app.jsx
`
import "./App.css";
import Hero from "./Components/Hero";
import { XyzTransition } from "@animxyz/react";
import "@animxyz/core";
function App() {
return (
);
}
export default App;
`
From the above code, we have imported the XyzTransition
component from @nimxyz/react
, which we installed as a dependency earlier. Then, we have to wrap our application around the component. We are currently wrapping our entire application with the XyzTransition
because it is a small demo app, and wrapping the entire application is not required as in the case of a provider in other technology like redux. Wrapping creates a unique code block that will be animated in a specific manner.
XyzTransition component usually takes duration
, appears
, and appear-visible
as major props.
- Duration: The
duration
defines how long an animation will run. During this time, the animation has an active class applied to it, and when the time is over, the active class is removed. Active classes are AnimXYZ classes that carry out a specific operation. Theduration
props can also be specified in milliseconds.javascript duration = "3000" //animation set to run for three seconds
Appear:
appear
is a boolean prop given to theXyzTransition
component. When it’s set totrue
, the animation on the element will only take effect when the page renders, and when set tofalse
, the animation will run when toggled.AppearVisible:
appearVisible
utilizes the intersection observer to check if the element is visible on the screen. It keeps the animation from running until the element is visible on the screen. For its value, you can give a boolean or your custom-created intersection observer, i.e.
javascript
appearVisible = { boolean | IntersectionObserverOptions }
Mode: The
mode
props control the behavior of the animation. The two major ones are:
javascript
mode = "out-in"
mode = "in-out"
One caveat to always remember when using XyzTransition
with react. You can only have HTML elements as your direct children, not the exact component. When you import a component, in our case, Hero,
we wrap it with HTML tags.
`javascript
`
javascript
Additionally, we have included the below line in our imports.
`
import "@animxyz/core"
`
This is necessary if your webpack utilizes the CSS loader, and you only need to import it once in your scripts.
Utilities
Now, create a new folder in the src
and name it Components
. Create a JSX file called Hero
and have the below code.
`javascript
import "../App.css";
function Hero() {
return (
);
}
export default Hero;
`
javascript
Now, here is where the magic happens. AnimXYZ is a variable and utility-oriented animation toolkit. You create your desired animation by passing the utility to the `xyz` variable.
AnimXYZ packages a large number of utilities that you can use.
Here is how you use them.
In the `Hero` component, we gave out the utilities to be
`
xyz="fade down small duration-30"
`
The above utilities specify
-
fade
: make the element visible as its opacity increases gradually. -
down
: indicates that the element will grow from the top down. -
small
: the element will start small and grow. -
duration
: the total time the animation will take to run
For our child components to run the animation, we add xyz-nested
to the class name of our child component. This is done so the children can inherit the animation from the parents' component. It is especially convenient when you have a lot of nested elements or components.
Our app will render the below animation.
Let's add more utilities to make the animation more complex.
Have the following line for the xyz
utilities in our app:
javascript
xyz="fade up-100% flip-down flip-right-50% rotate-left-100% origin-bottom duration-10 stagger"
Our animation will render as below.
Cool right?
XyzTransitonGroup
Component
This component is similar to the XyzTransition component. It is useful when applying animation to a list of elements.
Example:
`javascript
<XyzTransitionGroup
appear={boolean}
appear-visible={boolean | IntersectionObserverOptions}
duration={
number |
"auto" |
{ appear: number | "auto", in: number | "auto", out: number | "auto" }
}
tag={string}
...
;
`
In addition toduration
,appear
, andappear-visible
pros, inXyzTransitionGroup
, you also have the tag props. Thetag
props require you to specify the HTML tag you will use to wrap your components, for example, thediv
tag.
Session Replay for Developers
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay suite for developers. It can be self-hosted in minutes, giving you complete control over your customer data
Happy debugging! Try using OpenReplay today.
Creating the landing page
Now let’s put everything we’ve learned so far into action by creating a landing page. We will use AnimXYZ to animate our project to resemble a production-level landing page.
Before coding, let’s create a good folder structure for easy application management. Delete the already existing Hero.jsx
file in the Components folder and create two other folders, Navbar and Hero.
In the Navbar folder, create two files, Navbar.jsx
and Navabar.css
, for styling our Navbar.
Add the following line of code in index.css
`css
:root {
font-size: 16px;
font-weight: 400;
width: 100vw;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-image:linear-gradient(to bottom right, rgb(14, 14, 83),rgb(1, 1, 29) ) ;
background-repeat: no-repeat;
background-size: cover;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
`
Create two files in the Hero
folder: Hero.jsx
and Hero.css
.
Open the Navbar.css
file and paste the below line of code.
css
/* Navbar.css*/
@import url("https://fonts.googleapis.com/css2?family=Montez&family=Poppins:ital,wght@0,200;0,300;0,400;1,300;1,400&display=swap");
.navbar {
padding: 2rem;
padding: 2rem;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
top: 0;
left: 0;
max-height: 1rem;
}
.logo {
display: flex;
}
.logo h1 {
padding-left: 5px;
font-family: "Montez", cursive;
font-size: 3rem;
}
.items {
display: flex;
justify-content: space-between;
width: 30%;
}
.items p {
font-family: "Poppins", sans-serif;
}
We have imported two fonts from Google Fonts to add flavor to our text: the Poppins font and Montez. Open the Navbar.jsx
file and have the below lines of code.
`javascript
import svg from "../../assets/react.svg";
import "./Navbar.css";
import { XyzTransition } from "@animxyz/react";
const Navbar = () => {
return (
Open replay
About
Pricing
Sponsors
Team
);
};
export default Navbar;
`
The logo that we are using is the React logo that comes with Vite. We have followed this by importing our navbar CSS and the XyzTransition
component from @animxyz/react
.
We will only be animating our menu elements in the navbar by making them slide in from the left as the page loads.
For that, we first wrap the Navbar component with the XyzTransition
.Then, to ensure the animation runs when the page loads, we set the appear
pros to be true
. For the duration, we have set it to auto
since we will have nested elements, and we would like each element’s animation to complete before moving to the next.
To define the animation we want for our navbar menus, we give their parent element, the div
with class name items
, the xyz
utility class. For the utilities, we have defined them as shown below.
javascript
xyz="fade left duration-30"
fade
: Increase the element's opacity as it fades into visibility.left
: This will make the element move from the left.duration-30
: The duration specifies how long our animation will take.
Now, open the Hero.css
file in the Hero
folder, then paste the below lines of code.
`css
@import url('https://fonts.googleapis.com/css2?family=Montez&family=Poppins:ital,wght@0,200;0,300;0,400;1,300;1,400&family=Roboto:wght@100&display=swap');
.hero{
width: 100%;
display: flex;
}
.text{
width: 50%;
}
.text h1{
font-size: 3.5rem;
width: 80%;
padding-left: 2rem;
font-family: 'Roboto', sans-serif;
}
.text p{
padding-left: 2rem;
line-height: 1.8rem;
font-family: 'Poppins', sans-serif;
}
.buttons{
width:100%;
padding-left: 2rem;
}
.email{
padding: 1rem;
color:white;
width: 40%;
border-radius: .8rem;
border: none;
}
.acces{
padding: 1rem;
color:white;
width: 40%;
border-radius: .8rem;
border: none;
margin-left: 5px;
background-color: aqua;
color:black;
font-family: 'Poppins', sans-serif;
}
.image-wrapper{
padding-left: 1rem;
}
`
javascript
We shall use `Poppins` font to style up our text, so we use the Google font link we previously had on the `Navbar.css` file since it had `Poppins` font.
Then, open the `Hero.jsx` file and have the below lines of code.
`
import heroPic from "../../assets/group.png";
import "./Hero.css";
import { XyzTransition } from "@animxyz/react";
function Hero() {
return (
className="text"
xyz="fade small stagger ease-out-back delay-10 duration-30"
>
Welcome to open replay
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellendus
totam nemo vero quod laboriosam ullam suscipit beatae reiciendis
doloremque minima repellat possimus error, voluptatum eaque. Quos
dignissimos ullam dolorem molestiae.
Get Early Acces
className="image-wrapper"
xyz="fade right stagger delay-10 duration-20"
>
src={heroPic}
className="xyz-nested"
alt="colaboration illutartion"
/>
);
}
export default Hero;
`
Now, go ahead and download an illustration image from here for free and drag and drop it into the assets folder in our application. We have imported the image and named it heroPic
. We have also imported our styles and the XyzTransition component for animating our elements.
In the jsx
, we have two major div
tags with class names text
, and image-wrapper
. We shall be animating both of them, and as a result, we wrap the entire component with the XyzTransition
component.
Now for the text
class, we give it the xyz
utility class with the below utilities.
javascript
xyz="fade small stagger ease-out-back delay-10 duration-30"
fade
: the element will appear gradually, and its color will sink in.Small
: causes the element to expand inward and contract outward.stagger
: causes the menu list animations to follow each other.ease-out-back
: this gives the animation a slight overshoot at the end.delay-10
: this causes the animation to pause for a few seconds before starting.duration-30
: the time it will take to complete the animation
Additionally, all the elements in the list are given xyz-nested
class. It is to make them inherit the animation from the parent class.
For the image-wrapper
class, we gave it the below xyz
utilities.
javascript
xyz="fade right delay-10 duration-20"
fade
: this makes the element gradually appear while increasing its opacity.right
: it makes the element slide in from the right.delay-10
: this will pause the animation for a few milliseconds after the page loads.duration-20
: the time it takes for the animation to run.
We also gave the img
JSX tag the xyz-nested
class. It is to make it inherit the animation from its parent class.
Finally, open the App.jsx
file and insert the following code.
javascript
//App.jsx
import Navbar from "./Componets/Navbar/Navbar";
import Hero from "./Componets/Hero/Hero";
import "@animxyz/core";
import "./App.css";
function App() {
return (
<main>
<Navbar />
<Hero />
</main>
);
}
export default App;
We have imported our Navbar
and Hero
components and rendered them in our apps’ JSX. We have also imported @animxyz/core
. We have imported it because our Webpack uses a CSS loader. You can include the snippet anywhere in your JS file.
Conclusion
You must have seen how easy it is to get started using AnimXYZ. This article has introduced AnimXYZ, gone through how to set it up in a project, and shown how to use it. AnimXYZ is a powerful library that has a large community behind it. Feel free to try it out and bring the AnimXYZ awesomeness into your application.
Thank you.