diff --git a/website/assets/js/components/parallax-city.component.js b/website/assets/js/components/parallax-city.component.js
index b96cb58435..f023d03fff 100644
--- a/website/assets/js/components/parallax-city.component.js
+++ b/website/assets/js/components/parallax-city.component.js
@@ -13,19 +13,19 @@ parasails.registerComponent('parallaxCity', {
// ╔═╗╦═╗╔═╗╔═╗╔═╗
// ╠═╝╠╦╝║ ║╠═╝╚═╗
// ╩ ╩╚═╚═╝╩ ╚═╝
- props: ['isMobile'],
+ props: [],
// ╦╔╗╔╦╔╦╗╦╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗
// ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣
// ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝
data: function (){
return {
- parallaxCityElement: undefined,
- elementBottomPosition: undefined,
- elementHeight: undefined,
- distanceFromTopOfPage: undefined,
- distanceFromBottomOfPage: undefined,
- isAnimating: false,
+ parallaxCityElement: undefined,// For storing a jquery reference to the paralax-city-container div.
+ parallaxLayers: [],// Stores an array of dictionaries, each containing a reference to a parallax-layer element, and the scroll-amount attribute
+ elementBottomPosition: undefined,// For keeping track of the bottom position of the parllax image.
+ elementHeight: undefined,// For keeping track of how large the parallax image element's height
+ distanceFromTopOfPage: undefined, // Used to check if the image is within the user's viewport.
+ distanceFromBottomOfPage: undefined, // Used to track the amount of distance between the bottom of the image, and the bottom of the page.
};
},
@@ -54,73 +54,54 @@ parasails.registerComponent('parallaxCity', {
},
mounted: async function(){
- if(!this.isMobile){
- this.parallaxCityElement = document.querySelector('[purpose="parallax-city-container"]');
- this.elementHeight = this.parallaxCityElement.clientHeight;
- this.distanceFromTopOfPage = this.parallaxCityElement.offsetTop;
- this.distanceFromBottomOfPage = document.body.scrollHeight - this.distanceFromTopOfPage - (this.elementHeight * .5);
- this.elementBottomPosition = this.elementHeight + this.distanceFromTopOfPage;
- let parallaxCityElementPosition = this.parallaxCityElement.getBoundingClientRect();
- if(parallaxCityElementPosition.bottom > this.distanceFromTopOfPage) {
- this.handleParallaxScroll();
+ if(!bowser.isMobile){
+ // Store a reference to the parent container, we'll use this to determine the elements position relative to the user's viewport.
+ this.parallaxCityElement = $('div[purpose="parallax-city-container"]')[0];
+ // Build an array of parallax layers, and set the initial bottom position of each layer to be negative the layer's scroll amount.
+ for(let layer of $('div.parallax-layer')) {
+ let scrollAmount = Number($(layer).attr('scroll-amount'));
+ $(layer).css('bottom', `-${scrollAmount}px`);
+ this.parallaxLayers.push({element: layer, scrollAmount});
}
-
- this.parallaxCityElement.querySelectorAll('div.parallax-layer').forEach((layer)=>{
- let initialPosition = layer.getAttribute('scroll-amount');
- layer.style.bottom = `-${Number(initialPosition) + 4}px`;
- });
-
- window.addEventListener('scroll', this.onScroll);
- window.addEventListener('resize', this.updateElementPositions);
- window.addEventListener('orientationchange', this.updateElementPositions);
+ // Determine the parallax image's position on the page/user's viewport.
+ this.getElementPositions();
+ // If the bottom of the element is within the user's viewport, update the positions of the layers.
+ if(this.parallaxCityElement.getBoundingClientRect().bottom > this.parallaxCityElement.offsetTop) {
+ this.scrollParallaxLayers();
+ }
+ // Add a scroll event listener
+ $(window).scroll(this.scrollParallaxLayers);
+ // Add a resize event listener.
+ $(window).resize(this.getElementPositions);
}
},
beforeDestroy: function() {
- if(!this.isMobile){
- window.removeEventListener('scroll', this.onScroll);
- window.removeEventListener('resize', this.updateElementPositions);
- window.removeEventListener('orientationchange', this.updateElementPositions);
- }
+
},
// ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
methods: {
- updateElementPositions: function() {
+ getElementPositions: function() {
this.elementHeight = this.parallaxCityElement.clientHeight;
this.distanceFromTopOfPage = this.parallaxCityElement.offsetTop;
+ this.distanceFromBottomOfPage = document.body.scrollHeight - this.distanceFromTopOfPage - (this.elementHeight * .5);
this.elementBottomPosition = this.elementHeight + this.distanceFromTopOfPage;
},
- onScroll: function() {
- if(!this.isAnimating){
- this.isAnimating = true;
- window.requestAnimationFrame(this.handleParallaxScroll);
- }
- return;
- },
- handleParallaxScroll: function() {
- let viewportBottom = window.scrollY + window.innerHeight;
- let percentageScrolled;
- if (this.parallaxCityElement.offsetTop < viewportBottom) {
- let visibleHeight = viewportBottom - Math.max(this.distanceFromTopOfPage, window.scrollY);
- percentageScrolled = visibleHeight / (this.distanceFromBottomOfPage + (this.elementHeight / 2 ));
- } else {
- percentageScrolled = 0;
- }
- if(percentageScrolled > 1){
- percentageScrolled = 1;
- }
- percentageScrolled = percentageScrolled.toFixed(4);
- if(percentageScrolled > .25){// When the element has been scrolled down 25%, start adjusting the position of layers.
+ scrollParallaxLayers: function() {
+ // Calculate how much of the parallax image is visible.
+ let visibleHeight = (window.scrollY + window.innerHeight) - Math.max(this.distanceFromTopOfPage, window.scrollY);
+ let percentageScrolled = visibleHeight / (this.distanceFromBottomOfPage + (this.elementHeight / 2 ));
+ // When the element has been scrolled down 25%, iterate through the layers and update their positions.
+ if(percentageScrolled > .25 ){
let adjustedPercentage = (percentageScrolled - .25) * 4/3;
- this.parallaxCityElement.querySelectorAll('div.parallax-layer').forEach((layer) => {
- let scrollAmount = layer.getAttribute('scroll-amount');
- let movement = adjustedPercentage * scrollAmount;
- layer.style.transform = 'translateY(-' + movement + 'px)';
- });
+ for(let layer of this.parallaxLayers) {
+ let movement = Math.min(adjustedPercentage * layer.scrollAmount, layer.scrollAmount);
+ // Update the position of each layer.
+ $(layer.element).css('transform', 'translate3D(0, -' + movement + 'px, 0)');
+ }
}
- this.isAnimating = false;
},
}
});
diff --git a/website/assets/styles/components/parallax-city.component.less b/website/assets/styles/components/parallax-city.component.less
index b9ed8f2366..8becc971ca 100644
--- a/website/assets/styles/components/parallax-city.component.less
+++ b/website/assets/styles/components/parallax-city.component.less
@@ -28,7 +28,6 @@
}
[purpose='foreground-cloud-1'] {
background-image: url('/images/parallax-cloud-city/1-cloud-7050x600@2x.png');
-
background-position: center bottom;
background-repeat: no-repeat;
z-index: 100;
diff --git a/website/views/pages/device-management.ejs b/website/views/pages/device-management.ejs
index f1b27f1441..84bef812c6 100644
--- a/website/views/pages/device-management.ejs
+++ b/website/views/pages/device-management.ejs
@@ -211,6 +211,6 @@
<%/* Cloud city banner */%>
-
+
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
diff --git a/website/views/pages/endpoint-ops.ejs b/website/views/pages/endpoint-ops.ejs
index bf4758fd48..fb63338124 100644
--- a/website/views/pages/endpoint-ops.ejs
+++ b/website/views/pages/endpoint-ops.ejs
@@ -192,7 +192,7 @@
<%/* Cloud city banner */%>
-
+
diff --git a/website/views/pages/homepage.ejs b/website/views/pages/homepage.ejs
index e7008e3082..9a4f1cfb8e 100644
--- a/website/views/pages/homepage.ejs
+++ b/website/views/pages/homepage.ejs
@@ -322,7 +322,7 @@
<%/* Cloud city banner */%>
-
+
diff --git a/website/views/pages/vulnerability-management.ejs b/website/views/pages/vulnerability-management.ejs
index c3323fcde9..04aadf0c57 100644
--- a/website/views/pages/vulnerability-management.ejs
+++ b/website/views/pages/vulnerability-management.ejs
@@ -151,7 +151,7 @@
<%/* Cloud city banner */%>
-
+