@@ -547,16 +547,25 @@ function applyViewTransitionToHostInstances(
547
547
name : string ,
548
548
collectMeasurements : null | Array < InstanceMeasurement > ,
549
549
stopAtNestedViewTransitions : boolean ,
550
- ) : void {
550
+ ) : boolean {
551
551
if ( ! supportsMutation ) {
552
- return ;
552
+ return false ;
553
553
}
554
+ let inViewport = false ;
554
555
while ( child !== null ) {
555
556
if ( child . tag === HostComponent ) {
556
557
shouldStartViewTransition = true ;
557
558
const instance : Instance = child . stateNode ;
558
559
if ( collectMeasurements !== null ) {
559
- collectMeasurements . push ( measureInstance ( instance ) ) ;
560
+ const measurement = measureInstance ( instance ) ;
561
+ collectMeasurements . push ( measurement ) ;
562
+ if ( wasInstanceInViewport ( measurement ) ) {
563
+ inViewport = true ;
564
+ }
565
+ } else if ( ! inViewport ) {
566
+ if ( wasInstanceInViewport ( measureInstance ( instance ) ) ) {
567
+ inViewport = true ;
568
+ }
560
569
}
561
570
applyViewTransitionName (
562
571
instance ,
@@ -579,15 +588,20 @@ function applyViewTransitionToHostInstances(
579
588
// Skip any nested view transitions for updates since in that case the
580
589
// inner most one is the one that handles the update.
581
590
} else {
582
- applyViewTransitionToHostInstances (
583
- child . child ,
584
- name ,
585
- collectMeasurements ,
586
- stopAtNestedViewTransitions ,
587
- ) ;
591
+ if (
592
+ applyViewTransitionToHostInstances (
593
+ child . child ,
594
+ name ,
595
+ collectMeasurements ,
596
+ stopAtNestedViewTransitions ,
597
+ )
598
+ ) {
599
+ inViewport = true ;
600
+ }
588
601
}
589
602
child = child . sibling ;
590
603
}
604
+ return inViewport ;
591
605
}
592
606
593
607
function restoreViewTransitionOnHostInstances (
@@ -668,8 +682,20 @@ function commitEnterViewTransitions(placement: Fiber): void {
668
682
placement . stateNode ,
669
683
) ;
670
684
viewTransitionHostInstanceIdx = 0 ;
671
- applyViewTransitionToHostInstances ( placement . child , name , null , false ) ;
672
- commitAppearingPairViewTransitions ( placement ) ;
685
+ const inViewport = applyViewTransitionToHostInstances (
686
+ placement . child ,
687
+ name ,
688
+ null ,
689
+ false ,
690
+ ) ;
691
+ if ( ! inViewport ) {
692
+ // Revert the transition names. This boundary is not in the viewport
693
+ // so we won't bother animating it.
694
+ restoreViewTransitionOnHostInstances ( placement . child , false ) ;
695
+ // TODO: Should we still visit the children in case a named one was in the viewport?
696
+ } else {
697
+ commitAppearingPairViewTransitions ( placement ) ;
698
+ }
673
699
} else if ( ( placement . subtreeFlags & ViewTransitionStatic ) !== NoFlags ) {
674
700
let child = placement . child ;
675
701
while ( child !== null ) {
@@ -737,9 +763,18 @@ function commitExitViewTransitions(
737
763
const props : ViewTransitionProps = deletion . memoizedProps ;
738
764
const name = getViewTransitionName ( props , deletion . stateNode ) ;
739
765
viewTransitionHostInstanceIdx = 0 ;
740
- applyViewTransitionToHostInstances ( deletion . child , name , null , false ) ;
741
-
742
- if ( appearingViewTransitions !== null ) {
766
+ const inViewport = applyViewTransitionToHostInstances (
767
+ deletion . child ,
768
+ name ,
769
+ null ,
770
+ false ,
771
+ ) ;
772
+ if ( ! inViewport ) {
773
+ // Revert the transition names. This boundary is not in the viewport
774
+ // so we won't bother animating it.
775
+ restoreViewTransitionOnHostInstances ( deletion . child , false ) ;
776
+ // TODO: Should we still visit the children in case a named one was in the viewport?
777
+ } else if ( appearingViewTransitions !== null ) {
743
778
const pair = appearingViewTransitions . get ( name ) ;
744
779
if ( pair !== undefined ) {
745
780
// We found a new appearing view transition with the same name as this deletion.
@@ -2999,9 +3034,9 @@ function commitAfterMutationEffectsOnFiber(
2999
3034
finishedWork . flags |= Update ;
3000
3035
}
3001
3036
3002
- const inViewPort = measureUpdateViewTransition ( current , finishedWork ) ;
3037
+ const inViewport = measureUpdateViewTransition ( current , finishedWork ) ;
3003
3038
3004
- if ( ( finishedWork . flags & Update ) === NoFlags || ! inViewPort ) {
3039
+ if ( ( finishedWork . flags & Update ) === NoFlags || ! inViewport ) {
3005
3040
// If this boundary didn't update, then we may be able to cancel its children.
3006
3041
// We bubble them up to the parent set to be determined later if we can cancel.
3007
3042
// Similarly, if old and new state was outside the viewport, we can skip it
0 commit comments