While working on a website, I've incorporated a slight parallax effect that is functioning almost perfectly. However, I've noticed that the foreground divs tend to jump a little when scrolling down the page.
At the top of the page, there is a div called #top-banner with a fixed background image. Inside this div, there are two more divs placed in a row. The first div/column contains an image of a model, while the second div has text content.
Directly below the #top-banner div is another div with a background image depicting a waterline. The objective is to make it appear as if the waterline is covering the #top-banner as users scroll down, giving the illusion that the model, text, and background are submerged under water.
To achieve this effect, I used jQuery to adjust the CSS properties dynamically. By changing the bottom property of the columns divs, they appear to move downwards beneath the waterline at a speed relative to the user's scrolling motion. Small variations in speeds create the desired parallax effect.
Although the implementation works reasonably well, there are noticeable jitters. I attempted to use jQuery's animate function as well, but the result was even jerkier.
HTML
<section id="top-banner">
<div class="row">
<div class="col-2 prlx-1">
<img src="model.png"/>
</div>
<div class="r-col-2 prlx-2">
<h3>Lorem Ipsum</h1>
<p>More Ipsum</p>
</div>
</section>
<section id="hp-water-line"></section>
CSS
#hp-top-banner {
background: url(bg.png);
height: 600px;
background-attachment: fixed;
background-origin: initial;
background-clip: initial;
background-size: cover;
overflow: hidden;
width: 100%;
position: relative;
}
#hp-water-line {
background: url(water-line.png) no-repeat transparent;
min-height: 92px;
margin: 0 auto;
width: 100%;
position: relative;
top: -15px;
background-size: cover;
}
JS
$(document).ready(function(){
function parallax(){
var prlx_effect_1= -((window.pageYOffset / 4) *2.25 );
$('.prlx-1').css({"position": "relative","bottom":prlx_effect_1, "transition": "0s ease-in-out"});
// jQ('.prlx-1').css({"position": "relative"});
// jQ('.prlx-1').animate({"bottom":prlx_effect_1},"fast");
var prlx_effect_2= -(window.pageYOffset / 5 );
$('.prlx-2').css({"position": "relative","bottom":prlx_effect_2, "transition": "0s ease-in-out"});
}
window.addEventListener("scroll", parallax, false);
});
Updated JS based on Prinzhorn Comment
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
function onScroll() {
requestAnimationFrame(parallax);
}
function parallax(){
var prlx_effect_1= +(window.pageYOffset *.7).toFixed(2); // .55 is a good speed but slow
var prlx_str_1 = "translate3d(0, "+prlx_effect_1+"px, 0)";
jQ('.prlx-1').css({
"transform":prlx_str_1,
"-ms-transform":prlx_str_1,
"-webkit-transform":prlx_str_1
});
var prlx_effect_2= +(window.pageYOffset * 1 ).toFixed(2); // .33 is a good speed but slow
var prlx_str_2 = "translate3d(0, "+prlx_effect_2+"px, 0)";
jQ('.prlx-2').css({
"transform":prlx_str_2,
"-ms-transform":prlx_str_2,
"-webkit-transform":prlx_str_2
});
requestAnimationFrame(parallax);
}
window.addEventListener("scroll", onScroll, false);