Website: enable parallax animation on cloud city image (#17104)
Changes: - Merged two layers of the parallax cloud city image & updated filenames. - Added a transition property to the parallax cloud city image to make the animation smoother when scrolling with a mouse wheel. - Updated the z-index of the website's footer to prevent the content from being hidden by the parallax image when it is at its starting position --------- Co-authored-by: Mike Thomas <78363703+mike-j-thomas@users.noreply.github.com>
BIN
website/assets/images/parallax-cloud-city/1-cloud-3840x456@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
website/assets/images/parallax-cloud-city/2-cloud-3840x456@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
website/assets/images/parallax-cloud-city/3-island-3840x456@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 467 KiB |
BIN
website/assets/images/parallax-cloud-city/3-island-7050x600@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 227 KiB |
BIN
website/assets/images/parallax-cloud-city/4-island-3840x456@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 65 KiB |
BIN
website/assets/images/parallax-cloud-city/5-island-3840x456@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
BIN
website/assets/images/parallax-cloud-city/6-cloud-3840x456@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 34 KiB |
BIN
website/assets/images/parallax-cloud-city/7-cloud-3840x456@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
|
@ -26,6 +26,7 @@ parasails.registerComponent('parallaxCity', {
|
|||
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.
|
||||
parallaxLayersAreCurrentlyAnimating: false,
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -35,14 +36,13 @@ parasails.registerComponent('parallaxCity', {
|
|||
template: `
|
||||
<div>
|
||||
<div purpose="parallax-city-container">
|
||||
<div class="parallax-layer" purpose="background-cloud-3" scroll-amount=12></div>
|
||||
<div class="parallax-layer" purpose="background-cloud-2" scroll-amount=28></div>
|
||||
<div class="parallax-layer" purpose="small-island-2" scroll-amount=20></div>
|
||||
<div class="parallax-layer" purpose="small-island-1" scroll-amount=40></div>
|
||||
<div class="parallax-layer" purpose="background-cloud-1" scroll-amount=40></div>
|
||||
<div class="parallax-layer" purpose="large-island" scroll-amount=60></div>
|
||||
<div class="parallax-layer" purpose="foreground-cloud-2" scroll-amount=100></div>
|
||||
<div class="parallax-layer" purpose="foreground-cloud-1" scroll-amount=120></div>
|
||||
<div class="parallax-layer" purpose="background-cloud-2" scroll-amount=4></div>
|
||||
<div class="parallax-layer" purpose="background-cloud-1" scroll-amount=6></div>
|
||||
<div class="parallax-layer" purpose="small-island-2" scroll-amount=16></div>
|
||||
<div class="parallax-layer" purpose="small-island-1" scroll-amount=12></div>
|
||||
<div class="parallax-layer" purpose="large-island" scroll-amount=24></div>
|
||||
<div class="parallax-layer" purpose="foreground-cloud-2" scroll-amount=32></div>
|
||||
<div class="parallax-layer" purpose="foreground-cloud-1" scroll-amount=40></div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
|
@ -54,26 +54,26 @@ parasails.registerComponent('parallaxCity', {
|
|||
|
||||
},
|
||||
mounted: async function(){
|
||||
// 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});
|
||||
// }
|
||||
// // 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);
|
||||
// }
|
||||
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});
|
||||
}
|
||||
// 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.throttleParallaxScroll);
|
||||
// Add a resize event listener.
|
||||
$(window).resize(this.getElementPositions);
|
||||
}
|
||||
},
|
||||
beforeDestroy: function() {
|
||||
|
||||
|
|
@ -83,25 +83,34 @@ parasails.registerComponent('parallaxCity', {
|
|||
// ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗
|
||||
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
|
||||
methods: {
|
||||
// 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;
|
||||
// },
|
||||
// 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;
|
||||
// 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)');
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
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;
|
||||
},
|
||||
scrollParallaxLayers: function() {
|
||||
if(!this.parallaxLayersAreCurrentlyAnimating) {
|
||||
this.parallaxLayersAreCurrentlyAnimating = true;
|
||||
// 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;
|
||||
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)');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
throttleParallaxScroll: function() {
|
||||
this.scrollParallaxLayers();
|
||||
setTimeout(()=>{
|
||||
this.parallaxLayersAreCurrentlyAnimating = false;
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,73 +15,60 @@
|
|||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
[purpose='parallax-city-container'] {
|
||||
background-image: url('/images/parallax-cloud-city/cloud-city-static-7050x600@2x.png');
|
||||
background-size: cover;
|
||||
background-position: center bottom;
|
||||
background-repeat: no-repeat;
|
||||
height: 600px;
|
||||
height: 456px;
|
||||
position: relative;
|
||||
// .parallax-layer {
|
||||
// position: absolute;
|
||||
// right: 0;
|
||||
// bottom: -1px;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// will-change: transform;
|
||||
// background-size: auto 100%;
|
||||
// }
|
||||
// [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;
|
||||
// }
|
||||
// [purpose='foreground-cloud-2'] {
|
||||
// background-image: url('/images/parallax-cloud-city/2-cloud-7050x600@2x.png');
|
||||
// background-position: center bottom;
|
||||
// background-repeat: no-repeat;
|
||||
// z-index: 99;
|
||||
// }
|
||||
// [purpose='large-island'] {
|
||||
// background-image: url('/images/parallax-cloud-city/4-island-7050x600@2x.png');
|
||||
// background-position: center bottom;
|
||||
// background-repeat: no-repeat;
|
||||
// z-index: 97;
|
||||
// }
|
||||
// [purpose='background-cloud-1'] {
|
||||
// background-image: url('/images/parallax-cloud-city/5-cloud-7050x600@2x.png');
|
||||
// background-position: center bottom;
|
||||
// background-repeat: no-repeat;
|
||||
// z-index: 96;
|
||||
// }
|
||||
// [purpose='small-island-1'] {
|
||||
// background-image: url('/images/parallax-cloud-city/6-island-7050x600@2x.png');
|
||||
// background-position: center bottom;
|
||||
// background-repeat: no-repeat;
|
||||
// z-index: 95;
|
||||
// }
|
||||
// [purpose='small-island-2'] {
|
||||
// background-image: url('/images/parallax-cloud-city/7-island-7050x600@2x.png');
|
||||
// background-position: center bottom;
|
||||
// background-repeat: no-repeat;
|
||||
// z-index: 95;
|
||||
// }
|
||||
// [purpose='background-cloud-2'] {
|
||||
// background-image: url('/images/parallax-cloud-city/8-cloud-7050x600@2x.png');
|
||||
// background-position: center bottom;
|
||||
// background-repeat: no-repeat;
|
||||
// z-index: 1;
|
||||
// }
|
||||
// [purpose='background-cloud-3'] {
|
||||
// background-image: url('/images/parallax-cloud-city/9-cloud-7050x600@2x.png');
|
||||
// background-position: center bottom;
|
||||
// background-repeat: no-repeat;
|
||||
// z-index: 1;
|
||||
// }
|
||||
}
|
||||
@media (max-width: 1399px) {
|
||||
[purpose='parallax-city-container'] {
|
||||
height: 500px;
|
||||
.parallax-layer {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -1px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
will-change: transform;
|
||||
background-size: auto 100%;
|
||||
transition: 0.1s smooth;
|
||||
transition-property: all;
|
||||
}
|
||||
[purpose='foreground-cloud-1'] {
|
||||
background-image: url('/images/parallax-cloud-city/1-cloud-3840x456@2x.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: repeat-x;
|
||||
z-index: 100;
|
||||
}
|
||||
[purpose='foreground-cloud-2'] {
|
||||
background-image: url('/images/parallax-cloud-city/2-cloud-3840x456@2x.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: repeat-x;
|
||||
z-index: 99;
|
||||
}
|
||||
[purpose='large-island'] {
|
||||
background-image: url('/images/parallax-cloud-city/3-island-3840x456@2x.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 97;
|
||||
}
|
||||
[purpose='small-island-1'] {
|
||||
background-image: url('/images/parallax-cloud-city/4-island-3840x456@2x.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 95;
|
||||
}
|
||||
[purpose='small-island-2'] {
|
||||
background-image: url('/images/parallax-cloud-city/5-island-3840x456@2x.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 95;
|
||||
}
|
||||
[purpose='background-cloud-1'] {
|
||||
background-image: url('/images/parallax-cloud-city/6-cloud-3840x456@2x.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: no-repeat;
|
||||
z-index: 1;
|
||||
}
|
||||
[purpose='background-cloud-2'] {
|
||||
background-image: url('/images/parallax-cloud-city/7-cloud-3840x456@2x.png');
|
||||
background-position: center bottom;
|
||||
background-repeat: repeat-x;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
|
|
|
|||
6
website/assets/styles/layout.less
vendored
|
|
@ -20,9 +20,7 @@ html, body {
|
|||
}
|
||||
|
||||
[purpose='header-background'] {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(15px);
|
||||
-webkit-backdrop-filter: blur(15px);
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
// Styles for the page header
|
||||
|
|
@ -331,6 +329,8 @@ html, body {
|
|||
margin-left: -8px;
|
||||
margin-right: -8px;
|
||||
margin-bottom: 80px;
|
||||
position: relative;
|
||||
z-index: 101;
|
||||
}
|
||||
|
||||
[purpose='footer-nav-header'] {
|
||||
|
|
|
|||