Installing Parallax Scrolling

Automatic Installation

Include the following script: /includes/parallax/parallax.js. This will automatically enable parallax effects on elements that have a class of either parallax or parallax_bg within an ancestor that has an id of mainContainer. If mainContainer doesn't exist and another container needs to be used, after including the script you can add the following in a script block:

perpetuacms.parallax.init(document.querySelector("#someContainerId"));

Manual Installation

Alternatively, include the following under the script tag before the closing </body> tag:

//Parallax Effects
var parallax = (() => {

	const container = $("mainContainer");
	const parallax_elements = container.select(".parallax");
	const parallax_elements_bg = container.select(".parallax_bg");

	let scrolled = document.viewport.getScrollOffsets().top;

	Element.prototype.parallax = function(rate,start,stop,orientation,opacity){
		if (scrolled >= start && scrolled <= stop && document.viewport.getWidth() > 400){
			this.pos = (scrolled * rate).toFixed(2) - (start * rate);
			if (orientation == "horizontal") {
				this.transform = "translate(" + this.pos + "px, 0px)";
			} else {
				this.transform = "translate(0px," + this.pos + "px)";
			}
			if (opacity == 1) {
				this.opacity = (100 - scrolled * (100/(stop - start))) / 100;
			} else {
				this.opacity = 1;
			}
			this.setStyle({
				"transform": this.transform,
				"opacity": this.opacity,
			});
		} else if (scrolled <= start){
			this.pos = start * rate;
			this.transform = "translate(0px, 0px)";
			this.opacity = 1;
			this.setStyle({
				"transform": this.transform,
				"opacity": this.opacity,
			});
		};
	};
	Element.prototype.parallax_bg = function(rate,start,stop,offset,opacity){
		if (scrolled >= start && scrolled <= stop && document.viewport.getWidth() > 768){
			this.travel = (stop - start) * rate;
			this.offset = offset;
			this.pos = (scrolled * rate).toFixed(2) - (offset * rate);
			this.setStyle({
				"background-position": "center " + this.pos + "px",
			});
		} else if (scrolled <= start){
			this.travel = (stop - start) * rate;
			this.offset = this.travel / 2;
			this.pos = start;
			this.setStyle({
				"background-position": "center " + this.pos + "px",
			});
		};
	};

	const calculate = () => {
		scrolled = document.viewport.getScrollOffsets().top;
		
		parallax_elements.each(function(section){
			var rate = section.dataset.rate || -0.2;
			var orientation =  section.dataset.orientation || "vertical";
			var offset =  section.cumulativeOffset().top;
			var top = offset - document.viewport.getHeight();
			var bottom = offset + document.viewport.getHeight();
			section.parallax(rate,top,bottom,orientation,0);
		});
		parallax_elements_bg.each(function(section){
			var rate = section.dataset.rate || -0.2;
			var offset =  section.cumulativeOffset().top;
			var top = offset - document.viewport.getHeight();
			var bottom = offset + document.viewport.getHeight();
			section.parallax_bg(rate,top,bottom,offset,0);
		});
	}
	
	calculate();

	$(document).on("scroll", calculate);
	
	return {
		calculate: calculate
	}
})();
 
 

Activate

To activate the parallax effect on an element, give it a class of parallax and set a data-rate attribute (default is data-rate="-0.2") and style as needed in CSS.

 

Background Image Parallax Effect

To apply the effect to a background image instead of an element, set the class name on your div to parallax_bg instead of parallax and set a --parallax-image CSS custom property on it's parent. For example:

<div style="--parallax-image: url('/images/someimage.png');">
    <div class="parallax_bg"></div>
</div>

Additional Notes

Using the /includes/parallax/parallax.js script (Automatic Installation) will add a parallaxing class to the body element when the parallax effect is enabled which can be used to set styles on any element. onceaccounting.com uses this on /home-2022 to set a negative margin-top on the parallax elements to fix some spacing.

Note: Parallaxing is disabled when the browser window width goes below 768px to prevent issues on mobile, and therefore the parallaxing class is removed from the body element. For parallax_bg elements, this is why the --parallax-image custom property needs to be on it's parent, otherwise the image will be removed.