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.
What you will learn in this page transitions tutorial:
- How to scale up from where the user clicked
- How to use GreenSock for page transitions
- How to change the body class on page transition
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
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
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
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
Related Resources
- How To Make Page Transitions in HTML
- Practical GreenSock – Premium Online Tutorials
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.