Reveal photos on scroll on Location page

This commit is contained in:
2021-11-18 22:06:29 +01:00
parent 7900c124d2
commit fd871d55f9
3 changed files with 93 additions and 6 deletions

View File

@@ -27,7 +27,10 @@
const hasIllustration = location.illustration_desktop && location.illustration_desktop_2x && location.illustration_mobile const hasIllustration = location.illustration_desktop && location.illustration_desktop_2x && location.illustration_mobile
let introEl: HTMLElement let introEl: HTMLElement
let photosListEl: HTMLElement
let scrollY: number let scrollY: number
let observerPhotos: IntersectionObserver
let mutationPhotos: MutationObserver
let currentPage = 1 let currentPage = 1
let ended: boolean let ended: boolean
let currentPhotosAmount: number let currentPhotosAmount: number
@@ -138,6 +141,45 @@
translateY: ['10%', 0], translateY: ['10%', 0],
opacity: [0, 1], opacity: [0, 1],
}, 900 + ($navigating ? DURATION.PAGE_IN : 0)) }, 900 + ($navigating ? DURATION.PAGE_IN : 0))
// Photos IntersectionObserver
observerPhotos = new IntersectionObserver(entries => {
entries.forEach(({ isIntersecting, target }: IntersectionObserverEntry) => {
target.classList.toggle('is-visible', isIntersecting)
// Run effect once
isIntersecting && observerPhotos.unobserve(target)
})
}, {
threshold: 0.3,
rootMargin: '0px 0px 0px'
})
// Photos MutationObserver
mutationPhotos = new MutationObserver((mutationsList, observer) => {
// When adding new childs
for (const mutation of mutationsList) {
if (mutation.type === 'childList') {
// Observe new items
mutation.addedNodes.forEach((item: HTMLElement) => observerPhotos.observe(item))
}
}
})
mutationPhotos.observe(photosListEl, {
childList: true,
})
// Observe existing elements
const existingPhotos = photosListEl.querySelectorAll('.house')
existingPhotos.forEach(el => observerPhotos.observe(el))
// Destroy
return () => {
observerPhotos && observerPhotos.disconnect()
mutationPhotos && mutationPhotos.disconnect()
}
}) })
</script> </script>
@@ -220,7 +262,7 @@
</section> </section>
{#if photos.length} {#if photos.length}
<section class="location-page__houses grid"> <section class="location-page__houses grid" bind:this={photosListEl}>
{#each photos as { title, image: { id, title: alt }, slug, city, date_taken }, index} {#each photos as { title, image: { id, title: alt }, slug, city, date_taken }, index}
<div class="house grid"> <div class="house grid">
<div class="house__info"> <div class="house__info">

View File

@@ -244,16 +244,16 @@
isIntersecting && observerPhotos.unobserve(target) isIntersecting && observerPhotos.unobserve(target)
}) })
}, { }, {
threshold: 0, threshold: 0.3,
rootMargin: '0px 0px 0px' rootMargin: '0px 0px 0px'
}) })
// Photos MutationObserver // Photos MutationObserver
mutationPhotos = new MutationObserver((mutationsList, observer) => { mutationPhotos = new MutationObserver((mutationsList, observer) => {
// Use traditional 'for loops' for IE 11
for (const mutation of mutationsList) { for (const mutation of mutationsList) {
// When adding new childs
if (mutation.type === 'childList') { if (mutation.type === 'childList') {
console.log('A child node has been added or removed.') // Observe new items
mutation.addedNodes.forEach((item: HTMLElement) => observerPhotos.observe(item)) mutation.addedNodes.forEach((item: HTMLElement) => observerPhotos.observe(item))
} }
} }

View File

@@ -13,9 +13,11 @@
// Information // Information
&__info { &__info {
--delay: 0.2s;
grid-column: 1 / span var(--columns); grid-column: 1 / span var(--columns);
margin-bottom: 32px; margin-bottom: 32px;
padding: 0 20px; padding: 0 20px;
overflow: hidden;
@include bp (mob-lg) { @include bp (mob-lg) {
max-width: min(540px, 85vw); max-width: min(540px, 85vw);
@@ -27,11 +29,20 @@
max-width: 800px; max-width: 800px;
} }
h2 {
opacity: 0;
transform: translate3d(0, 25%, 0);
transition: transform 1.2s var(--ease-quart), opacity 1.2s var(--ease-quart);
transition-delay: var(--delay);
}
.info { .info {
display: block; display: block;
margin-top: 16px; margin-top: 16px;
color: $color-lightgray; color: $color-lightgray;
line-height: 1.5; line-height: 1.5;
opacity: 0;
transition: opacity 1.2s var(--ease-quart);
transition-delay: var(--delay);
@include bp (sm) { @include bp (sm) {
margin-top: 24px; margin-top: 24px;
@@ -57,6 +68,8 @@
position: relative; position: relative;
display: block; display: block;
grid-column: 1 / span 17; grid-column: 1 / span 17;
opacity: 0;
transition: opacity 2s var(--ease-quart);
@include bp (sm) { @include bp (sm) {
border-radius: 8px; border-radius: 8px;
@@ -69,8 +82,40 @@
img { img {
display: block; display: block;
width: 100%; width: 100%;
height: auto; height: 100%;
object-fit: contain; object-fit: cover;
transform: scale3d(1.125, 1.125, 1.125);
transition: transform 2s var(--ease-quart), opacity 1.2s var(--ease-quart);
will-change: transform;
}
// Scale down image on hover
a:hover {
img {
opacity: 0.6;
transform: scale3d(1.03, 1.03, 1.03) !important;
transition-duration: 1.2s;
}
}
}
// Visible state
&.is-visible {
.house__info {
h2 {
opacity: 1;
transform: translate3d(0,0,0);
}
.info {
opacity: 1;
}
}
.house__photo {
opacity: 1;
img {
transform: scale3d(1,1,1);
}
} }
} }