diff --git a/README.md b/README.md
index 2542648..feedd22 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
-
Ready-to-use CSS Animation presets for [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/)
> [!TIP]
@@ -75,12 +74,36 @@ function App() {
}
```
+### Shimmer
+
+Add `shimmer` style object to an `Animated` component to make it animate from left to right indefinitely. Great for shimmer loading effect.
+
+
+
+> [!NOTE]
+> While the `shimmer` style object supports both iOS, Android, and the Web, the example video on the right uses `@react-native-masked-view/masked-view` and `expo-linear-gradient`, and thus doesn't work on the Web.
+
+```jsx
+import { shimmer } from 'react-native-css-animations';
+import Animated from 'react-native-reanimated';
+
+function App() {
+ return ;
+}
+```
+
## Alternative API
The following animations are also available in a form of React Native components.
```jsx
-import { Spin, Ping, Pulse, Bounce } from 'react-native-css-animations';
+import {
+ Spin,
+ Ping,
+ Pulse,
+ Bounce,
+ Shimmer,
+} from 'react-native-css-animations';
function App() {
return (
@@ -91,6 +114,29 @@ function App() {
}
```
+## Customizing animation presets
+
+You can customize the animation style objects by overriding the styles like so:
+
+```diff
+import { shimmer } from 'react-native-css-animations';
+import Animated from 'react-native-reanimated';
+
+function App() {
+ return
+}
+```
+
## Credits
- The examples and animations were adopted from [Tailwind CSS](https://tailwindcss.com/docs/animation).
diff --git a/example/package.json b/example/package.json
index 1eace60..2776698 100644
--- a/example/package.json
+++ b/example/package.json
@@ -10,7 +10,9 @@
},
"dependencies": {
"@expo/metro-runtime": "~4.0.0",
+ "@react-native-masked-view/masked-view": "0.3.2",
"expo": "~52.0.25",
+ "expo-linear-gradient": "~14.0.2",
"expo-status-bar": "~2.0.1",
"react": "18.3.1",
"react-dom": "18.3.1",
diff --git a/example/src/App.tsx b/example/src/App.tsx
index c2dd33d..a0b41fe 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -1,9 +1,18 @@
-import { SafeAreaView, StyleSheet, Text, View } from 'react-native';
+import {
+ bounce,
+ ping,
+ pulse,
+ shimmer,
+ spin,
+} from 'react-native-css-animations';
+
+import { Platform, SafeAreaView, StyleSheet, Text, View } from 'react-native';
+import { LinearGradient } from 'expo-linear-gradient';
import Animated from 'react-native-reanimated';
import Fontisto from '@expo/vector-icons/Fontisto';
import Entypo from '@expo/vector-icons/Entypo';
import EvilIcons from '@expo/vector-icons/EvilIcons';
-import { bounce, ping, pulse, spin } from 'react-native-css-animations';
+import MaskedView from '@react-native-masked-view/masked-view';
export default function App() {
return (
@@ -32,9 +41,38 @@ export default function App() {
Bounce
+ {/* Bounce animation ⬇️ */}
+
+ {(Platform.OS === 'ios' || Platform.OS === 'android') && (
+ <>
+ Shimmer
+
+
+
+
+
+ }
+ >
+ {/* Shimmer animation ⬇️ */}
+
+
+
+
+
+ >
+ )}
);
}
@@ -116,4 +154,23 @@ const styles = StyleSheet.create({
justifyContent: 'center',
borderColor: '#e2e8f0',
},
+ shimmerContainer: {
+ width: '100%',
+ height: 48,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ mask: {
+ height: 48,
+ width: 210,
+ },
+ gradientContainer: {
+ flex: 1,
+ width: '300%',
+ marginHorizontal: '-100%',
+ },
+ gradient: {
+ flex: 1,
+ width: '100%',
+ },
});
diff --git a/src/index.tsx b/src/index.tsx
index 91207cd..4a141f3 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -123,3 +123,29 @@ export function Bounce({
);
}
+
+export const shimmer: CSSStyleDeclaration = {
+ animationName: {
+ from: {
+ transform: [{ translateX: '-25%' }],
+ },
+ to: {
+ transform: [{ translateX: '25%' }],
+ },
+ },
+ animationDuration: '1s',
+ animationIterationCount: 'infinite',
+ animationTimingFunction: 'linear',
+};
+
+export function Shimmer({
+ style,
+ children,
+ ...rest
+}: React.PropsWithChildren): JSX.Element {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/yarn.lock b/yarn.lock
index 8e459b0..25c7ae5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2906,6 +2906,16 @@ __metadata:
languageName: node
linkType: hard
+"@react-native-masked-view/masked-view@npm:0.3.2":
+ version: 0.3.2
+ resolution: "@react-native-masked-view/masked-view@npm:0.3.2"
+ peerDependencies:
+ react: ">=16"
+ react-native: ">=0.57"
+ checksum: e35ab882148df3f9b71f04355d2fb1b24d6f2aaf29043f80758f398bdf905eed67734b36b072fa8b934923ff4e3d80ccb5e37d8376cb1825272078b96a21dadc
+ languageName: node
+ linkType: hard
+
"@react-native/assets-registry@npm:0.76.6":
version: 0.76.6
resolution: "@react-native/assets-registry@npm:0.76.6"
@@ -6546,6 +6556,17 @@ __metadata:
languageName: node
linkType: hard
+"expo-linear-gradient@npm:~14.0.2":
+ version: 14.0.2
+ resolution: "expo-linear-gradient@npm:14.0.2"
+ peerDependencies:
+ expo: "*"
+ react: "*"
+ react-native: "*"
+ checksum: 3f318f50fae44b1f2f90becf421a1c7c0c2822e0a381031fa6d893899173b7ecc6f0c4eddde699e6825fd091d5576cf5960ba81046aeaf0300f44de1147bb543
+ languageName: node
+ linkType: hard
+
"expo-modules-autolinking@npm:2.0.5":
version: 2.0.5
resolution: "expo-modules-autolinking@npm:2.0.5"
@@ -11785,7 +11806,9 @@ __metadata:
dependencies:
"@babel/core": ^7.20.0
"@expo/metro-runtime": ~4.0.0
+ "@react-native-masked-view/masked-view": 0.3.2
expo: ~52.0.25
+ expo-linear-gradient: ~14.0.2
expo-status-bar: ~2.0.1
react: 18.3.1
react-dom: 18.3.1