elementor4fun-logo
Last update: February 25, 2020

Animate a 3D Banner with BasicScroll

First, check this page to learn what is BasicScroll and how to use it: Better Scroll Animations with BasicScroll

Then, check this demo to see some better example of 3D banners:

Structure

Creating a cube in 3D is quite easy in CSS. You need 6 divs (1 Div for each face) and use some transform properties to change their positions, rotations and origins.

For these banners, there are only 3 faces. We don't need to create the back and side faces as they won't be visible.
We could use 3 Divs (one for the front, one for the top and one for the bottom) but to make it more simple, we will only use one Div + 2 pseudo-classes).

So the structure is actually pretty simple:

.banner3d is the container
.banner3d-front is the 3D object. It's a Div + 2 pseudo-class, for the 3 faces.
The main Div for the front face, the pseudo-class :before for the top face, and the pseudo-class :after for the bottom face.

Let's start to build it.

Step 1

Add a Section (yay!)

Step 2

Add a Div with a class called .banner3d and apply these settings :

Step 3

Now we can start to create the 3D object.
Add a Div with the class .banner3d-front
Change the background color and apply these settings:

Step 4

Add a text element and write whatever you want.
So now it looks like this:

Whatever your want

Step 5

Let's create the other faces, with the :before and :after pseudo-classes.
We could use the visual interface to add most of these properties, but sometimes it can be faster to put everything in CSS.
In a Code Block, add these CSS:

.banner3d-front:before {
    position: absolute;
    content: "";
    width: 100%;
    left: 0;
    height: 25px;
    background-color: #BFBFBF;
    top: -25px;
    transform-origin: center bottom;
    transform: rotatex(45deg);
}

.banner3d-front:after {
    position: absolute;
    content: "";
    width: 100%;
    left: 0;
    height: 25px;
    background-color: #BFBFBF;
    bottom: -25px;
    transform-origin: center top;
    transform: rotatex(-45deg);
}

So now we have our 3 faces, but they are still flat, not in 3D...

Whatever you want

Step 6

So we need to add some perspective. Still in the same Code Block, add :

.banner3d {
    perspective: 700px;
    transform-style: preserve-3d;
}

.banner3d-front {
    transform: translatez(25px);
    transform-style: preserve-3d;
}

 

Whatever you want

How to animate it?

What we have to do is to change the perspective origin of the container.
By default, the origin is set to center (vertically and horizontally).

Visit this page to learn how it works (it will be easier to understand) :
https://developer.mozilla.org/en-US/docs/Web/CSS/perspective-origin

 

Step 7

In the Code Block, add the perspective-origin CSS property:

.banner3d {
    perspective: 700px;
    transform-style: preserve-3d;
    perspective-origin: center calc(50% + var(--per));
}

We need some explanation here.
The syntax is : perspective-origin: x-position y-position;
Which is, by default, perspective-origin: center ( or perspective-origin: center center, or perspective-origin: 50% 50%. They are all the same).

We keep the x-position to center. But we need to change the y-position.
Remember, we are going to use the BasicScroll library, so we need a CSS Variable.

The variable will go from -1000px to 1000px. When the banner appears from the bottom of the screen, the variable will start at -1000px, then while we scroll down, the banner will go to the top and the variable will reach 1000px.
Which also means that the variable will be 0px when the banner is in the middle of the screen.

So the calculation for the perspective-origin (for the y-position only) is calc(50% + var(--per))

Step 8

in the same Code Block, but in the Javascript section, add this code:

const instance = basicScroll.create({
    elem: document.querySelector('.banner3d'),
    from: 'top-bottom',
    to: 'bottom-top',
    props: {
        '--per': {
            from: '-1000px',
            to: '1000px'
        }
    }
})

instance.start()

As you can see in the code, we have the variable --per , that will go from -1000px to 1000px.
You can of course change the data, it's just an example here.

So now, you can see the effect:

Whatever your want

Important Note

In this example, I set the rotation to 45deg and -45deg.
It's actually better with 90deg and -90deg (like the banners in the demo page).
But to explain and show how to build the object, it's easier when we can see the faces ;)

Important Note 2

The '25px' is actually the depth of the object. We can change it to make it look thicker.
But it means that you have to change it 5 times :

transform: translatez(25px);
height: 25px;
top:-25px;
height: 25px;
bottom:-25px;

So it can be a good idea to use a CSS variable for that too.

Here is the full CSS code:

:root {
    --depth: 25px;
}

.banner3d {
    perspective: 700px;
    transform-style: preserve-3d;
    perspective-origin: center calc(50% + var(--per));
}

.banner3d-front {
    transform: translatez(var(--depth));
    transform-style: preserve-3d;
}

.banner3d-front:before {
    position: absolute;
    content: "";
    width: 100%;
    left: 0;
    height: var(--depth);
    background-color: #BFBFBF;
    top: calc(var(--depth) * -1);
    transform-origin: center bottom;
    transform: rotatex(90deg);
}

.banner3d-front:after {
    position: absolute;
    content: "";
    width: 100%;
    left: 0;
    height: var(--depth);
    background-color: #BFBFBF;
    bottom: calc(var(--depth) * -1);
    transform-origin: center top;
    transform: rotatex(-90deg);
}
closealign-justifychevron-downcaret-up