JavaScript Parallax Scrolling Effect
Browse our Teachable courses.
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;
- orb - the HTML element we want to move
- ease - we control how fast or slow the HTML element scrolls relative to our page
- start_position - where does this element start (y position) relative to the top of the document/page
- scroll_request - when we scroll our page, we want to tell our program to then scroll our HTML element
- total_offset - we keep track of how far, in total, we have scrolled up or down
- 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).
- Calculate the difference between the current position of our document and the top of our page/document.
Where our page starts.
How we calculate the difference.
- Move our HTML by that difference. (*the difference is multiplied by our **ease to create our parallax effect ***)
- Request another loop for our animation.
- 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.
If you want a more in-depth guide, check out my full video tutorial on YouTube, An Object Is A.
JavaScript Parallax Scrolling Effect
Top comments (0)