react-native-glitter 0.3.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/lib/module/index.js +38 -9
- package/lib/typescript/src/index.d.ts +3 -1
- package/package.json +1 -1
- package/src/index.tsx +43 -11
package/README.md
CHANGED
|
@@ -164,6 +164,8 @@ function ControlledGlitter() {
|
|
|
164
164
|
| `mode` | `'normal' \| 'expand' \| 'shrink'` | `'normal'` | Animation mode for the shimmer line |
|
|
165
165
|
| `position` | `'top' \| 'center' \| 'bottom'` | `'center'` | Position where the line shrinks/expands (for shrink/expand modes) |
|
|
166
166
|
| `direction` | `'left-to-right' \| 'right-to-left'` | `'left-to-right'` | Direction of the shimmer animation |
|
|
167
|
+
| `iterations` | `number` | `-1` | Number of animation cycles (-1 for infinite) |
|
|
168
|
+
| `onAnimationComplete` | `() => void` | - | Callback when all iterations complete |
|
|
167
169
|
|
|
168
170
|
## Examples
|
|
169
171
|
|
|
@@ -237,6 +239,26 @@ function ControlledGlitter() {
|
|
|
237
239
|
</Glitter>
|
|
238
240
|
```
|
|
239
241
|
|
|
242
|
+
### Limited Iterations with Callback
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
// Run 3 times then call onAnimationComplete
|
|
246
|
+
<Glitter
|
|
247
|
+
iterations={3}
|
|
248
|
+
onAnimationComplete={() => console.log('Done!')}
|
|
249
|
+
>
|
|
250
|
+
<View style={styles.box} />
|
|
251
|
+
</Glitter>
|
|
252
|
+
|
|
253
|
+
// Run once (useful for loading states)
|
|
254
|
+
<Glitter
|
|
255
|
+
iterations={1}
|
|
256
|
+
onAnimationComplete={() => setLoading(false)}
|
|
257
|
+
>
|
|
258
|
+
<View style={styles.skeleton} />
|
|
259
|
+
</Glitter>
|
|
260
|
+
```
|
|
261
|
+
|
|
240
262
|
## TypeScript
|
|
241
263
|
|
|
242
264
|
This library is written in TypeScript and includes type definitions:
|
package/lib/module/index.js
CHANGED
|
@@ -48,24 +48,46 @@ function generateVerticalSegments(fadeRatioParam) {
|
|
|
48
48
|
}
|
|
49
49
|
return segments;
|
|
50
50
|
}
|
|
51
|
-
export function Glitter({ children, duration = 1500, delay = 400, color = 'rgba(255, 255, 255, 0.8)', angle = 20, shimmerWidth = 60, active = true, style, easing, mode = 'normal', position = 'center', direction = 'left-to-right', }) {
|
|
51
|
+
export function Glitter({ children, duration = 1500, delay = 400, color = 'rgba(255, 255, 255, 0.8)', angle = 20, shimmerWidth = 60, active = true, style, easing, mode = 'normal', position = 'center', direction = 'left-to-right', iterations = -1, onAnimationComplete, }) {
|
|
52
52
|
const animatedValue = useRef(new Animated.Value(0)).current;
|
|
53
53
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
54
54
|
const [containerHeight, setContainerHeight] = useState(0);
|
|
55
55
|
const animationRef = useRef(null);
|
|
56
|
+
const iterationCount = useRef(0);
|
|
56
57
|
const defaultEasing = Easing.bezier(0.4, 0, 0.2, 1);
|
|
57
58
|
const startAnimation = useCallback(() => {
|
|
58
59
|
if (!active || containerWidth === 0)
|
|
59
60
|
return;
|
|
60
61
|
animatedValue.setValue(0);
|
|
62
|
+
iterationCount.current = 0;
|
|
61
63
|
const timing = Animated.timing(animatedValue, {
|
|
62
64
|
toValue: 1,
|
|
63
65
|
duration,
|
|
64
66
|
useNativeDriver: true,
|
|
65
67
|
easing: easing ?? defaultEasing,
|
|
66
68
|
});
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
const singleIteration = Animated.sequence([timing, Animated.delay(delay)]);
|
|
70
|
+
const runIteration = () => {
|
|
71
|
+
animatedValue.setValue(0);
|
|
72
|
+
singleIteration.start(({ finished }) => {
|
|
73
|
+
if (finished) {
|
|
74
|
+
iterationCount.current += 1;
|
|
75
|
+
if (iterations === -1 || iterationCount.current < iterations) {
|
|
76
|
+
runIteration();
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
onAnimationComplete?.();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
if (iterations === -1) {
|
|
85
|
+
animationRef.current = Animated.loop(singleIteration);
|
|
86
|
+
animationRef.current.start();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
runIteration();
|
|
90
|
+
}
|
|
69
91
|
return () => {
|
|
70
92
|
animationRef.current?.stop();
|
|
71
93
|
};
|
|
@@ -77,6 +99,8 @@ export function Glitter({ children, duration = 1500, delay = 400, color = 'rgba(
|
|
|
77
99
|
animatedValue,
|
|
78
100
|
easing,
|
|
79
101
|
defaultEasing,
|
|
102
|
+
iterations,
|
|
103
|
+
onAnimationComplete,
|
|
80
104
|
]);
|
|
81
105
|
useEffect(() => {
|
|
82
106
|
const cleanup = startAnimation();
|
|
@@ -166,12 +190,14 @@ export function Glitter({ children, duration = 1500, delay = 400, color = 'rgba(
|
|
|
166
190
|
]
|
|
167
191
|
: [{ translateY: startOffset }],
|
|
168
192
|
},
|
|
169
|
-
], children: (isAnimated ? animatedSegments : normalSegments).map((segment, vIndex) => (_jsx(View, { style:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
193
|
+
], children: (isAnimated ? animatedSegments : normalSegments).map((segment, vIndex) => (_jsx(View, { style: [
|
|
194
|
+
styles.segment,
|
|
195
|
+
{
|
|
196
|
+
height: lineHeight * segment.heightRatio,
|
|
197
|
+
backgroundColor: color,
|
|
198
|
+
opacity: layer.opacity * segment.opacity,
|
|
199
|
+
},
|
|
200
|
+
] }, vIndex))) }, layerIndex))) }) }))] }));
|
|
175
201
|
}
|
|
176
202
|
const styles = StyleSheet.create({
|
|
177
203
|
container: {
|
|
@@ -193,5 +219,8 @@ const styles = StyleSheet.create({
|
|
|
193
219
|
position: 'absolute',
|
|
194
220
|
flexDirection: 'column',
|
|
195
221
|
},
|
|
222
|
+
segment: {
|
|
223
|
+
width: '100%',
|
|
224
|
+
},
|
|
196
225
|
});
|
|
197
226
|
export default Glitter;
|
|
@@ -16,6 +16,8 @@ export interface GlitterProps {
|
|
|
16
16
|
mode?: GlitterMode;
|
|
17
17
|
position?: GlitterPosition;
|
|
18
18
|
direction?: GlitterDirection;
|
|
19
|
+
iterations?: number;
|
|
20
|
+
onAnimationComplete?: () => void;
|
|
19
21
|
}
|
|
20
|
-
export declare function Glitter({ children, duration, delay, color, angle, shimmerWidth, active, style, easing, mode, position, direction, }: GlitterProps): ReactElement;
|
|
22
|
+
export declare function Glitter({ children, duration, delay, color, angle, shimmerWidth, active, style, easing, mode, position, direction, iterations, onAnimationComplete, }: GlitterProps): ReactElement;
|
|
21
23
|
export default Glitter;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-glitter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A beautiful shimmer/glitter effect component for React Native. Add a sparkling diagonal shine animation to any component!",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
package/src/index.tsx
CHANGED
|
@@ -35,6 +35,8 @@ export interface GlitterProps {
|
|
|
35
35
|
mode?: GlitterMode;
|
|
36
36
|
position?: GlitterPosition;
|
|
37
37
|
direction?: GlitterDirection;
|
|
38
|
+
iterations?: number;
|
|
39
|
+
onAnimationComplete?: () => void;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
function generateGlitterOpacities(count: number, peak: number = 1): number[] {
|
|
@@ -111,11 +113,16 @@ export function Glitter({
|
|
|
111
113
|
mode = 'normal',
|
|
112
114
|
position = 'center',
|
|
113
115
|
direction = 'left-to-right',
|
|
116
|
+
iterations = -1,
|
|
117
|
+
onAnimationComplete,
|
|
114
118
|
}: GlitterProps): ReactElement {
|
|
115
119
|
const animatedValue = useRef(new Animated.Value(0)).current;
|
|
116
120
|
const [containerWidth, setContainerWidth] = useState(0);
|
|
117
121
|
const [containerHeight, setContainerHeight] = useState(0);
|
|
118
|
-
const animationRef = useRef<
|
|
122
|
+
const animationRef = useRef<{ start: () => void; stop: () => void } | null>(
|
|
123
|
+
null
|
|
124
|
+
);
|
|
125
|
+
const iterationCount = useRef(0);
|
|
119
126
|
|
|
120
127
|
const defaultEasing = Easing.bezier(0.4, 0, 0.2, 1);
|
|
121
128
|
|
|
@@ -123,6 +130,7 @@ export function Glitter({
|
|
|
123
130
|
if (!active || containerWidth === 0) return;
|
|
124
131
|
|
|
125
132
|
animatedValue.setValue(0);
|
|
133
|
+
iterationCount.current = 0;
|
|
126
134
|
|
|
127
135
|
const timing = Animated.timing(animatedValue, {
|
|
128
136
|
toValue: 1,
|
|
@@ -131,11 +139,28 @@ export function Glitter({
|
|
|
131
139
|
easing: easing ?? defaultEasing,
|
|
132
140
|
});
|
|
133
141
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
)
|
|
142
|
+
const singleIteration = Animated.sequence([timing, Animated.delay(delay)]);
|
|
143
|
+
|
|
144
|
+
const runIteration = () => {
|
|
145
|
+
animatedValue.setValue(0);
|
|
146
|
+
singleIteration.start(({ finished }) => {
|
|
147
|
+
if (finished) {
|
|
148
|
+
iterationCount.current += 1;
|
|
149
|
+
if (iterations === -1 || iterationCount.current < iterations) {
|
|
150
|
+
runIteration();
|
|
151
|
+
} else {
|
|
152
|
+
onAnimationComplete?.();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
};
|
|
137
157
|
|
|
138
|
-
|
|
158
|
+
if (iterations === -1) {
|
|
159
|
+
animationRef.current = Animated.loop(singleIteration);
|
|
160
|
+
animationRef.current.start();
|
|
161
|
+
} else {
|
|
162
|
+
runIteration();
|
|
163
|
+
}
|
|
139
164
|
|
|
140
165
|
return () => {
|
|
141
166
|
animationRef.current?.stop();
|
|
@@ -148,6 +173,8 @@ export function Glitter({
|
|
|
148
173
|
animatedValue,
|
|
149
174
|
easing,
|
|
150
175
|
defaultEasing,
|
|
176
|
+
iterations,
|
|
177
|
+
onAnimationComplete,
|
|
151
178
|
]);
|
|
152
179
|
|
|
153
180
|
useEffect(() => {
|
|
@@ -273,12 +300,14 @@ export function Glitter({
|
|
|
273
300
|
(segment, vIndex) => (
|
|
274
301
|
<View
|
|
275
302
|
key={vIndex}
|
|
276
|
-
style={
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
303
|
+
style={[
|
|
304
|
+
styles.segment,
|
|
305
|
+
{
|
|
306
|
+
height: lineHeight * segment.heightRatio,
|
|
307
|
+
backgroundColor: color,
|
|
308
|
+
opacity: layer.opacity * segment.opacity,
|
|
309
|
+
},
|
|
310
|
+
]}
|
|
282
311
|
/>
|
|
283
312
|
)
|
|
284
313
|
)}
|
|
@@ -311,6 +340,9 @@ const styles = StyleSheet.create({
|
|
|
311
340
|
position: 'absolute',
|
|
312
341
|
flexDirection: 'column',
|
|
313
342
|
},
|
|
343
|
+
segment: {
|
|
344
|
+
width: '100%',
|
|
345
|
+
},
|
|
314
346
|
});
|
|
315
347
|
|
|
316
348
|
export default Glitter;
|