Tag Archives: snippets

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

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.