@@ -7,6 +7,7 @@ import { useRouter } from 'next/navigation'
77import {
88 useCallback ,
99 useEffect ,
10+ useLayoutEffect ,
1011 useMemo ,
1112 useRef ,
1213 useState ,
@@ -255,6 +256,12 @@ const pageIds = [
255256
256257const CTA_PAGE_INDEX = pageIds . indexOf ( 'join' )
257258
259+ type IntroLogoOverlayAnimation = {
260+ x : number
261+ y : number
262+ scale : number
263+ }
264+
258265function SectionShell ( {
259266 id,
260267 children,
@@ -1120,6 +1127,7 @@ export default function OnboardingLanding() {
11201127 const introLogoRef = useRef < HTMLDivElement | null > ( null )
11211128 const introLogoOverlayRef = useRef < HTMLDivElement | null > ( null )
11221129 const headerLogoMeasureRef = useRef < HTMLDivElement | null > ( null )
1130+ const pendingIntroLogoAnimationRef = useRef < IntroLogoOverlayAnimation | null > ( null )
11231131 const incomingDirectionRef = useRef ( 1 )
11241132 const reduceMotionRef = useRef ( false )
11251133 const transitionLockRef = useRef ( false )
@@ -1174,7 +1182,13 @@ export default function OnboardingLanding() {
11741182 const targetLeft = targetRect ?. left ?? fallbackTargetLeft
11751183 const targetTop = targetRect ?. top ?? 21
11761184 const baseLogoWidth = startRect . width / introLogoScale
1177- const targetScale = targetRect ? targetRect . width / baseLogoWidth : 1
1185+ const targetScale = targetRect && baseLogoWidth > 0 ? targetRect . width / baseLogoWidth : 1
1186+
1187+ pendingIntroLogoAnimationRef . current = {
1188+ x : targetLeft - startRect . left ,
1189+ y : targetTop - startRect . top ,
1190+ scale : targetScale
1191+ }
11781192
11791193 setIsIntroLogoHidden ( true )
11801194 setIntroLogoOverlayStyle ( {
@@ -1183,29 +1197,6 @@ export default function OnboardingLanding() {
11831197 transform : `translate3d(0, 0, 0) scale(${ introLogoScale } )` ,
11841198 transformOrigin : 'top left'
11851199 } )
1186-
1187- window . requestAnimationFrame ( ( ) => {
1188- if ( ! introLogoOverlayRef . current ) {
1189- setActiveIndex ( 1 )
1190- setIntroLogoOverlayStyle ( null )
1191- transitionLockRef . current = false
1192- return
1193- }
1194-
1195- gsap . to ( introLogoOverlayRef . current , {
1196- x : targetLeft - startRect . left ,
1197- y : targetTop - startRect . top ,
1198- scale : targetScale ,
1199- duration : 1 ,
1200- ease : 'power3.inOut' ,
1201- overwrite : true ,
1202- onComplete : ( ) => {
1203- setActiveIndex ( 1 )
1204- setIntroLogoOverlayStyle ( null )
1205- transitionLockRef . current = false
1206- }
1207- } )
1208- } )
12091200 } , [ ] )
12101201
12111202 const navigateToIndex = useCallback (
@@ -1328,6 +1319,39 @@ export default function OnboardingLanding() {
13281319 return ( ) => window . clearTimeout ( introTimer )
13291320 } , [ activeIndex , runIntroLogoTransition ] )
13301321
1322+ useLayoutEffect ( ( ) => {
1323+ if ( ! introLogoOverlayStyle ) return
1324+
1325+ const overlayElement = introLogoOverlayRef . current
1326+ const animation = pendingIntroLogoAnimationRef . current
1327+
1328+ if ( ! overlayElement || ! animation ) {
1329+ setActiveIndex ( 1 )
1330+ setIntroLogoOverlayStyle ( null )
1331+ transitionLockRef . current = false
1332+ return
1333+ }
1334+
1335+ const tween = gsap . to ( overlayElement , {
1336+ x : animation . x ,
1337+ y : animation . y ,
1338+ scale : animation . scale ,
1339+ duration : 1 ,
1340+ ease : 'power3.inOut' ,
1341+ overwrite : true ,
1342+ onComplete : ( ) => {
1343+ pendingIntroLogoAnimationRef . current = null
1344+ setActiveIndex ( 1 )
1345+ setIntroLogoOverlayStyle ( null )
1346+ transitionLockRef . current = false
1347+ }
1348+ } )
1349+
1350+ return ( ) => {
1351+ tween . kill ( )
1352+ }
1353+ } , [ introLogoOverlayStyle ] )
1354+
13311355 useEffect ( ( ) => {
13321356 if ( ! stageRef . current ) return
13331357
0 commit comments