From d3e0cd136979f606423bb92dca51a8cd162c0cdb Mon Sep 17 00:00:00 2001 From: CatsJuice Date: Thu, 13 Feb 2025 05:58:09 +0000 Subject: [PATCH] chore(core): use fadeBottom animation for center peek (#10072) close AF-2184, AF-2186 ![CleanShot 2025-02-11 at 09.31.39.gif](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/LakojjjzZNf6ogjOVwKE/81ed6601-33ff-4eee-bb35-636a2a27cd85.gif) --- .../modules/peek-view/entities/peek-view.ts | 2 +- .../peek-view/view/modal-container.tsx | 53 ++++++++++++++++++- .../peek-view/view/peek-view-manager.tsx | 5 +- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts b/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts index 75935bde25..466704381a 100644 --- a/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts +++ b/packages/frontend/core/src/modules/peek-view/entities/peek-view.ts @@ -217,7 +217,7 @@ function resolvePeekInfoFromPeekTarget( return; } -export type PeekViewAnimation = 'fade' | 'zoom' | 'none'; +export type PeekViewAnimation = 'fade' | 'fadeBottom' | 'zoom' | 'none'; export type PeekViewMode = 'full' | 'fit' | 'max'; export class PeekViewEntity extends Entity { diff --git a/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx b/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx index 10cb7db364..28a7bf3e0f 100644 --- a/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/modal-container.tsx @@ -77,7 +77,7 @@ export const PeekViewModalContainer = forwardRef< children, onAnimationStart, onAnimationEnd, - animation = 'zoom', + animation = 'fadeBottom', mode = 'fit', dialogFrame = true, }, @@ -310,6 +310,45 @@ export const PeekViewModalContainer = forwardRef< [onAnimationEnd, onAnimationStart] ); + const animateFadeBottom = useCallback( + (animateIn: boolean) => { + setAnimeState('animating'); + return new Promise(resolve => { + if (animateIn) setVtOpen(true); + setTimeout(() => { + const overlay = overlayRef.current; + const contentClip = contentClipRef.current; + if (!overlay || !contentClip) { + resolve(); + return; + } + + anime({ + targets: [overlay], + opacity: animateIn ? [0, 1] : [1, 0], + easing: 'easeOutQuad', + duration: 230, + }); + anime({ + targets: [contentClip], + opacity: animateIn ? [0, 1] : [1, 0], + y: animateIn ? ['-2%', '0%'] : ['0%', '-2%'], + scale: animateIn ? [0.96, 1] : [1, 0.96], + easing: 'cubicBezier(0.42, 0, 0.58, 1)', + duration: 230, + complete: () => { + if (!animateIn) setVtOpen(false); + setAnimeState('idle'); + onAnimationEnd?.(); + resolve(); + }, + }); + }); + }); + }, + [onAnimationEnd] + ); + useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { @@ -325,12 +364,22 @@ export const PeekViewModalContainer = forwardRef< useLayoutEffect(() => { if (animation === 'zoom') { open ? animateZoomIn() : animateZoomOut(); + } else if (animation === 'fadeBottom') { + animateFadeBottom(open).catch(console.error); } else if (animation === 'fade') { animateFade(open).catch(console.error); } else if (animation === 'none') { setVtOpen(open); } - }, [animateZoomOut, animation, open, target, animateZoomIn, animateFade]); + }, [ + animateZoomOut, + animation, + open, + target, + animateZoomIn, + animateFade, + animateFadeBottom, + ]); return ( diff --git a/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx b/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx index e30112c731..23697a15fb 100644 --- a/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx +++ b/packages/frontend/core/src/modules/peek-view/view/peek-view-manager.tsx @@ -93,10 +93,7 @@ const getRendererProps = ( ? activePeekView.target.element : undefined, mode: getMode(activePeekView.info), - animation: - activePeekView.target.element && getMode(activePeekView.info) !== 'full' - ? 'zoom' - : 'fade', + animation: 'fadeBottom', dialogFrame: activePeekView.info.type !== 'image', }; };