Skip to content
Native Animation
VPN Connect Globe animation preview

This preview uses fictional demo content. See the props below for the customization options available in this component.

npx nativeanimation add vpn-connect-globe
SkiaGlass

VPN Connect Globe

A VPN status panel with a rotating globe and rolling session timer, with configurable locations, status labels, colors, and fonts.

$9 for this animation

Add to your project

Copy the component and its assets into your app with the Native Animation CLI, or paste the agent prompt into Claude Code, Codex or Cursor once the MCP server is connected.

About this animation

A VPN status panel with a rotating globe and rolling session timer, with configurable locations, status labels, colors, and fonts. Your app supplies the connection state; this is presentation UI rather than a VPN client.

Why this one

Connecting becomes visible: points travel from the world into the button, then a 550 ms light pulse follows the horizon when the connection settles. A location change rotates the globe and starts a fresh connection. The world-to-button flow and the horizon pulse add two visual layers to a conventional connection switch.

How it works

  1. A measured, scrollable layout keeps text and controls in flow, caps the panel width at 420 pt, and sizes the globe from its container.
  2. Latitude/longitude samples project onto a sphere. A deterministic noise-band mask distinguishes stylized land from ocean; it is decorative geography, not a map.
  3. Two Points batches draw all globe dots in one Canvas. Shared values drive rotation, particles, the continuous ring, and horizon light on the UI thread.
  4. The uncontrolled machine moves from disconnected to connecting to connected. A second tap cancels or disconnects; changing locations requests a fresh connection.
  5. Each timer digit animates independently to an exact integer. Separators own their widths; accessibility text updates only once per elapsed second.
  6. The demo runs: 1 s idle → 1.6 s connect → 3 s connected → Tokyo/reconnect → disconnect → repeat. Any touch stops automation.

Install

npx expo install @shopify/react-native-skia expo-blur expo-linear-gradient react-native-gesture-handler react-native-reanimated react-native-worklets

Use a GestureHandlerRootView in your host app. On web, initialize CanvasKit before rendering this component (Expo/Skia's LoadSkiaWeb or equivalent host loader). The component has no external assets or catalog imports. Icons: Lucide (ISC), copied from the Native Animation kit. The demo uses the kit's Nimbus cloud tile, never an invented arrow logo.

Usage

import { VpnConnectGlobe } from './vpn-connect-globe';

<VpnConnectGlobe
  locations={[
    { id: 'lisbon', label: 'Lisbon · PT', longitude: -9.14 },
    { id: 'tokyo', label: 'Tokyo · JP', longitude: 139.69 },
  ]}
  onConnect={() => requestConnection()}
  onDisconnect={() => closeConnection()}
/>

Customize or manage actual connection results from your host:

const connection = useRef<VpnConnectGlobeRef>(null);

<VpnConnectGlobe
  ref={connection}
  status={networkStatus}
  location={selectedLocationId}
  locations={availableLocations}
  onLocationChange={item => setSelectedLocationId(item.id)}
  onConnect={connectNetwork}
  onDisconnect={disconnectNetwork}
  connectDuration={1600}
  rotationSpeed={0.025}
  colors={{ accent: '#A493FF', land: '#D0C7FF', muted: '#A5A9CD' }}
  fontFamily="YourRegularFont"
  semiboldFontFamily="YourSemiboldFont"
  monoFontFamily="YourMonoFont"
/>

Import VpnConnectGlobeRef from the same folder. Its methods are connect(), disconnect(), and selectLocation(id). In controlled mode, these methods and taps request changes through callbacks; the host must update status and location. Controlled connecting stays connecting until the host reports a result. In uncontrolled mode, completion is simulated after connectDuration.

Props

PropTypeDefaultPurpose
statusVpnConnectionStatusuncontrolleddisconnected, connecting, or connected
onConnect, onDisconnect() => void—Connection requests; cancel also requests disconnect
onStatusChange(status) => void—Visual state changes
locationsreadonly VpnLocation[]Nearby · USIDs, display labels, longitudes, optional dot colors
location, onLocationChangestring, (item) => voiduncontrolled, —Controlled selection; tapping cycles locations
colorsPartial<VpnGlobeColors>night paletteBackground/end, surface, button, text, muted, border, accent, ocean, land, brand start/end
title, subtitlestringBrowse from anywhere, / privatelyHeading and dimmed continuation
brandstringPrivate networkWordmark
connectionLabelstringSecure connectionTimer caption
statusLabelsRecord<VpnConnectionStatus, string>Connect / Connecting… / ConnectedVisible and announced states
footerstringYour connection. Your world.Supporting copy
settingsLabel, favoriteLabel, locationLabelstringConnection settings / Favorite connection / Change locationAccessible labels
onSettings, onFavorite() => void—Optional actions; otherwise their icons are decorative
onInteraction() => void—User touch/accessibility activation; stop host automation
fontFamily, semiboldFontFamily, monoFontFamilystringsystemHost-loaded text fonts
connectDurationnumber1600Connection duration in ms (minimum 200)
initialSecondsnumber0Initial elapsed time for an initially connected state
rotationSpeednumber0.035Ambient radians per second
styleStyleProp<ViewStyle>—Root overrides; defaults to flex 1
testIDstringvpn-connect-globeRoot; controls append -connect, -location, -settings, -favorite

Compatibility

Targets Expo SDK 58, React Native 0.88.0, Reanimated 4.7.1, Worklets 0.13.0, and Skia 2.14.0. Uses modules available in this project's Expo Go. Android glass uses BlurTargetView and the SDK 31+ blur method; older Android versions keep the tinted surface fallback. Web requires host CanvasKit initialization.

The host supplies safe-area padding. Width is capped; short containers and large type can scroll instead of hiding controls. The intended layout covers 320×568, 390×844, 430×932, tablet, landscape, and a 300×400 embedded panel.

Accessibility

Interactive elements expose button roles, labels, selected state, activate actions, and at least 48 pt touch areas. Major status changes are announced. The timer has a single spoken value; its visual digit layers are excluded from accessibility. All important text is configurable.

Reduced motion removes ambient rotation, spark flights, horizon sweeps, and digit travel. State content fades over 200 ms; timer digits crossfade. No dragging is required: tap to connect/disconnect or cycle locations.