JavaScript Parallax Scrolling Effect
Tags: webdev, ux, design, javascript
Published: 2021-01-29 15:12:27

### <center>JavaScript Parallax Scrolling Effect</center>

------------

#### <center>Browse our [Teachable](http://anobject.teachable.com "Teachable") courses.</center>

------------

![JavaScript Parallax Scrolling Effect](https://user-images.githubusercontent.com/58220766/105657672-eda23980-5e92-11eb-97df-a5587afc92e7.png)

### The general solution we're working with is this:

We are going to **fix** an HTML element on page (***in this case a DIV shaped like a circle***).

When we scroll our page **down**, we'll manually scroll the HTML element **up**.

Since we are manually scrolling our element up, we can control how fast or slow it moves.

This creates our **parallax effect**.

#### Let's get our HTML and CSS written.

**Normalize the page and make it vertically long so we have scroll space.**

```
body {
    overflow-x: hidden;
    width: 100vw;
    height: 300vh;
    background-size: contain;
    background-image: url('./back.png');
}
```

**Create a DIV...**

```
<body>
    <div class="orb"></div>
</body>
```

**that we'll style into a circle.**

```
.orb {
    margin: 0;
    padding: 0;
    height: 200px;
    width: 200px;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background-color: #0083FF;
    box-shadow: 0px 0px 20px 10px #0083FF;
}
```

------------

### Let's get on to the JavaScript.

#### We'll need 6 variables for this project.

```
const orb = document.querySelector('.orb'),
    ease = 0.05,
    start_position = orb.offsetTop;

let scroll_request = 0,
    total_offset = 0,
    animation_running = false;
```

1. **orb** - the HTML element we want to move
2. **ease** - we control how fast or slow the HTML element scrolls relative to our page
3. **start_position** - where does this element start (***y position***) relative to the top of the document/page
4. **scroll_request** - when we scroll our page, we want to tell our program to then scroll our HTML element
5. **total_offset** - we keep track of how far, in total, we have scrolled up or down
6. **animation_running** - we use this to get our **requestAnimationFrame() loop** to start and stop

#### Let's build the logic for starting our animation loop.

```
function animate_scroll() {
    scroll_request++;

    if (!animation_running) {
        animation_running = true;
        animation_loop();
    }
}
```

**Every time we scroll our page, we want to scroll our HTML element(s).**

If we scroll 100 clicks of our wheel, we want to make sure we **put in a request to scroll our HTML element(s) 100 times as well**.

```
scroll_request++;
```

If there is no animation loop currently running, we'll start one; making sure to switch our **animation_running** to **true**.

```
if (!animation_running) {
    animation_running = true;
    animation_loop();
}
```

#### Let's create the actual animation loop.

```
function animation_loop() {
    let current_offset = window.pageYOffset;

    let difference = current_offset - total_offset;
    different *= ease;

    if (Math.abs(difference) < 0.05) {
        scroll_request = 0;

        total_offset = current_offset;
        animation_running = false;
        return;
    }

    orb.style.top = `${start_position - total_offset}px`;
    total_offset += difference;

    requestAnimationFrame(animation_loop);
}
```

**We do 4 major things here (not in this order).**

1. Calculate the **difference** between the current position of our document and the top of our page/document.

**Where our page starts.**

![initial_pageOffset](https://user-images.githubusercontent.com/58220766/103390897-c8651a00-4ae4-11eb-877c-1dc7cd163eb2.png)

**How we calculate the difference.**

![difference_calculation_example](https://user-images.githubusercontent.com/58220766/103390909-ddda4400-4ae4-11eb-9d00-c43790373b45.png)

2. Move our HTML by that **difference**. (***the difference is multiplied by our **ease** to create our parallax effect ***)
3. Request another loop for our animation.
4. Our **exit clause** for the animation loop is if the **difference** is less than **0.05**. Basically if the HTML element has reached its destination.

------------

### We can use this logic for any type of HTML element.

#### DIVs, paragraphs, spans, images...

You can get the source file [here](https://github.com/an-object-is-a/js-parallax-scroll "here").

------------

#### <center>If you want a more in-depth guide, check out my full video tutorial on YouTube, **[An Object Is A](https://www.youtube.com/c/anobjectisa "An Object Is A")**.</center>

### <center>JavaScript Parallax Scrolling Effect</center>

{% youtube HQ68W5t5_5Y %}