Skip to content

Commit fb42f3f

Browse files
committed
update:
- bugfix for different entrance & leave bearing - add ability remove child after disappearance - optional ability to set the distance for directional bearing movement
1 parent 4d6962d commit fb42f3f

File tree

7 files changed

+185
-136
lines changed

7 files changed

+185
-136
lines changed

.DS_Store

6 KB
Binary file not shown.

README.md

+11-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
FadeView is a handy component written in [TypeScript](https://www.typescriptlang.org/) in order to handle the fade animations more easier for every react native component.
55

6+
![](https://github.com/aliunco/react-native-fadeview/blob/main/demo.gif?raw=true)
67

78
## Installing
89

@@ -22,15 +23,19 @@ yarn add react-native-fadeview-wrapper
2223

2324
```tsx
2425
import React, { Component } from 'react';
25-
import { FadeView } from 'react-native-fadeview-wrapper';
26+
import FadeView, { Bearing } from 'react-native-fadeview-wrapper';
2627

2728
const Example = () => {
2829

2930
const [isVisible, setIsVisible] = React.useState<boolean>(false)
3031

3132
return (
32-
<FadeView visible={isVisible}>
33-
{/** any components can be used here in order to have the fade animation */}
33+
<FadeView
34+
visible={visible}
35+
bearingMoveDistance={20}
36+
leaveBearing={Bearing.Top}
37+
entranceBearing={Bearing.Bottom}>
38+
{/** any components can be used here in order to have the fade animation */}
3439
</FadeView>
3540
);
3641
}
@@ -46,7 +51,9 @@ here is the properties and the descriptions of it:
4651
| visible | | **it's required** | `boolean` | `YES` | changing this param would initiate the fade animation |
4752
| shouldEnterWithAnimation | `false` | `boolean` | `NO` | if it's `true`, then the first state of `visible` would be presented by animation |
4853
| style | `undefined` | `ViewStyle` | `NO` | optinal style for the fadeview itself |
49-
| children | `undefined` | `JSX.Element | JSX.Element[]` | `NO` | child component(s) in order to have the fade animation |
54+
| bearingMoveDistance| 50 | `number` | `NO` | option distance when you pass the directional Bearing for entrance or leave |
55+
| removeChildrenAfterDisapearance| `false` | `boolean` | `NO` | you can choose if you want the children view to be removed after disappearance |
56+
| children | `undefined` | `JSX.Element` | `JSX.Element[]` | `NO` | child component(s) in order to have the fade animation |
5057
| entranceBearing | `Bearing.Center` | `Bearing` | `NO` | entrance animation with can be determined by `Bearing` enum from the lib, values: `Top`, `Bottom`, `Left`, `Right` , `Center` |
5158
| leaveBearing | `Bearing.Center` | `Bearing` | `NO` | leave animation with can be determined by `Bearing` enum from the lib, values: `Top`, `Bottom`, `Left`, `Right` , `Center` |
5259
| fadeOutScale | 1.1 | `number` | `NO` | scale of fade out state of the animation |

demo.gif

78.7 KB
Loading

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-fadeview-wrapper",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"author": "Ali Saeedifar <[email protected]>",
55
"description": "A handy fadeview component for the react native",
66
"main": "lib/index.js",
@@ -31,5 +31,8 @@
3131
"bugs": {
3232
"url": "https://github.com/aliunco/react-native-fadeview/issues"
3333
},
34-
"homepage": "https://github.com/aliunco/react-native-fadeview#readme"
34+
"homepage": "https://github.com/aliunco/react-native-fadeview#readme",
35+
"files": [
36+
"/lib"
37+
]
3538
}

src/components/FadeView.tsx

+138-87
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,154 @@
1-
import React from 'react'
2-
import {
3-
Animated,
4-
Easing,
5-
ViewStyle
6-
} from 'react-native'
1+
import React from "react";
2+
import { Animated, Easing, StyleProp, ViewProps, ViewStyle } from "react-native";
73

84
export enum Bearing {
9-
Top, Bottom, Left, Right, Center
5+
Top,
6+
Bottom,
7+
Left,
8+
Right,
9+
Center,
1010
}
1111

12-
type Props = {
13-
visible: boolean
14-
style?: ViewStyle,
15-
children?: JSX.Element | JSX.Element[],
16-
entranceBearing?: Bearing
17-
leaveBearing?: Bearing
18-
fadeOutScale?: number
19-
duration?: number
20-
shouldEnterWithAnimation?: boolean
21-
animationFinished?: (isVisible: boolean) => void
22-
// All other props
23-
[x: string]: any
24-
}
12+
type Props = ViewProps & {
13+
visible: boolean;
14+
style?: StyleProp<ViewStyle>;
15+
children?: React.ReactNode;
16+
entranceBearing?: Bearing;
17+
leaveBearing?: Bearing;
18+
fadeOutScale?: number;
19+
duration?: number;
20+
shouldEnterWithAnimation?: boolean;
21+
bearingMoveDistance?: number
22+
removeChildrenAfterDisapearance?: boolean
23+
animationFinished?: (isVisble: boolean) => void;
24+
// All other props
25+
[x: string]: any;
26+
};
2527

26-
export const FadeView = ({
27-
style,
28-
visible,
29-
children,
30-
shouldEnterWithAnimation,
31-
fadeOutScale = 1.1,
32-
duration = 200,
33-
entranceBearing = Bearing.Center,
34-
leaveBearing = Bearing.Center,
35-
animationFinished,
36-
...rest
28+
const FadeView = ({
29+
style,
30+
visible,
31+
children,
32+
duration = 200,
33+
fadeOutScale = 1.1,
34+
shouldEnterWithAnimation,
35+
bearingMoveDistance = 50,
36+
leaveBearing = Bearing.Center,
37+
entranceBearing = Bearing.Center,
38+
removeChildrenAfterDisapearance = false,
39+
animationFinished,
40+
...rest
3741
}: Props) => {
42+
const [visibleState, setVisibleState] = React.useState<boolean>(
43+
shouldEnterWithAnimation === true ? !visible : visible,
44+
);
45+
const [visibilityAnimValue] = React.useState(
46+
new Animated.Value(
47+
shouldEnterWithAnimation === true ? (visible ? 0 : 1) : visible ? 1 : 0,
48+
),
49+
);
50+
const theAnimation = React.useRef<Animated.CompositeAnimation | null>(null);
51+
const applyingVisibleState = React.useRef<boolean>(
52+
shouldEnterWithAnimation === true ? !visible : visible,
53+
);
3854

39-
const [visibleState, setVisibleState] = React.useState<boolean>(shouldEnterWithAnimation == true ? !visible : visible)
40-
const [visibilityAnimValue] = React.useState(new Animated.Value(shouldEnterWithAnimation == true ? (visible ? 0 : 1) : (visible ? 1 : 0)))
41-
const theAnimation = React.useRef<Animated.CompositeAnimation | null>(null)
42-
const applyingVisibleState = React.useRef<Boolean>(shouldEnterWithAnimation == true ? !visible : visible)
43-
44-
React.useEffect(() => {
45-
if (applyingVisibleState.current == visible) { return }
46-
if (theAnimation && applyingVisibleState.current != visible) {
47-
theAnimation.current?.stop()
48-
theAnimation.current = null
49-
}
50-
applyingVisibleState.current = visible
51-
52-
theAnimation.current = Animated.timing(visibilityAnimValue, {
53-
toValue: visible ? 1 : 0,
54-
duration,
55-
easing: Easing.inOut(Easing.linear),
56-
useNativeDriver: true
57-
})
55+
React.useEffect(() => {
56+
if (applyingVisibleState.current === visible) {
57+
return;
58+
}
59+
if (theAnimation && applyingVisibleState.current !== visible) {
60+
theAnimation.current?.stop();
61+
theAnimation.current = null;
62+
}
63+
applyingVisibleState.current = visible;
5864

59-
if (visible && !visibleState) { setVisibleState(true) }
60-
theAnimation.current.start(({ finished }) => {
61-
theAnimation.current = null
62-
if (finished) {
63-
setVisibleState(visible)
64-
animationFinished && animationFinished(visible)
65-
}
66-
})
67-
}, [visible])
65+
theAnimation.current = Animated.timing(visibilityAnimValue, {
66+
toValue: visible ? 1 : 0,
67+
duration,
68+
easing: Easing.inOut(Easing.linear),
69+
useNativeDriver: true,
70+
});
6871

69-
var transforms: any[] = []
72+
if (visible && !visibleState) {
73+
setVisibleState(true);
74+
}
75+
theAnimation.current.start(({ finished }) => {
76+
theAnimation.current = null;
77+
if (finished) {
78+
setVisibleState(visible);
79+
animationFinished?.(visible);
80+
}
81+
});
82+
}, [visible]);
7083

71-
if (entranceBearing != Bearing.Center || (applyingVisibleState.current == false && leaveBearing == entranceBearing)) {
72-
if (entranceBearing == Bearing.Left || entranceBearing == Bearing.Right)
73-
transforms.push({ translateX: visibilityAnimValue.interpolate({ inputRange: [0, 1], outputRange: [entranceBearing == Bearing.Left ? -50 : 50, 0] }) })
84+
const transforms: any[] = [];
7485

75-
if (entranceBearing == Bearing.Top || entranceBearing == Bearing.Bottom)
76-
transforms.push({ translateY: visibilityAnimValue.interpolate({ inputRange: [0, 1], outputRange: [entranceBearing == Bearing.Top ? -50 : 50, 0] }) })
77-
} else if (applyingVisibleState.current == false && leaveBearing != Bearing.Center) {
78-
if (leaveBearing == Bearing.Left || leaveBearing == Bearing.Right)
79-
transforms.push({ translateX: visibilityAnimValue.interpolate({ inputRange: [0, 1], outputRange: [leaveBearing == Bearing.Left ? -50 : 50, 0] }) })
86+
if (
87+
entranceBearing !== Bearing.Center && visible === true
88+
) {
89+
if (entranceBearing === Bearing.Left || entranceBearing === Bearing.Right) {
90+
transforms.push({
91+
translateX: visibilityAnimValue.interpolate({
92+
inputRange: [0, 1],
93+
outputRange: [entranceBearing === Bearing.Left ? -bearingMoveDistance : bearingMoveDistance, 0],
94+
}),
95+
});
96+
}
8097

81-
if (leaveBearing == Bearing.Top || leaveBearing == Bearing.Bottom)
82-
transforms.push({ translateY: visibilityAnimValue.interpolate({ inputRange: [0, 1], outputRange: [leaveBearing == Bearing.Top ? -50 : 50, 0] }) })
98+
if (entranceBearing === Bearing.Top || entranceBearing === Bearing.Bottom) {
99+
transforms.push({
100+
translateY: visibilityAnimValue.interpolate({
101+
inputRange: [0, 1],
102+
outputRange: [entranceBearing === Bearing.Top ? -bearingMoveDistance : bearingMoveDistance, 0],
103+
}),
104+
});
105+
}
106+
} else if (visible === false && leaveBearing !== Bearing.Center) {
107+
if (leaveBearing === Bearing.Left || leaveBearing === Bearing.Right) {
108+
transforms.push({
109+
translateX: visibilityAnimValue.interpolate({
110+
inputRange: [0, 1],
111+
outputRange: [leaveBearing === Bearing.Left ? -bearingMoveDistance : bearingMoveDistance, 0],
112+
}),
113+
});
83114
}
84115

85-
var containerStyle = {
86-
opacity: visibilityAnimValue,
87-
transform: [
88-
...transforms,
89-
{
90-
scale: visibilityAnimValue.interpolate({
91-
inputRange: [0, 1],
92-
outputRange: [fadeOutScale, 1],
93-
})
94-
}
95-
]
116+
if (leaveBearing === Bearing.Top || leaveBearing === Bearing.Bottom) {
117+
transforms.push({
118+
translateY: visibilityAnimValue.interpolate({
119+
inputRange: [0, 1],
120+
outputRange: [leaveBearing === Bearing.Top ? -bearingMoveDistance : bearingMoveDistance, 0],
121+
}),
122+
});
96123
}
124+
}
125+
126+
const containerStyle = {
127+
opacity: visibilityAnimValue,
128+
transform: [
129+
...transforms,
130+
{
131+
scale: visibilityAnimValue.interpolate({
132+
inputRange: [0, 1],
133+
outputRange: [fadeOutScale, 1],
134+
}),
135+
},
136+
],
137+
};
138+
139+
return (
140+
<Animated.View
141+
pointerEvents={visibleState ? "auto" : "none"}
142+
style={[style, containerStyle]}
143+
{...rest}
144+
>
145+
{
146+
removeChildrenAfterDisapearance ?
147+
visibleState && children
148+
: children
149+
}
150+
</Animated.View>
151+
);
152+
};
97153

98-
return (
99-
<Animated.View pointerEvents={visibleState ? 'auto' : 'none'} style={[style, containerStyle]} {...rest}>
100-
{ visibleState && children }
101-
</Animated.View>
102-
)
103-
};
154+
export default FadeView;

src/index.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
export * from "./components/FadeView";
1+
import FadeView, { Bearing } from "./components/FadeView";
2+
3+
export { Bearing };
4+
export default FadeView;

yarn.lock

+27-42
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,46 @@
33

44

55
"@types/prop-types@*":
6-
"integrity" "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
7-
"resolved" "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
8-
"version" "15.7.5"
6+
version "15.7.5"
7+
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
8+
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
99

1010
"@types/react-native@^0.63.3":
11-
"integrity" "sha512-rKV8r7fpydtOXiTzmty9Y+p8bTAO1n8WLBv78x85/GMaW4RmNbATTCii7vxLJobZBRF71FBEE5GR++RFjsqMvg=="
12-
"resolved" "https://registry.npmjs.org/@types/react-native/-/react-native-0.63.62.tgz"
13-
"version" "0.63.62"
11+
version "0.63.62"
12+
resolved "https://registry.npmjs.org/@types/react-native/-/react-native-0.63.62.tgz"
13+
integrity sha512-rKV8r7fpydtOXiTzmty9Y+p8bTAO1n8WLBv78x85/GMaW4RmNbATTCii7vxLJobZBRF71FBEE5GR++RFjsqMvg==
1414
dependencies:
1515
"@types/react" "*"
1616

1717
"@types/react@*":
18-
"integrity" "sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow=="
19-
"resolved" "https://registry.npmjs.org/@types/react/-/react-18.0.15.tgz"
20-
"version" "18.0.15"
18+
version "18.0.15"
19+
resolved "https://registry.npmjs.org/@types/react/-/react-18.0.15.tgz"
20+
integrity sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow==
2121
dependencies:
2222
"@types/prop-types" "*"
2323
"@types/scheduler" "*"
24-
"csstype" "^3.0.2"
24+
csstype "^3.0.2"
2525

2626
"@types/react@^16.13.1":
27-
"integrity" "sha512-83zBE6+XUVXsdL3iFzOyUewdauaU+KviKCHEGOgSW52coAuqW7tEKQM0E9+ZC0Zk6TELQ2/JgogPvp7FavzFwg=="
28-
"resolved" "https://registry.npmjs.org/@types/react/-/react-16.14.28.tgz"
29-
"version" "16.14.28"
27+
version "16.14.28"
28+
resolved "https://registry.npmjs.org/@types/react/-/react-16.14.28.tgz"
29+
integrity sha512-83zBE6+XUVXsdL3iFzOyUewdauaU+KviKCHEGOgSW52coAuqW7tEKQM0E9+ZC0Zk6TELQ2/JgogPvp7FavzFwg==
3030
dependencies:
3131
"@types/prop-types" "*"
3232
"@types/scheduler" "*"
33-
"csstype" "^3.0.2"
33+
csstype "^3.0.2"
3434

3535
"@types/scheduler@*":
36-
"integrity" "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
37-
"resolved" "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
38-
"version" "0.16.2"
39-
40-
"csstype@^3.0.2":
41-
"integrity" "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
42-
"resolved" "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz"
43-
"version" "3.1.0"
44-
45-
"js-tokens@^3.0.0 || ^4.0.0":
46-
"version" "4.0.0"
47-
48-
"loose-envify@^1.1.0":
49-
"version" "1.4.0"
50-
dependencies:
51-
"js-tokens" "^3.0.0 || ^4.0.0"
52-
53-
"react-native@*":
54-
55-
"react@*":
56-
"version" "18.0.0"
57-
dependencies:
58-
"loose-envify" "^1.1.0"
59-
60-
"typescript@^4.7.4":
61-
"integrity" "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ=="
62-
"resolved" "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz"
63-
"version" "4.7.4"
36+
version "0.16.2"
37+
resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
38+
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
39+
40+
csstype@^3.0.2:
41+
version "3.1.0"
42+
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz"
43+
integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==
44+
45+
typescript@^4.7.4:
46+
version "4.7.4"
47+
resolved "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz"
48+
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==

0 commit comments

Comments
 (0)