fix: various issues to reduce effect_update_depth_exceeded
+ use `scroll` from Motion One for parallax
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
let scrollY = $state<number>()
|
||||
let innerWidth = $state<number>()
|
||||
let innerHeight = $state<number>()
|
||||
let titleEl = $state<HTMLElement>()
|
||||
let titleEl: HTMLElement
|
||||
|
||||
// Check if title is larger than viewport to translate it
|
||||
const isLarger = $derived<boolean>(titleEl && titleEl.offsetWidth >= innerWidth)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
const { settings }: any = getContext('global')
|
||||
|
||||
let locationEl = $state<HTMLElement>()
|
||||
let locationEl: HTMLElement
|
||||
let photoIndex = $state(0)
|
||||
|
||||
// Location date limit
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
const { settings: { switcher_links } }: any = getContext('global')
|
||||
|
||||
let switcherEl = $state<HTMLElement>()
|
||||
let switcherEl: HTMLElement
|
||||
let isOpen = $state(false)
|
||||
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
} = $props()
|
||||
|
||||
let innerWidth = $state<number>()
|
||||
let globeParentEl = $state<HTMLElement>()
|
||||
let globeEl = $state<HTMLElement>()
|
||||
let globeParentEl: HTMLElement
|
||||
let globeEl: HTMLElement
|
||||
let globe = $state<any>()
|
||||
let observer: IntersectionObserver
|
||||
let animation = $state<number>()
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
let innerWidth = $state<number>()
|
||||
let navObserver: IntersectionObserver
|
||||
let introEl = $state<HTMLElement>()
|
||||
let navChooseEl = $state<HTMLElement>()
|
||||
let introEl: HTMLElement
|
||||
let navChooseEl: HTMLElement
|
||||
let scrolledPastIntro = $state(false)
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<script lang="ts">
|
||||
import { PUBLIC_LIST_INCREMENT } from '$env/static/public'
|
||||
import { page, navigating } from '$app/stores'
|
||||
import { stagger, timeline } from 'motion'
|
||||
import { scroll, stagger, timeline } from 'motion'
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import { quartOut } from '$animations/easings'
|
||||
@@ -13,6 +13,7 @@
|
||||
import { DELAY } from '$utils/constants'
|
||||
import { seenLocations } from '$utils/stores'
|
||||
import { photoFields } from '$utils/api'
|
||||
import { lerp } from 'utils/math'
|
||||
import { padZero } from 'utils/string'
|
||||
// Components
|
||||
import Metas from '$components/Metas.svelte'
|
||||
@@ -34,14 +35,13 @@
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
let introEl = $state<HTMLElement>()
|
||||
let introEl: HTMLElement
|
||||
let photosListEl = $state<HTMLElement>()
|
||||
let scrollY = $state<number>()
|
||||
let observerPhotos: IntersectionObserver
|
||||
let mutationPhotos: MutationObserver
|
||||
let currentPage = $state(1)
|
||||
let currentPhotosAmount = $derived(photos.length)
|
||||
let heroOffsetY = $state(0)
|
||||
let heroParallax = $state(0)
|
||||
|
||||
const ended = $derived(currentPhotosAmount === totalPhotos)
|
||||
const latestPhoto = $derived(photos[0])
|
||||
@@ -50,23 +50,7 @@
|
||||
/**
|
||||
* Load photos
|
||||
*/
|
||||
/** Load more photos from CTA */
|
||||
const loadMorePhotos = async () => {
|
||||
// Append more photos from API
|
||||
const newPhotos: any = await loadPhotos(currentPage + 1)
|
||||
|
||||
if (newPhotos) {
|
||||
photos = [...photos, ...newPhotos]
|
||||
|
||||
// Define actions if the number of new photos is the expected ones
|
||||
if (newPhotos.length === Number(PUBLIC_LIST_INCREMENT)) {
|
||||
// Increment the current page
|
||||
currentPage++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load photos helper
|
||||
/** Load photos helper */
|
||||
const loadPhotos = async (page?: number) => {
|
||||
const res = await fetch('/api/data', {
|
||||
method: 'POST',
|
||||
@@ -94,15 +78,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** Load more photos from CTA */
|
||||
const loadMorePhotos = async () => {
|
||||
// Append more photos from API
|
||||
const newPhotos: any[] = await loadPhotos(currentPage + 1)
|
||||
|
||||
/**
|
||||
* Add parallax on illustration when scrolling
|
||||
*/
|
||||
$effect(() => {
|
||||
if (scrollY && scrollY < introEl.offsetHeight) {
|
||||
heroOffsetY = scrollY * 0.1
|
||||
if (newPhotos) {
|
||||
photos = [...photos, ...newPhotos]
|
||||
|
||||
// Define actions if the number of new photos is the expected ones
|
||||
if (newPhotos.length === Number(PUBLIC_LIST_INCREMENT)) {
|
||||
// Increment the current page
|
||||
currentPage++
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
$effect(() => {
|
||||
@@ -147,6 +137,15 @@
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add parallax on illustration when scrolling
|
||||
*/
|
||||
scroll(({ y }) => heroParallax = lerp(-15, 10, y.progress), {
|
||||
target: introEl,
|
||||
offset: ['start end', 'end start'],
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* Animations
|
||||
*/
|
||||
@@ -205,8 +204,6 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window bind:scrollY />
|
||||
|
||||
<Metas
|
||||
title="Houses Of {location.name}"
|
||||
description="Discover {totalPhotos} beautiful homes from {location.name}, {location.country.name}"
|
||||
@@ -215,7 +212,7 @@
|
||||
|
||||
|
||||
<main class="location-page">
|
||||
<section class="location-page__intro grid" bind:this={introEl}>
|
||||
<section bind:this={introEl} class="location-page__intro grid">
|
||||
<h1 class="title" class:is-short={location.name.length <= 4}>
|
||||
<span class="housesof mask">
|
||||
<strong class="word">Houses</strong>
|
||||
@@ -269,7 +266,7 @@
|
||||
</div>
|
||||
|
||||
{#if location?.hero?.id}
|
||||
<picture class="location-page__hero" style:--parallax-y="{heroOffsetY}px">
|
||||
<picture class="location-page__hero" style:--parallax="{heroParallax}%">
|
||||
<source media="(min-width: 1200px)" srcset={getAssetUrlKey(location.hero.id, 'hero-large')}>
|
||||
<source media="(min-width: 768px)" srcset={getAssetUrlKey(location.hero.id, 'hero-small')}>
|
||||
<img
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
import { navigating } from '$app/stores'
|
||||
import { quartOut as quartOutSvelte } from 'svelte/easing'
|
||||
import { fade, fly } from 'svelte/transition'
|
||||
import { animate, inView, stagger, timeline } from 'motion'
|
||||
import { animate, inView, scroll, stagger, timeline } from 'motion'
|
||||
import { mailtoClipboard } from '$utils/functions'
|
||||
import { getAssetUrlKey } from '$utils/api'
|
||||
import { DELAY } from '$utils/constants'
|
||||
import { map } from 'utils/math'
|
||||
import { lerp } from 'utils/math'
|
||||
import { sendEvent } from '$utils/analytics'
|
||||
import { quartOut } from '$animations/easings'
|
||||
// Components
|
||||
@@ -23,16 +23,13 @@
|
||||
|
||||
let { data } = $props()
|
||||
|
||||
let scrollY = $state<number>()
|
||||
let innerWidth = $state<number>()
|
||||
let innerHeight = $state<number>()
|
||||
let photosGridEl = $state<HTMLElement>()
|
||||
let photosGridOffset = $state<number>()
|
||||
let photosGridEl: HTMLElement
|
||||
let photosGridParallax = $state<number>()
|
||||
let currentStep = $state(0)
|
||||
let emailCopied = $state<string>()
|
||||
let emailCopiedTimeout: ReturnType<typeof setTimeout> | number
|
||||
|
||||
const parallaxPhotos = $derived(photosGridEl && map(scrollY, photosGridOffset - innerHeight, photosGridOffset + innerHeight / 1.5, 0, innerHeight * 0.15, true))
|
||||
const fadedPhotosIndexes = $derived(
|
||||
innerWidth > 768
|
||||
? [0, 2, 5, 7, 9, 12, 17, 20, 22, 26, 30, 32, 34]
|
||||
@@ -41,9 +38,11 @@
|
||||
|
||||
|
||||
$effect(() => {
|
||||
// Update photos grid top offset
|
||||
photosGridOffset = photosGridEl.offsetTop
|
||||
|
||||
// Add parallax to photos grid
|
||||
scroll(({ y }) => photosGridParallax = lerp(-15, 10, y.progress), {
|
||||
target: photosGridEl,
|
||||
offset: ['start end', 'end start']
|
||||
})
|
||||
|
||||
/**
|
||||
* Animations
|
||||
@@ -171,7 +170,7 @@
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:window bind:scrollY bind:innerWidth bind:innerHeight />
|
||||
<svelte:window bind:innerWidth />
|
||||
|
||||
<Metas
|
||||
title={data.about.seo_title}
|
||||
@@ -349,7 +348,7 @@
|
||||
|
||||
<section class="about__photos" bind:this={photosGridEl}>
|
||||
<div class="container-wide">
|
||||
<div class="photos-grid" style:--parallax-y="{parallaxPhotos}px">
|
||||
<div class="photos-grid" style:--parallax="{photosGridParallax}%">
|
||||
{#each data.photos as { image: { id }, title }, index}
|
||||
<AboutGridPhoto
|
||||
class="grid-photo"
|
||||
|
||||
@@ -492,7 +492,7 @@
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 1.75vw;
|
||||
margin: -5% -5% 0;
|
||||
transform: rotate(-6deg) translateY(var(--parallax-y)) translateZ(0);
|
||||
transform: rotate(-6deg) translateY(var(--parallax)) translateZ(0);
|
||||
transition: transform 0.8s var(--ease-quart);
|
||||
|
||||
@include bp (sm) {
|
||||
|
||||
@@ -173,8 +173,8 @@
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
filter: grayscale(25%);
|
||||
transform: translate3d(0, var(--parallax-y), 0);
|
||||
transition: transform 0.7s var(--ease-quart);
|
||||
transform: translateY(var(--parallax)) translateZ(0);
|
||||
transition: transform 0.5s var(--ease-quart);
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user