Tweak loading choreography

This commit is contained in:
Sam Becker 2024-05-19 18:25:21 -05:00
parent 446d3ae963
commit 8bfa078c9d
6 changed files with 43 additions and 6 deletions

View File

@ -1,4 +1,5 @@
import {
INFINITE_SCROLL_GRID_PHOTO_INITIAL,
descriptionForPhoto,
titleForPhoto,
} from '@/photo';
@ -59,12 +60,15 @@ export default async function PhotoCameraPage({
if (!photo) { redirect(PATH_ROOT); }
const camera = cameraFromPhoto(photo, { make, model });
const [
photos,
{ count, dateRange },
] = await getPhotosCameraDataCached({ camera });
camera,
] = await getPhotosCameraDataCached(
make,
model,
INFINITE_SCROLL_GRID_PHOTO_INITIAL,
);
return <>
{children}

View File

@ -5,6 +5,8 @@ import { Variant, motion } from 'framer-motion';
import { useAppState } from '@/state/AppState';
import usePrefersReducedMotion from '@/utility/usePrefersReducedMotion';
const IGNORE_CAN_START = true;
export type AnimationType = 'none' | 'scale' | 'left' | 'right' | 'bottom';
export interface AnimationConfig {
@ -20,9 +22,11 @@ interface Props extends AnimationConfig {
classNameItem?: string
items: ReactNode[]
itemKeys?: string[]
canStart?: boolean
animateFromAppState?: boolean
animateOnFirstLoadOnly?: boolean
staggerOnFirstLoadOnly?: boolean
onAnimationComplete?: () => void
}
function AnimateItems({
@ -30,6 +34,7 @@ function AnimateItems({
classNameItem,
items,
itemKeys,
canStart = true,
type = 'scale',
duration = 0.6,
staggerDelay = 0.1,
@ -38,6 +43,7 @@ function AnimateItems({
animateFromAppState,
animateOnFirstLoadOnly,
staggerOnFirstLoadOnly,
onAnimationComplete,
}: Props) {
const {
hasLoaded,
@ -89,7 +95,7 @@ function AnimateItems({
<motion.div
className={className}
initial={shouldAnimate ? 'hidden' : false}
animate="show"
animate={canStart || IGNORE_CAN_START ? 'show' : 'hidden'}
variants={shouldStagger
? {
show: {
@ -102,6 +108,7 @@ function AnimateItems({
if (animateFromAppState) {
clearNextPhotoAnimation?.();
}
onAnimationComplete?.();
}}
>
{items.map((item, index) =>

View File

@ -100,6 +100,8 @@ export default function PhotoDetailPage({
photos={photosGrid ?? photos}
selectedPhoto={photo}
tag={tag}
camera={camera}
simulation={simulation}
animateOnFirstLoadOnly
/>}
contentSide={<AnimateItems

View File

@ -15,11 +15,13 @@ export default function PhotoGrid({
photoPriority,
fast,
animate = true,
canStart,
animateOnFirstLoadOnly,
staggerOnFirstLoadOnly = true,
additionalTile,
small,
onLastPhotoVisible,
onAnimationComplete,
}: {
photos: Photo[]
selectedPhoto?: Photo
@ -29,11 +31,13 @@ export default function PhotoGrid({
photoPriority?: boolean
fast?: boolean
animate?: boolean
canStart?: boolean
animateOnFirstLoadOnly?: boolean
staggerOnFirstLoadOnly?: boolean
additionalTile?: JSX.Element
small?: boolean
onLastPhotoVisible?: () => void
onAnimationComplete?: () => void
}) {
return (
<AnimateItems
@ -47,11 +51,13 @@ export default function PhotoGrid({
'items-center',
)}
type={animate === false ? 'none' : undefined}
canStart={canStart}
duration={fast ? 0.3 : undefined}
staggerDelay={0.075}
distanceOffset={40}
animateOnFirstLoadOnly={animateOnFirstLoadOnly}
staggerOnFirstLoadOnly={staggerOnFirstLoadOnly}
onAnimationComplete={onAnimationComplete}
items={photos.map((photo, index) =>
<div
key={photo.id}

View File

@ -9,6 +9,7 @@ import { FilmSimulation } from '@/simulation';
export default function PhotoGridInfinite({
cacheKey,
initialOffset,
canStart,
tag,
camera,
simulation,
@ -16,6 +17,7 @@ export default function PhotoGridInfinite({
}: {
cacheKey: string
initialOffset: number
canStart?: boolean
tag?: string
camera?: Camera
simulation?: FilmSimulation
@ -33,6 +35,7 @@ export default function PhotoGridInfinite({
{({ photos, onLastPhotoVisible }) =>
<PhotoGrid {...{
photos,
canStart,
tag,
camera,
simulation,

View File

@ -1,3 +1,5 @@
'use client';
import SiteGrid from '@/components/SiteGrid';
import { Photo } from '.';
import PhotoGrid from './PhotoGrid';
@ -6,6 +8,7 @@ import { Camera } from '@/camera';
import { clsx } from 'clsx/lite';
import AnimateItems from '@/components/AnimateItems';
import { FilmSimulation } from '@/simulation';
import { useCallback, useState } from 'react';
export default function PhotoGridPage({
cacheKey,
@ -28,6 +31,16 @@ export default function PhotoGridPage({
header?: JSX.Element
sidebar?: JSX.Element
}) {
const [
shouldAnimateDynamicItems,
setShouldAnimateDynamicItems,
] = useState(false);
const onAnimationComplete = useCallback(() =>
setShouldAnimateDynamicItems(true), []);
const initialOffset = photos.length;
return (
<SiteGrid
contentMain={<div className={clsx(
@ -46,11 +59,13 @@ export default function PhotoGridPage({
camera,
simulation,
animateOnFirstLoadOnly,
onAnimationComplete,
}} />
{count > photos.length &&
{count > initialOffset &&
<PhotoGridInfinite {...{
cacheKey,
initialOffset: photos.length,
initialOffset,
canStart: shouldAnimateDynamicItems,
tag,
camera,
simulation,