-
-
Notifications
You must be signed in to change notification settings - Fork 433
Expand file tree
/
Copy pathViewMask.tsx
More file actions
109 lines (100 loc) · 3.12 KB
/
Copy pathViewMask.tsx
File metadata and controls
109 lines (100 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import React, { useCallback, useEffect, useRef, useState } from "react";
import { Animated, View, I18nManager } from "react-native";
import { styles } from "./style";
import type { MaskProps, ValueXY } from "../types";
const rtl = I18nManager.isRTL;
const start = rtl ? 'right' : 'left';
const end = rtl ? 'left' : 'right';
export const ViewMask = (props: MaskProps) => {
const sizeValue = useRef<Animated.ValueXY>(
new Animated.ValueXY(props.size)
).current;
const positionValue = useRef<Animated.ValueXY>(
new Animated.ValueXY(props.position)
).current;
const [animated, setAnimated] = useState(false);
const animate = useCallback(
(size: ValueXY = props.size, position: ValueXY = props.position): void => {
if (animated) {
Animated.parallel([
Animated.timing(sizeValue, {
toValue: size,
duration: props.animationDuration,
easing: props.easing,
useNativeDriver: false,
}),
Animated.timing(positionValue, {
toValue: position,
duration: props.animationDuration,
easing: props.easing,
useNativeDriver: false,
}),
]).start();
} else {
sizeValue.setValue(size);
positionValue.setValue(position);
setAnimated(props.animated);
}
},
[
animated,
positionValue,
props.animated,
props.animationDuration,
props.easing,
props.position,
props.size,
sizeValue,
]
);
useEffect(() => {
if (props.position || props.size) {
animate(props.size, props.position);
}
}, [animate, props.position, props.size]);
const width = props.layout ? props.layout.width : 500;
const height = props.layout ? props.layout.height : 500;
const leftOverlayRight = Animated.add(
width,
Animated.multiply(positionValue.x, -1)
);
const rightOverlayLeft = Animated.add(sizeValue.x, positionValue.x);
const bottomOverlayTopBoundary = Animated.add(sizeValue.y, positionValue.y);
const topOverlayBottomBoundary = Animated.add(
height,
Animated.multiply(-1, positionValue.y)
);
const verticalOverlayLeftBoundary = positionValue.x;
const verticalOverlayRightBoundary = Animated.add(
width,
Animated.multiply(-1, rightOverlayLeft)
);
return (
<View style={props.style} onStartShouldSetResponder={props.onClick}>
{[
{
[end]: leftOverlayRight,
backgroundColor: props.backdropColor,
},
{
[start]: rightOverlayLeft,
backgroundColor: props.backdropColor,
},
{
top: bottomOverlayTopBoundary,
[start]: verticalOverlayLeftBoundary,
[end]: verticalOverlayRightBoundary,
backgroundColor: props.backdropColor,
},
{
bottom: topOverlayBottomBoundary,
[start]: verticalOverlayLeftBoundary,
[end]: verticalOverlayRightBoundary,
backgroundColor: props.backdropColor,
},
].map((style, index) => (
<Animated.View key={index} style={[styles.overlayRectangle, style]} />
))}
</View>
);
};