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>
This commit is contained in:
Eric 2024-03-06 01:28:11 -06:00 committed by GitHub
parent fa093203df
commit 30a36b0b3a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 113 additions and 117 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View file

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View file

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -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);
}
}
});

View file

@ -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) {

View file

@ -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'] {