├── .gitignore ├── README.md ├── app.json ├── app ├── (tabs) │ ├── _layout.tsx │ └── index.tsx └── _layout.tsx ├── assets ├── fonts │ └── SpaceMono-Regular.ttf └── images │ ├── adaptive-icon.png │ ├── favicon.png │ ├── icon.png │ ├── partial-react-logo.png │ ├── react-logo.png │ ├── react-logo@2x.png │ ├── react-logo@3x.png │ └── splash-icon.png ├── bun.lockb ├── components └── immersive-overlay │ ├── components │ ├── gradient │ │ ├── constants.ts │ │ └── index.tsx │ └── overlay.tsx │ ├── index.tsx │ ├── store.tsx │ └── utils.ts ├── constants └── Colors.ts ├── hooks └── useColorScheme.ts ├── package.json ├── scripts └── reset-project.js └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # Expo 7 | .expo/ 8 | dist/ 9 | web-build/ 10 | expo-env.d.ts 11 | 12 | # Native 13 | *.orig.* 14 | *.jks 15 | *.p8 16 | *.p12 17 | *.key 18 | *.mobileprovision 19 | 20 | # Metro 21 | .metro-health-check* 22 | 23 | 24 | ios/ 25 | android/ 26 | 27 | # debug 28 | npm-debug.* 29 | yarn-debug.* 30 | yarn-error.* 31 | 32 | # macOS 33 | .DS_Store 34 | *.pem 35 | 36 | # local env files 37 | .env*.local 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | 42 | app-example 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Immersive overlay example 2 | 3 | As seen on X (thank you for the positive comments!), this is a component inspired by the apple intellgence animation, if you have an iOS device and apple intelligence enabled, long press your power button to see it in action. 4 | 5 | Not a full replica, as this component was built for my own personal needs, however I think something great came out of it. 6 | 7 | That being said, since my app is developed for iOS, I have not tested in android 😭, however, this is using well managed packages such as expo-blur, skia, and reanimated. Fingers crossed all is well. 8 | 9 | Create an expo dev build 10 | 11 | ``` 12 | npm install 13 | 14 | npx expo prebuild 15 | 16 | npx expo run ios 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "immersive-overlay-example", 4 | "slug": "immersive-overlay-example", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/images/icon.png", 8 | "scheme": "myapp", 9 | "userInterfaceStyle": "light", 10 | "newArchEnabled": true, 11 | "ios": { 12 | "supportsTablet": true, 13 | "bundleIdentifier": "com.eds2002.immersiveoverlayexample" 14 | }, 15 | "android": { 16 | "adaptiveIcon": { 17 | "foregroundImage": "./assets/images/adaptive-icon.png", 18 | "backgroundColor": "#ffffff" 19 | }, 20 | "package": "com.eds2002.immersiveoverlayexample" 21 | }, 22 | "web": { 23 | "bundler": "metro", 24 | "output": "static", 25 | "favicon": "./assets/images/favicon.png" 26 | }, 27 | "plugins": [ 28 | "expo-router", 29 | [ 30 | "expo-splash-screen", 31 | { 32 | "image": "./assets/images/splash-icon.png", 33 | "imageWidth": 200, 34 | "resizeMode": "contain", 35 | "backgroundColor": "#ffffff" 36 | } 37 | ] 38 | ], 39 | "experiments": { 40 | "typedRoutes": true 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/(tabs)/_layout.tsx: -------------------------------------------------------------------------------- 1 | import { Tabs } from "expo-router"; 2 | import React from "react"; 3 | 4 | import { ImmersiveOverlay } from "@/components/immersive-overlay"; 5 | import { Colors } from "@/constants/Colors"; 6 | import { useColorScheme } from "@/hooks/useColorScheme"; 7 | 8 | export default function TabLayout() { 9 | const colorScheme = useColorScheme(); 10 | 11 | return ( 12 | 13 | {/*Wrapper that gives us our screen 'warp' effect */} 14 | 20 | 26 | 27 | 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /app/(tabs)/index.tsx: -------------------------------------------------------------------------------- 1 | import { useImmersiveOverlay } from "@/components/immersive-overlay/store"; 2 | import { Button, Text, View } from "react-native"; 3 | 4 | export default function HomeScreen() { 5 | const { immerse } = useImmersiveOverlay(); 6 | 7 | const basicExampleFn = () => { 8 | immerse(); 9 | }; 10 | 11 | const differentPalleteExampleFn = () => { 12 | // Pallete generated by ai, wow what a crazy pallete 13 | immerse({ 14 | colors: { 15 | primary: "#FF69B4", 16 | secondary: "#1E90FF", 17 | expanding: { 18 | dark: ["#FF69B4", "#DA70D6", "#1E90FF"], 19 | light: ["#FF69B4", "#DA70D6", "#1E90FF"], 20 | }, 21 | }, 22 | }); 23 | }; 24 | 25 | const withComponentExampleFn = () => { 26 | immerse({ 27 | component: ( 28 | 36 | 37 | dimelo 38 | 39 | 47 | Hello, Hola, Bonjour, Ciao, Hallo, Olá, Привет, こんにちは, 你好, 48 | 안녕하세요, Merhaba, Γειά σου, नमस्ते, สวัสดี, Xin chào, Salaam, Jambo, 49 | Hej, Ahoj, Aloha 50 | 51 | 52 | ), 53 | colors: { 54 | primary: "#FF0000", 55 | secondary: "#8B0000", 56 | expanding: { 57 | dark: ["#FF0000", "#B22222", "#8B0000"], 58 | light: ["#FF6347", "#DC143C", "#CD5C5C"], 59 | }, 60 | }, 61 | }); 62 | }; 63 | 64 | return ( 65 | 73 |