Tag Archives: tutorial

Barba.js - Namespace, Rules and Conditions

Barba.js – Namespace, Rules, and Conditions

In the previous tutorial, we’ve covered how to create some cool page transitions using Barba.js and the CSS plugin. Today we will break down some the of terms associated with Barbas page transitions logic.

This will help you to trigger the right transition at the right time.

Barba.js Tutorial

What you will learn:

View Demo →Download Files ↓

What is a namespace?

Barba.js namespace

In simple terms, a namespace is the name of the page that you are leaving or entering.

It is defined on the data-barba="container".

<div class="wrapper" data-barba="container" data-barba-namespace="home">
    ...
</div>

This namespace is very useful if you want to define some rules for your page transitions.

When defining a transition in barba.init({...}) you can tell Barba to use this transition only if some conditions are met. More on conditions later.

There are many custom page transitions in the top award-winning websites.

The developers carefully consider which elements need to be animated out before the new page is animated.

In the CSS page transitions example, I have defined a different namespace for each page to be able to trigger different page transitions.

barba.init({
  transitions: [
    {
      name: 'home',
      to: { namespace: ['home'] },
      leave() {},
      enter() {},
    }, {
      name: 'fade',
      to: { namespace: ['fade'] },
      leave() {},
      enter() {},
    }
  ],
});

If we click on a link that takes us to fade.html, we play the fade transition. If we go to the index.html, the home transition will be used.

That’s how we have used namespace in the transition rule.

How to set rules for transitions?

Barba.js rules for transitions

To define the rules we can specify to, from, or both keywords.

The transition with both keywords will always take a priority, followed by to and from.

namespace is not the only condition that you can use.

To make the rules even more flexible you can also define custom or route if you are using Barba Router.

Think about rules as if this is true, use this transition.

{
    name: 'home',
    to: { namespace: ['home'] },
    leave() {},
    enter() {},
}, {
    name: 'clip',
    // to: { namespace: ['home'] }, // this would make it stronger
    from: { namespace: ['with-cover'] },
    leave() {},
    enter() {},
}

Above are two transitions, one with the rule “to home”, the other one with “from with-cover” namespace.

What if the user goes from with-cover to home? Which one would be used?

The home because to is stronger than from.

If we would add to: { namespace: ['home'] } to the clip transition it would become stronger and would be used instead.

How to use a custom condition for your transition?

Barba.js conditions for transitions

Let’s say you have a special link on a page and you want it to trigger a special transition.

At the same time, you want any other link on that page to trigger a default transition.

You can use the custom condition like this:

{
    name: 'default',
    sync: true,
    from: { namespace: ['home'] },
    leave() {},
    enter() {},
},
{
    name: 'special',
    sync: true,
    from: {
        custom: ({trigger}) => {
            return trigger.text === 'Clip-Path Transition';
        },
        namespace: ['home']
    },
    leave() {},
    enter() {},
}

Any link on the home page would trigger a default transition, but clicking on Clip-Path Transition would trigger the special transition.

Do you see how powerful the rules are? That is how you can craft your page transitions based on many conditions.

custom is the strongest out of all conditions followed by route and namespace.

Barba applies a transition if all conditions are fulfilled.

For more details on the priorities of Barba.js transitions refer to the official documentation.

Do you want to learn even more about Barba.js? Join me in Barba 101 where we will cover Barba API in more detail. I hope to see you there.

Final Demo

View Demo Download Files

Conclusion

Mastering transition rules and knowing exactly which transition will be trigger when is the key.

Now you know how to use a namespace, set some rules, and use custom conditions for your page transitions.

I can’t wait to see how you will use it on your project.

Do you have any questions related to Barba.js or page transitions? Let me know in the comments.

Barba.js and CSS Plugin Tutorial

Page Transitions Tutorial – Barba.js with CSS Plugin

Do you want to add page transitions to your project but don’t feel comfortable with JavaScript or GreenSock animations?

In this page transitions tutorial, you will learn how to use Barba.js with the CSS plugin to create page transitions purely with CSS.

What you will learn:

View Demo Download Files

Installation

Include @barba/core, @barba/css plugin in your JavaScript module, and tell Barba to use the CSS plugin.

// install via npm or yarn
npm install @barba/core @barba/css
yarn add @barba/core @barba/css
// Include Barba and Barba CSS in your project
import barba from '@barba/core';
import barbaCss from '@barba/css';

// Tell Barba to use the CSS plugin
barba.use(barbaCss);

// Initiate Barba
barba.init();
<body data-barba="wrapper">
    <!-- content that stays the same on all pages - eg. header -->
    <div data-barba="container">
        <!-- content that will change from page to page -->
    </div>
    <!-- content that stays the same on all pages - eg. footer -->
</div>

Barba.js will now add and remove specific CSS classes from the data-barba="container".

These CSS classes will be based on the transitions that we need to specify.

If you are completely new to Barba.js, you can check this tutorial to learn more about the required HTML markup.

How to create fade-in transition on page load

Barba.js CSS Page Transition

To create a simple fade in transition on page load we can use the once hook.

barba.init({
	transitions: [
        {
            once() {}
        }
    ]
});

Barba.js will add and remove the following CSS classes .barba-once, .barba-once-active and .barba-once-to during the transition.

/* Page load animation */
.barba-once {
    opacity: 0;
}
.barba-once-active {
    transition: all 1s linear;
}
.barba-once-to {
    opacity: 1;
}

.barba-once and .barba-once-active will be applied at the start of the transition.

.barba-once-active and .barba-once-to will be applied during the transition.

This hook is called once, because this transition only runs once on the page load.

When the CSS transition is completed, all CSS classes will be removed from the container.

Barba CSS with once hook

How long these classes stay on the container depends on the duration of the CSS transition or animation.

Because the CSS plugin overrides the main once hook, any code inside of once will be ignored. The same applies to the enter and leave hooks.

barba.init({
	transitions: [
        {
            once() {
                console.log('this will be ignored');
            },
            beforeOnce() {
                console.log('shows up BEFORE once transition');
            },
            afterOnce() {
                console.log('shows up AFTER once transition');
            }
        }
    ]
});

If you need to run any code related to the once transition use beforeOnce or afterOnce hooks.

How to customize the name of the CSS class?

You can customize the CSS classes by specifying a name for your transition.

transitions: [
    {
        name: "home",
        once() {}
    }
]

If you specify home as the name, Barba will generate these classes:

.home-once
.home-once-active
.home-once-to

The format of the class is always the same: .[name]-[hook]-[state].

How to create CSS transition between two pages

Barba.js CSS Page Transition

Every page transition has two phases.

Firstly the current page leaves, then the next page enters.

To use CSS transitions between two pages, we need to specify the hooks inside of the Barba transition, even if there is no code inside of them.

transitions: [
    {
        name: "fade",
        leave() {},
        enter() {}
    }
]

Now we can add the CSS transitions to the stylesheet.

/* =Fade out, fade in */
/* Fade out current container */
.fade-leave {
    opacity: 1;
}
.fade-leave-active {
    transition: opacity 0.3s linear;
}
.fade-leave-to {
    opacity: 0;
}

/* Fade in the next container */
.fade-enter {
    opacity: 0;
}
.fade-enter-active {
    transition: opacity 0.3s linear;
}
.fade-enter-to {
    opacity: 1;
}

1. Fade out the current page

Barba CSS with leave hook

In the first phase of the transition, we are fading out the current page.

.fade-leave /* start of the transition */
.fade-leave-active /* CSS transition */
.fade-leave-to /* end of the transition */

The state of our container is opacity: 1 at the start of the transition and opacity: 0 at the end of the transition.

.fade-enter-active class defines the CSS transition that will be used, eg. opacity 0.3s linear.

2. Fade in the next page

Barba CSS with enter hook

In the second phase of the transition, we are fading in the next page.

.fade-enter /* start of the transition */
.fade-enter-active /* CSS transition */
.fade-enter-to /* end of the transition */

We are starting from opacity: 0 and finishing with the page fully visible at opacity: 1.

Of course, you can combine the CSS selectors if the styles are the same.

/* =Fade out, fade in */
/* Fade out current container */
.fade-leave,
.fade-enter-to {
    opacity: 1;
}
.fade-leave-active,
.fade-enter-active {
    transition: opacity 0.3s linear;
}
.fade-leave-to,
.fade-enter {
    opacity: 0;
}

Perfect, this was a simple fade transition, but what if wanted to make a transition where both containers are visible on the page? How would we do that with Barba.js?

Let’s see in the next example.

How to create clip-path transition

Clip-path page transition using Barba.js

Now that you know the basics of Barba.js and the CSS plugin, only your imagination is your limit!

In the next example, we will try to reveal the next page from the center of the screen.

We will clip the incoming page clip-path: circle(0%); at the start and reveal it by specifying clip-path: circle(75%); as the end of the transition.

For this effect, we need to have both containers on the page and Barba has a sync mode build-in exactly for that.

transitions: [
    {
        name: "clip",
        sync: true,
        leave() {},
        enter() {}
    }
]

This will append the next container to the page and we will have both containers available for the transition.

Without the sync mode, the current page is removed from the DOM just before the next page is appended.

/* =Clip-path transition */
.clip-enter { 
    clip-path: circle(0%); 
}
.clip-enter-active {
    position: absolute;
    top: 0;
    z-index: 2;
}
.clip-leave-active,
.clip-enter-active {
    transition: all 0.75s var(--easing);
}
.clip-enter-to { 
    clip-path: circle(75%); 
}
.clip-leave { 
    opacity: 1; 
}
.clip-leave-to { 
    opacity: 0; 
}

With both containers on the page, we are overlapping them by positioning the incoming page on top of the current page.

Then we are animating the clip-path from 0% to 75%.

At the end of the transition, the current page is removed from the DOM and the next is the new current.

Makes sense? I hope it does.

It is quite fun to play with these transitions. Agree?

Let me know in the comments.

How to create a cover transition

Cover page transition using Barba.js

In this example, we will look at how to cover the current page and reveal the next page.

For this effect, we will need to include .transition element inside of each page.

<div data-barba="container">
    <div class="transition">
        <h2>Cover Screen</h2>
    </div>
</div>

This is a simple full-screen element covering the whole viewport, by default it is positioned outside of the viewport using transform: translateY(-100%);.

/* =Transition with cover screen */
.with-cover-leave,
.with-cover-enter,
.with-cover-leave-active .transition,
.with-cover-enter-active .transition {
    transition: transform 0.5s var(--easing);
}
.with-cover-leave .transition {
    transform: translateY(-100%);
}
.with-cover-leave-to .transition,
.with-cover-enter .transition {
    transform: translateY(0);
}
.with-cover-enter-to .transition {
    transform: translateY(100%);
}

In the first phase, we are transitioning the .transition element to translateY(0) using the .with-cover-leave-to .transition selector. This is also the starting position for the enter animation.

Then we are moving the .transition out of the viewport to transform: translateY(100%); using the .with-cover-enter-to .transition selector.

As you can see, the stylesheet could grow quite quickly.

Especially if you want to animate multiple elements in a sequence, that is where JavaScript animations with GreenSock come very handy.

How to create a slide transition

Slide page transition using Barba.js

Now that you know what sync: true does, you can come up with any transition that needs both containers.

One of these transitions could be a slide transition.

.slide-leave,
.slide-enter-to {
    transform: translateX(0);
}
.slide-leave-active,
.slide-enter-active {
    transition: all 0.7s cubic-bezier(0.5, 0.7, 0.4, 1);
}
.slide-leave-to {
    transform: translateX(100%);
}

.slide-enter {
    transform: translateX(-100%);
}
.slide-enter-to {
    position: absolute;
    top: 0;
    left: 0;
}

At the start of the transition, we are using .slide-enter CSS class to position the incoming next page outside of the viewport.

Then we are animating both containers by 100%. The current page goes away from the viewport to translateX(100%) and the next page moves to translateX(0).

The page entering the viewport is positioned absolute during the transition as we have defined in the .slide-enter-to CSS class.

And that is it, now you have learned how to create 4 different page transitions using Barba.js and the CSS Plugin.

Final Demo

View Demo Download Files

Things to remember

  • You need to add an empty hook to your JS, to use CSS transition for that hook!
  • The JavaScript code in once, enter, leave hooks will be ignored!
  • beforeOnce, afterOnce, beforeEnter, afterEnter, beforeLeave, afterLeave can be used.
  • Currently, there is a bug with the back button not triggering the transition.

Conclusion

As you can see from the above examples, you can create some interesting page transitions using CSS transitions.

You have learned how Barba.js and the CSS plugin works and which CSS classes are applied to your container during the page transition.

Have you seen any cool page transitions on the web?

Let me know in the comments and don’t forget to check out some of my online courses to learn even more about creative front-end development.

Practical GreenSock - Premium GreenSock Tutorials

Practical GreenSock Launch Date and Giveaway

After a long time in making, I am very excited to announce that the new lineup of my premium online courses will be available for purchase from the 18th of August 2020.

What is Practical GreenSock?

Practical GreenSock is a bundle of 3 online courses teaching you how to create more advanced animations and effects using GreenSock, ScrollTrigger and vanilla JavaScript.

All 3 courses are suitable for intermediate to advanced developers and designers.

Here is the breakdown of all 3 courses included in Practical GreenSock, watch the first unit from each of them to learn more.

  1. Projects Slider (*) – starter project – watch the first unit
  2. Pen Reveal (*) – starter project – watch the first unit
  3. Bella – main project – watch the first unit

* Free Upgrade for Existing Students

Anyone who has purchased at least one of my “closed” premium courses gets free access to Projects Slider and Pen Reveal from today.

Simply login to your account and start any of these two GSAP3 and ScrollTrigger courses today.

Enjoy this as a gift for all your support over the last few years. Thank you!

Enter to Win Practical GreenSock

To celebrate the re-launch of my premium courses I am also giving away 5 copies of Practical GreenSock.

Congratulations to the winners:

a Rafflecopter giveaway

Cheers
Petr

React and GreenSock Tutorial

React and Greensock Tutorial for Beginners

This React and Greensock Tutorial is focusing mainly on the basics of targeting elements and using React Hooks with GreenSock.

If you have been following my blog and YouTube channel for a while, you know that I enjoy using React and GreenSock.

They are both very powerful libraries with elegant APIs.

As more and more websites are build using React, it’s important to know how to use GreenSock in the React world.

What will you learn:

Baby steps I know, but lets learn how to walk before you try to run.

If you prefer learning by watching videos, checkout React + GreenSock 101.

View Demo →Download Files ↓

1. How to include GSAP in your React Project

React and Greensock Tutorial for Beginners

I am assuming you already know how to spin up a brand new React project using the Create React App.

npx create-react-app gsap-app
cd gsap-app

Now we can install GreenSock through npm and start the app.

npm i gsap
npm start

Cool, GSAP is installed lets import it to our App component.

import React from 'react';
import { gsap } from "gsap";

const App = () => {
    ...
    return (
        <div className="App">
            <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
            </header>
        </div>
    )
}

2. How to target elements using refs

Firstly we need to get access to the element that we want to animate.

We can use useRef because our App component is a functional component.

import React, { useRef } from 'react';
import { gsap } from "gsap";

const App = () => {
    
    const headerRef = useRef(null);

    ...
    return (
        <div className="App">
            <header ref={headerRef} className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
            </header>
        </div>
    )
}

We are storing a reference to our header element in the headerRef variable.

You can read more about React Refs in the official documentation.

3. How to animate React ref using GSAP

With our header “selected”, we can create a tween that will play when the component mounts.

import React, { useRef, useEffect } from 'react';
...

const App = () => {
    
    ...

    useEffect(() => {
        
        gsap.from(headerRef.current, {
            autoAlpha: 0, 
            ease: 'none',
            delay: 1
        });

    }, []);

    ...
}

Firstly we need to import useEffect and create our tween inside of it.

The empty array as a dependency of this effect will make sure that our tween runs only on the initial mount of this component.

If you are new to React Hooks you can check my free online course React 101.

The target for our .fromTo tween is headerRef.current that is how we can access the underlying DOM element.

Ok, now we have our header fading in with a slight delay, but how do we animate when the state of our component changes?

4. How to animate when React state changes

React and GreenSock Tutorial

Lets create a button that will change the background color of the header.

But we could that with css class, right? Off course we could, but I thought you are here to learn React + Greensock.

import React, { useRef, useEffect, useState } from 'react';
...

const App = () => {
    
    const [background, setBackground] = useState('#5a7d95');
    
    ...

    const toggleBackground = () => {
        const color = background !== '#5a7d95' ? '#5a7d95' : '#1b4943';
        setBackground(color);
    }

    useEffect(() => {

        gsap.to(headerRef.current, { 
            backgroundColor: background, 
            duration: 1,  
            ease: 'none' 
        });

    }, [background]);

    return (
        <div className="App">
            ...
            <button onClick={() => toggleBackground()}>Change background</button>
            ...
        </div>
    );
}

We import useState, set the default color and create a function toggleBackground that will toggle the background color between light and dark.

Then inside of a new useEffect that only listens to the background color change, we are using GreenSock’s .to tween to animate the background-color to the right value.

Please excuse my non-creative animations today, I am trying to keep the example as simple as possible.

5. How to create an array of refs

React and GreenSock Tutorial

ScrollTrigger is the cool plugin from GreenSock that lets you trigger animations as the user scrolls through your page.

Let have a look how to include ScrollTrigger in your React project and fade in a few section.

import React, { useRef, useEffect, useState } from 'react';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);

const sections = [
  {
    title: 'Title 1', 
    subtitle: 'Subtitle 1'
  },
  {
    title: 'Title 2', 
    subtitle: 'Subtitle 2'
  },
  {
    title: 'Title 3', 
    subtitle: 'Subtitle 3'
  }
];
...

We import ScrollTrigger and then register the plugin to make sure it survives the code tree shaking.

For this demo we are hardcoding some content in the sections array.

const App = () => {

    ...

    const revealRefs = useRef([]);
    revealRefs.current = [];

    const addToRefs = el => {
        if (el &amp;&amp; !revealRefs.current.includes(el)) {
            revealRefs.current.push(el);
        }
    };

    return (
        <div className="App">
            {
                sections.map(({title, subtitle}) => (
                    <div className="App-section" key={title} ref={addToRefs}>
                        <h2>{title}</h2>
                        <p>{subtitle}</p>
                    </div>
                ))
            }
        </div>
    );
}

Because we want to access multiple sections and trigger them individually, we need to create an array of refs revealRefs.

As you know from the above header example we get access to the underlying DOM elements in the .current property.

That is why we need to create a function addToRefs and add all our references to the sections to the revealRefs.current array.

6. How to use ScrollTrigger with React

Ok, great. We have access to all sections. Now lets loop over them and create new GSAP tween with scrollTrigger.

useEffect(() => {

    ...

    revealRefs.current.forEach((el, index) => {
        
        gsap.fromTo(el, {
            autoAlpha: 0
        }, {
            duration: 1, 
            autoAlpha: 1,
            ease: 'none',
            scrollTrigger: {
                id: `section-${index+1}`,
                trigger: el,
                start: 'top center+=100',
                toggleActions: 'play none none reverse'
            }
        });

    });

}, []);

We are looping over the revealRefs.current array and creating a simple .fromTo tween.

Each sections fades in when top of it is 100 pixels from the center of the viewport.

Again, today I could not think of a more creative way than just simply fading in a bunch of dummy sections.

React and GreenSock Tutorial Demo

View Demo →Download Files ↓

Do you want to learn more about React or GreenSock? Check out my free online courses React 101 and GreenSock 101.

Conclusion

Quite a long tutorial, but I hope that this guide will help you with implementing GreenSock in your React projects.

Do you have any questions related to GSAP and React? Let me know in the comments.

Barba.js Tutorial

Page Transitions Tutorial – Barba and GreenSock – Part 2

In the previous page transitions tutorial we have created a simple “take over” effect.

Today we will explore a little bit more about Barba.js and GreenSock and create a circular page transition.

Page Transitions Tutorial

What you will learn in this page transitions tutorial:

View Demo Download Files

Init Barba.js

The general setup of Barba.js is the same as in the previous tutorial.

barba.init({
    transitions: [{
        async leave({trigger}) {
            await loaderIn(trigger);
        },
        enter({next}) {
            loaderAway(next);
        }
    }]
})

We have two transitions leave() and enter(), but this time we are passing trigger to the loaderIn function and next to the loaderAway function.

How to scale up from where the user clicked

Page transitions tutorial

Each Barba.js hook receives the same data argument that contains the current and next page properties, it also includes trigger that is the link that triggered the transition.

You can read more about the Barba Hooks in the official documentation.

function loaderIn(trigger) {

    // get the size of the clicked trigger element
    const { height, width, top, left } = trigger.getBoundingClientRect();
    const triggerTop = Math.floor(top);
    const triggerLeft = Math.floor(left);
    const triggerWidth = Math.floor(width);
    const triggerHeight = Math.floor(height);

    // get viewport size, this will be used for scaling up the loader
    const viewportHeight = window.innerHeight;
    const viewportWidth = window.innerWidth;     
    const loaderSize = viewportHeight > viewportWidth ? viewportHeight*2 : viewportWidth*2;

    ...
}

We are firstly getting the dimensions of the trigger and its top and left offset relative to the viewport using the javascript getBoundingClientRect() method.

Secondly, we are getting the size of the viewport to be able to resize the loader accordingly.

Because the loader will always scale up from the center of the clicked element we need to make sure it is twice the size of the viewport.

How to use GreenSock for page transitions

GreenSock timeline

Now we need to create a GreenSock timeline that will scale the loader up.

function loaderIn(trigger) {

    ...
    const tl = gsap.timeline();
    tl
        .set(loader, {
            autoAlpha: 1,
            x: triggerLeft + (triggerWidth/2),
            y: triggerTop + (triggerHeight/2),
            width: loaderSize,
            height: loaderSize,
            xPercent: -50,
            yPercent: -50
        })
        .fromTo(loader, 
        {
            scale: 0,
            transformOrigin: 'center center'
        },
        { 
            duration: 0.8,
            scale: 1, 
            ease: 'power4.out'
        });
    return tl;

}

Firstly we use the .set tween to set the right position of the loader and resize it according to the viewport.

We use xPercent: -50 and yPercent: -50 to center, the middle of the loader in the center of the clicked link.

The .fromTo tween scales the loader from 0 to 1.

Regardless of where the link is on the page, the loader will always scale up from there and cover the whole screen.

Still with me? Lets keep going.

If you are new to GreenSock, checkout out my GreenSock 101 online course.

How to change the body class on page transition

Now let’s try to change the body class and display the correct background colors as defined in the stylesheet.

.is-home { background: #1f213f; }
.is-page-2 { background: #1c323d; }

Remember Barba.js only replaces the content of the data-barba="container”. This means that the body class would stay the same when navigating between the pages.

We have to manually update it like this:

function loaderAway(next) {
    document.body.removeAttribute('class');
    document.body.classList.add(next.container.dataset.class);
    ...
}

We are passing the next page to the loaderAway(next) function.

Inside of it, we are firstly removing the class attribute from the body tag and then applying the class that we have defined on the incoming page container as data-class="is-page-2”.

This will make sure that the body class is updated before we reveal the incoming page.

Reveal the new page

Page transitions tutorial

Now we have the whole page covered by the scaled-up loader, Barba updated the page under the loader and we are ready to reveal it.

The loader is a simple div, with a border-radius set to 100% to appear as a circle.

function loaderAway(next) {
    ...
    const h1 = next.container.querySelector('h1');
    const p = next.container.querySelectorAll('p');
    const img = next.container.querySelector('img');

    const tl = gsap.timeline();
    return tl.to(loader, { 
        duration: 1, 
        scaleX: 0.5, // squash the loader
        scaleY: 0.1, // squash the loader
        yPercent: 0, // move it down
        ease: 'power4.inOut'
    }).fromTo([h1, p, img], {
        autoAlpha: 0
    }, {
        duration: 0.9, 
        autoAlpha: 1, 
        stagger: 0.02, 
        ease: 'none'}, 
    0.3);
}

We can access the content of the incoming page by getting the right selectors from next.container.

Then we can reveal it in whatever fashion we want.

The .to tween above is squashing it down and moving it away from the viewport using the yPercent: 0.

With a slight 0.3s delay and a short stagger offset we are also fading the content in.

Final Demo

View Demo Download Files

Related Resources

Conclusion

And that is it, now you know how to create a circular page transition using Barba.js and GreenSock. If you are new to GreenSock, checkout GreenSock 101 where you can learn even more about this powerful animation library.

Have you seen any cool page transitions that you would like to see covered in my future page transitions tutorial?

Let me know in the comments.

Barba.js - Fluid smooth page transitions

How To Make Page Transitions in HTML – Barba.js and GSAP3 Tutorial

Page transitions are a thoroughly popular tool to help make your website stand out!

Smooth, fluid, and creative transitions often sets awarding winning websites apart from the rest.

Page Transitions Tuturial

In this tutorial we will demonstrate how to create a simple page transition using Barba.js and GreenSock.

What you will learn:

View Demo Download Files

Introduction to Page Transitions

Whilst creating page transitions may sound difficult, Barba.js makes the process incredibly easy.

There are two types of page transitions:

Now, let’s walk through the process of creating a loading screen page transition on a project with 2 static html pages.

/css/app.css
/js/main.js
index.html
page2.html

1. Create a loading screen

Page Transitions Tutorial

Firstly, we will create a loading screen .loader. This will be a container that will cover our screen while Barba.js is loading the next page.

<div class="loader"></div>

.loader {
    position: fixed;
    width: 100vw;
    height: 200vh;
    pointer-events: none;
    background-color: #FFF6ED;
    z-index: 1;
    visibility: hidden;
    opacity: 0;
}

We will make it position: fixed and the height twice as tall as the screen height: 200vh. This is because we will soon be slightly rotating it. Without any rotation a height: 100vh would be enough to cover the whole screen.

Opacity and visiblity are set to 0 and hidden, because we don’t want to see a flash of the loader before GSAP scales it down.

// reset position of the loading screen
gsap.set(loader, {
    scaleX: 0, 
    rotation: 10, 
    xPercent: -5,
    yPercent: -50, 
    transformOrigin: 'left center', 
    autoAlpha: 1
});

In the main.js we are rotating the loader and setting the scaleX to 0 to make it invisible for the user. At the same time we are setting visibility: visible and opacity: 1 using GreenSock’s handy autoAlpha property.

2. Include Barba.js

Barba.js - Fluid smooth page transitions

Include Barba.js at the bottom of both HTML files.

<script src="https://unpkg.com/@barba/core"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script>
<script src="js/main.js" defer></script>

I am also including GreenSock because Barba.js is not an animation library – it only takes care of content loading.

Your preferred animation library and style of page transition is completely up to you.

I tend to choose GreenSock for its flexibility and easy functionality. I have also become very familiar with it.

If you want to learn how to use GreenSock from scratch, check out GreenSock 101.

There are plenty of other animation libraries that would also work well, such as popmotion, animejs, mojs or spirit.

3. HTML Markup

Barba.js requires two special data-attributes somewhere in your markup.

<body data-barba="wrapper">
    <!-- content that stays the same on all pages - eg. header -->
    <div id="intro" data-barba="container">
        <!-- content that will change from page to page -->
    </div>
    <!-- content that stays the same on all pages - eg. footer -->
</div>

data-barba="wrapper" specifies the main wrapper of your page structure. This could be in the body or any other HTML element.

data-barba="container" is a section of your page which will be “reloaded or updated,” with the incoming content from the other page.

Anything outside of the container will not change between the page transitions.

You can use any markup you want, the only requirement is that the wrapper always needs to wrap the container.

4. Init Barba.js

barba.init({
    transitions: [{
        async leave() {
            await loaderIn();
        },
        enter() {
            loaderAway();
        }
    }]
});

In the main.js, we then initiate Barba.js to create our transition.

leave() will be executed first, followed by enter().

loaderIn() is a function that returns GSAP tween which stretches our .loader to cover the whole screen.

loaderAway() is a function that returns GSAP tween which scales the loader back to scaleX:0, when the new page is loaded underneath it.

5. GreenSock Animations

Page Transitions Tutorial

Now let’s have a look at the two tweens which create the transition.

function loaderIn() {
    // GSAP tween to stretch the loading screen across the whole screen
    return gsap.fromTo(loader, 
        {
            rotation: 10,
            scaleX: 0,
            xPercent: -5
        },
        { 
            duration: 0.8,
            xPercent: 0,
            scaleX: 1, 
            rotation: 0,
            ease: 'power4.inOut', 
            transformOrigin: 'left center'
        });
}

fromTo tween takes care of the first half of transitions and covers the screen when it’s completed.

We are setting the transformOrigin to be 'left center'. This makes it grow from left to right.

Page Transitions Tutorial
function loaderAway() {
    // GSAP tween to hide loading screen
    return gsap.to(loader, { 
        duration: 0.8, 
        scaleX: 0, 
        xPercent: 5, 
        rotation: -10, 
        transformOrigin: 'right center', 
        ease: 'power4.inOut'
    });
}

This tween reveals the new page which was loaded underneath the loader by Barba.js.

By changing the transformOrigin to 'right center' we create the effect of the loader disappearing on the right side of the screen.

6. Before and after the transition

Barba.js also gives you access to specific lifecycle methods or hooks that you can tap into.

One common example would be to add css class to your page to prevent users from double clicking on links.

// do something before the transition starts
barba.hooks.before(() => {
    document.querySelector('html').classList.add('is-transitioning');
});
// do something after the transition finishes
barba.hooks.after(() => {
    document.querySelector('html').classList.remove('is-transitioning');
});
.is-transitioning {
    pointer-events: none;
    cursor: progress;
}

Another example would be to enable scrolling to the top of the newly loaded page. We can use .enter hook for that.

// scroll to the top of the page
barba.hooks.enter(() => {
    window.scrollTo(0, 0);
});

Final Demo

View Demo Download Files

Related Resources

Conclusion

This may have been just a basic example, however I hope you can now see implementing page transitions can be a simple task!

The ultimate key is to master Barba.js and an animation library of your choice. If you’d like to go with GreenSock, learn everything you’ll need to know at GreenSock 101.

Today we really only scratched the surface of page transitions. It is a broad area, with lots of creative options out there.

So, if you have you seen other interesting page transitions you would like to learn about, please let me know! I’d be happy to make more in-depth page transition tutorials.