I have a problem with a parallax animation i made. The effect works as follows:
There are 2 sections surrounding a parallax element. This parallax element will be moved if a scroll event was triggered.
How fast the element is going to move is defined by a speed value. This value should be something between -1 and 1. So the element will move down if the speed is positive and up if it's negative.
To prevent a gap between the sections and the parallax element a new height will be calculated for the moving element, so it won't show the gap until the element is no longer visible within the viewport.
This works just fine if the speed value is positive and the element is moving downwards, but my problem is: if I change the speed to a negative value, the calculations for the height and position of the parallax element are no longer valid and the gap is still there.
My thought was that the calculation for the height of this element is wrong, because it's too small, but i can't get it to work :(
Maybe some of you knows exactly where the problem is. I would really appreciate an answer :) Sitting on this problem for days.
Fiddle: https://jsfiddle.net/xs74pmvq/
Thank you in advance.
var parallaxElement = document.querySelector('#parallax-element');
var parallaxContainer = parallaxElement.parentNode;
var containerHeight = parallaxContainer.offsetHeight;
/**
* The speed of the parallax element. Currently ony working
* with positive values.
*
* Change this to -[0-1] to see the gap between the parallax
* element and the surrounding sections.
*
* @todo(Hero): Make negative values working.
*/
var parallaxSpeed = 0.5;
/**
* This calculates the new height of the given parallax element.
* The height is used to fill up the gap between the two sections.
* It allows the parallax element to move without showing a space.
* The height is calculated by the given speed
*/
function setParallaxHeight(element) {
var gapHeight = containerHeight - window.innerHeight;
var newHeight = containerHeight + gapHeight * Math.abs(parallaxSpeed);
// @todo(Hero): Maybe change the calculation for negative speed values.
element.style.height = newHeight + 'px';
}
/**
* This simply sets the translation value of the parallax element.
*/
function updateElement() {
var scrollY = window.scrollY;
var elementOffset = parallaxElement.getBoundingClientRect();
var elementTop = elementOffset.top + scrollY;
/**
* This is the translation value on the y axis. This will start
* the element moving above the lower bound of the viewport after
* the user scrolled to the edge of the element.
*/
var translateY = parallaxSpeed * (scrollY - elementTop);
// @todo(Hero): Maybe change the calculation for negative speed values.
parallaxElement.style.transform = 'translate3d(0,' + translateY + 'px,0)';
}
setParallaxHeight(parallaxElement);
window.onscroll = updateElement;
.section {
width: 100vw;
height: 100vh;
}
.section1 {
background-color: gray;
}
.section2 {
height: 1000px;
}
.section3 {
height: 3000px;
background-color: green;
}
.parallax-container {
height: 100%;
width: 100%;
overflow: hidden;
}
#parallax-element {
width: 100%;
height: 50%;
background: url('https://static.vecteezy.com/system/resources/previews/000/093/696/original/vector-yellow-abstract-background.jpg') no-repeat center;
background-size: cover;
}
<div class="section section1">Scroll down</div>
<div class="section section2">
<div class="parallax-container">
<div id="parallax-element"></div>
</div>
</div>
<div class="section section3">Section2</div>
Fixed it.
Updated the calculations for the translation and the height of the parallax element. This calculations are special cases for negative speed values.
Calculation for the translation:
translateY = parallaxSpeed * (scrollY + window.innerHeight - elementTop);
Calculation for the gap:
gapHeight = (containerHeight + window.innerHeight) / (1 + parallaxSpeed);
Updated fiddle: https://jsfiddle.net/xs74pmvq/