1- import React , { useState , useMemo } from 'react' ;
2- import { Animated , StyleSheet , LayoutChangeEvent } from 'react-native' ;
1+ import React , { useState , useMemo , useRef } from 'react' ;
2+ import { Animated , StyleSheet , LayoutChangeEvent , View } from 'react-native' ;
33import MaskLayer , { MaskLayerProps } from '../MaskLayer' ;
44
55export interface ModalProps extends MaskLayerProps {
@@ -9,7 +9,8 @@ export interface ModalProps extends MaskLayerProps {
99
1010export default ( props : ModalProps = { } ) => {
1111 const { onClosed, visible, children, placement = 'bottom' , ...otherProps } = props ;
12- const [ display ] = useState < 'none' | 'flex' > ( 'none' ) ;
12+ const AnimatedOpacity : Animated . Value = useRef ( new Animated . Value ( 0 ) ) . current ;
13+ // const [display] = useState<'none' | 'flex'>('none');
1314 let [ layoutHeight , setLayoutHeight ] = useState ( 0 ) ;
1415 let [ layoutWidth , setLayoutWidth ] = useState ( 0 ) ;
1516 const [ translateValue ] = useState ( new Animated . Value ( 0 ) ) ;
@@ -43,26 +44,36 @@ export default (props: ModalProps = {}) => {
4344 return 0 ;
4445 }
4546 useMemo ( ( ) => {
46- if ( visible && ( layoutHeight !== 0 || layoutWidth !== 0 ) ) {
47- translateValue . setValue ( getTransformSize ( ) ) ;
48- Animated . parallel ( [
49- Animated . spring ( translateValue , {
50- toValue : 0 ,
51- overshootClamping : true ,
52- useNativeDriver : true ,
53- } ) ,
54- ] ) . start ( ) ;
55- } else if ( layoutHeight !== 0 || layoutWidth !== 0 ) {
47+ const result = getTransformSize ( ) ;
48+ if ( ! result ) return ;
49+ if ( visible ) {
50+ translateValue . setValue ( result ) ;
51+ // AnimatedOpacity
52+ Animated . timing ( AnimatedOpacity , {
53+ toValue : 1 ,
54+ duration : 0 ,
55+ useNativeDriver : false ,
56+ } ) . start ( ( { finished } ) => {
57+ Animated . parallel ( [
58+ Animated . spring ( translateValue , {
59+ toValue : 0 ,
60+ overshootClamping : true ,
61+ useNativeDriver : true ,
62+ } ) ,
63+ ] ) . start ( ) ;
64+ } ) ;
65+ }
66+ if ( ! visible ) {
5667 Animated . parallel ( [
5768 Animated . spring ( translateValue , {
58- toValue : getTransformSize ( ) ,
69+ toValue : result ,
5970 overshootClamping : true ,
6071 useNativeDriver : true ,
6172 } ) ,
6273 ] ) . start ( ) ;
6374 }
6475 // eslint-disable-next-line react-hooks/exhaustive-deps
65- } , [ visible , layoutHeight ] ) ;
76+ } , [ visible , getTransformSize ] ) ;
6677 const translateStyle = { } as {
6778 translateY : Animated . Value ;
6879 translateX : Animated . Value ;
@@ -74,18 +85,20 @@ export default (props: ModalProps = {}) => {
7485 translateStyle . translateX = translateValue ;
7586 }
7687 const child = (
77- < Animated . View
78- onLayout = { measureContainer }
79- style = { [
80- styles . content ,
81- placement && styles [ placement ] ,
82- ! layoutHeight && isVertical ? { display : display } : { } ,
83- ! layoutWidth && isHorizontal ? { display : display } : { } ,
84- // // getTransformStyle(),
85- { transform : [ translateStyle ] } ,
86- ] }
87- >
88- { children }
88+ < Animated . View style = { [ styles . content , placement && styles [ placement ] , { opacity : AnimatedOpacity } ] } >
89+ < Animated . View
90+ onLayout = { measureContainer }
91+ style = { [
92+ styles . content ,
93+ placement && styles [ placement ] ,
94+ // !layoutHeight && isVertical ? { display: display } : {},
95+ // !layoutWidth && isHorizontal ? { display: display } : {},
96+ // // getTransformStyle(),
97+ { transform : [ translateStyle ] } ,
98+ ] }
99+ >
100+ { children }
101+ </ Animated . View >
89102 </ Animated . View >
90103 ) ;
91104 return (
0 commit comments