mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Website: update parallax component (#16521)
Closes: #16494 Changes: - Updated the parallax-city component to use jquery for DOM manipulation and event handlers. - Updated the names of functions in the parallax city component to match website naming conventions. - Removed the isMobile prop from the parallax-city component, it now uses bowser directly.
This commit is contained in:
parent
6c6364b5af
commit
50a6a64045
6 changed files with 43 additions and 63 deletions
|
|
@ -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;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
2
website/views/pages/device-management.ejs
vendored
2
website/views/pages/device-management.ejs
vendored
|
|
@ -211,6 +211,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<%/* Cloud city banner */%>
|
||||
<parallax-city :is-mobile="bowser.mobile"></parallax-city>
|
||||
<parallax-city></parallax-city>
|
||||
</div>
|
||||
<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>
|
||||
|
|
|
|||
2
website/views/pages/endpoint-ops.ejs
vendored
2
website/views/pages/endpoint-ops.ejs
vendored
|
|
@ -192,7 +192,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<%/* Cloud city banner */%>
|
||||
<parallax-city :is-mobile="bowser.mobile"></parallax-city>
|
||||
<parallax-city></parallax-city>
|
||||
<modal purpose="video-modal" v-if="modal === 'austin-anderson'" @close="closeModal()">
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/G5Ry_vQPaYc?si=vv0AfRe30yssWWRM&rel=0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
</modal>
|
||||
|
|
|
|||
2
website/views/pages/homepage.ejs
vendored
2
website/views/pages/homepage.ejs
vendored
|
|
@ -322,7 +322,7 @@
|
|||
|
||||
</div>
|
||||
<%/* Cloud city banner */%>
|
||||
<parallax-city :is-mobile="bowser.mobile"></parallax-city>
|
||||
<parallax-city></parallax-city>
|
||||
<modal purpose="video-modal" v-if="modal === 'austin-anderson'" @close="closeModal()">
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/G5Ry_vQPaYc?si=vv0AfRe30yssWWRM&rel=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
</modal>
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<%/* Cloud city banner */%>
|
||||
<parallax-city :is-mobile="bowser.mobile"></parallax-city>
|
||||
<parallax-city></parallax-city>
|
||||
<modal purpose="video-modal" v-if="modal === 'austin-anderson'" @close="closeModal()">
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/G5Ry_vQPaYc?si=vv0AfRe30yssWWRM&rel=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
</modal>
|
||||
|
|
|
|||
Loading…
Reference in a new issue