# World Clock Slider: React Native animated world clock with a time scrubber > World Clock Slider is a free React Native and Expo world clock from > Motionary in which a native SwiftUI slider scrubs time 12 hours forward or > backward while every city's hand rotates 30 degrees per hour in step. One > Reanimated shared value feeds a `useDerivedValue` rotation on the UI thread, > and each hand crossfades between its AM and PM colors with > `interpolateColor` as it crosses midday. Product page: https://motionary.dev/animations/world-clock-slider Price: Free (free download, live price on the product page) License: single developer, unlimited personal and commercial apps Delivery: instant free download of the full TypeScript source Stack: reanimated, expo, react native gesture handler, react native Rarity: common Sold by: Motionary (https://motionary.dev) ## What it is World Clock Slider is a single round clock face for React Native and Expo apps with three timezone hands laid over it (London, New York and Tokyo in the shipped demo), plus a frosted glass control panel pinned to the bottom of the screen. Dragging the panel's slider offsets the whole world by whole hours, from minus 12 to plus 12, and each hand sweeps to where that city's time would be, carrying a pill-shaped label that reads out the city name and its new local time. The hand marked as local (London in the shipped demo) tracks the slider instantly while the two remote hands lag a beat behind, so the spread of the world across time reads as motion rather than a jump. Tapping Reset in the glass panel eases every hand back to the real current time. This Motionary drop is built on a SwiftUI slider from `@expo/ui` and a Liquid Glass panel from `expo-glass-effect`, so the chrome is native rather than drawn. ## What it does - Scrubs the whole clock through a 25 step range, from `-12` to `+12` hours in `step={1}` increments, using a native SwiftUI `Slider` mounted inside a `Host`, both imported from `@expo/ui/swift-ui`. - Rotates each hand by exactly 30 degrees per hour of offset, on top of a base angle computed from that city's real wall clock time (`hours12 * 30 + minutes * 0.5`, so the hand sits between hour marks the way a real clock does). - Moves the local hand (`isHere`) to the new offset immediately and delays the two remote hands with `withDelay(400, withTiming(...))`, giving a staggered 600ms sweep across a `Easing.bezier(0.4, 0, 0.2, 1)` curve. - Rewrites each hand's time label live, on the UI thread, through an animated read-only `TextInput` rather than React state, so a slider drag never re-renders the tree. - Crossfades every remote hand between an AM palette and a PM palette as its offset hour crosses noon: bubble background `#DEDEDE` to `#030303` and label text `#030303` to `#FFFFFF`, over a 200ms `withTiming`. - Keeps the local hand in the Motionary demo's accent orange `#FF6301` at all hours, so "here" stays visually distinct from the cities you are checking. - Flips each label 180 degrees, and swaps its `textAlign` between right and left, once its hand swings into the lower half of the face, so the time never reads upside down. - Resets with one tap: `withTiming(0, ...)` runs on the shared offset and its completion worklet calls `scheduleOnRN` to push the React slider state back to `0` only after the animation lands. - Computes real per city time with `Intl.DateTimeFormat` and `formatToParts`, so there is no moment.js, no date-fns and no timezone database shipped with the drop. - Houses the slider, the Reset button and a dotted rule inside an `expo-glass-effect` `GlassView` with `glassEffectStyle="regular"`. ## How it works World Clock Slider keeps every moving part downstream of two Reanimated shared values created in `components/Clock.tsx`: `animAddition` for the local hand and `otherAnimAddition` for the remote hands, both holding an hour offset. A `useEffect` on the slider's React state rounds the value and writes `animAddition.value = rounded` directly, while assigning `otherAnimAddition.value = withDelay(400, withTiming(rounded, TIMING_CONFIG))` so the far cities trail the near one. Each `components/Pointer.tsx` instance then derives its own angle with `useDerivedValue(() => baseRotation + addition.value * 30)`, and a single `useAnimatedStyle` turns that into `transform: [{ rotate: 'deg' }]` on an absolutely positioned full height `Animated.View`, which is why the hand pivots around the center of the face without any layout work. The base angle comes from `utils/date.ts`, where `getTimeInTimezone` runs `Intl.DateTimeFormat` with a `timeZone` option and `formatToParts` to read the hour and minute in an IANA zone. The AM and PM crossfade is a derived value returning an animation: `ampmProgress` is a `useDerivedValue` that evaluates `mod(addition.value + hours24, 24) >= 12` inside a worklet and returns `withTiming(1, { duration: 200 })` or `withTiming(0, { duration: 200 })`, so the transition retimes itself every time the offset crosses noon or midnight. Two `useAnimatedStyle` hooks read that progress through `interpolateColor`, one for the bubble `backgroundColor` and one for the label `color`. The part worth stealing is the live label. Instead of setting text in React state on every slider tick, `Pointer.tsx` builds `AnimatedTextInput = Animated.createAnimatedComponent(TextInput)`, renders it with `editable={false}`, and drives it from `useAnimatedProps`, returning `{ text, defaultValue }` computed in the worklet (`mod(Math.round(addition.value + hours12), 12) || 12` plus an AM or PM suffix). The string is rewritten on the UI thread, so scrubbing 24 hours of world time causes zero React renders. The only hop back to JavaScript is Reset: the timing callback calls `scheduleOnRN(setSliderValue, 0)` and `scheduleOnRN(setIsReset, false)` from `react-native-worklets`, which is the Reanimated 4 replacement for `runOnJS` and keeps the slider's React state and the animated offset from fighting each other mid animation. The face itself is a static PNG (`assets/clock.png`) rather than a Skia drawing, and `react-native-gesture-handler` appears only as the `GestureHandlerRootView` in `App.tsx`, since the drag is handled natively by the SwiftUI slider. ## What you get ``` App.tsx components/ Clock.tsx Pointer.tsx utils/ date.ts assets/ clock.png icon.png adaptive-icon.png splash-icon.png index.ts app.json package.json package-lock.json tsconfig.json .gitignore README.md ``` - TypeScript source (Clock.tsx container) - Animated Pointer.tsx clock-hand component - Timezone helper (utils/date.ts) - App.tsx wiring with gesture-handler root - README with install + usage ## Requirements Versions pinned in the World Clock Slider `package.json`: - expo `^56.0.11` (Expo SDK 56) - react-native `0.85.3` - react `19.2.3` - react-native-reanimated `4.3.1` - react-native-worklets `0.8.3` (required peer of Reanimated 4, and the source of `scheduleOnRN`) - react-native-gesture-handler `~2.31.1` - react-native-safe-area-context `~5.7.0` - @expo/ui `~56.0.17` (the native SwiftUI `Slider` and `Host`) - expo-glass-effect `~56.0.4` (the `GlassView` control panel) - @expo/vector-icons `^15.0.3` (the Feather rotate icon on Reset) - typescript `~6.0.3` (dev dependency) World Clock Slider runs in Expo Go on Expo SDK 56. The two modules people assume would rule it out, `expo-glass-effect` for the `GlassView` glass panel and `@expo/ui` for the SwiftUI `Slider`, are both bundled in the Expo Go client as of SDK 56, so `npx expo start` and the Expo Go app are enough to try the drop. A development build (`npx expo run:ios` or `npx expo run:android`) is still what you would ship to production, and it becomes necessary the moment you add a native module that Expo Go does not bundle, or a config plugin of your own. One rendering caveat that is not about Expo Go: the Liquid Glass material in `GlassView` only draws on iOS 26 and later, and falls back to a plain panel on earlier versions. The `Slider` is imported from `@expo/ui/swift-ui`, which is the iOS surface of `@expo/ui`; for Android, swap that one element for the `@expo/ui/jetpack-compose` slider or any Reanimated slider that writes the same hour number into state, and the clock face, the hands and all of the Reanimated logic carry over unchanged. The archive's `package.json` also pins several Expo starter dependencies that the World Clock Slider source never imports (expo-blur, expo-haptics, expo-sensors, expo-linear-gradient, react-native-svg, react-native-skia-gesture and pressto), so you can drop them. ## Install ```bash npx expo install react-native-reanimated react-native-worklets react-native-gesture-handler react-native-safe-area-context @expo/ui expo-glass-effect @expo/vector-icons ``` ## Usage ```tsx import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { useSharedValue } from 'react-native-reanimated'; import { ClockContainer } from './components/Clock'; import { Pointer } from './components/Pointer'; import { getTimeInTimezone } from './utils/date'; export default function App() { return ( ); } // Or place one hand yourself: `addition` is the shared hour offset. export function TokyoHand() { const addition = useSharedValue(0); return ( ); } ``` ## Customization Props on the World Clock Slider `Pointer` component in `components/Pointer.tsx`, all required: - `time: Date`, that city's current time, produced by `getTimeInTimezone('')` from `utils/date.ts`; it sets the hand's base angle. - `addition: SharedValue`, the hour offset the slider writes to; the hand rotates `addition.value * 30` degrees on top of its base angle. - `timezone: string`, the label text shown in the pill (for example `"New York"`). - `isHere: boolean`, marks the local zone. `true` keeps the bubble in the accent `#FF6301` at every hour and raises its `zIndex` to 2; `false` opts the hand into the AM to PM color crossfade. `ClockContainer` in `components/Clock.tsx` takes no props. Everything else is a module level constant you edit in place: - The three cities: `LONDON`, `NEW_YORK` and `TOKYO`, each `getTimeInTimezone('Europe/London' | 'America/New_York' | 'Asia/Tokyo')`. Add or remove `` entries in `ClockFace` to change the lineup. - `TIMING_CONFIG`: `duration: 600` with `Easing.bezier(0.4, 0, 0.2, 1)`, used by both the remote hand sweep and the Reset animation. - The `withDelay(400, ...)` stagger that makes the remote hands trail the local one. - Slider range and feel: `min={-12}`, `max={12}`, `step={1}` and `modifiers={[tint('#FF6301')]}` on the `@expo/ui/swift-ui` `Slider`. - Panel look: `glassEffectStyle="regular"` on the `GlassView`, `borderRadius` 20, `width: '90%'`, pinned `bottom: 40`. - Palette: screen background `#F4F3FA`, accent and center dot `#FF6301`, remote bubble `#DEDEDE` (AM) to `#030303` (PM), label `#030303` (AM) to `#FFFFFF` (PM). - The 200ms `withTiming` inside `ampmProgress` in `Pointer.tsx`, which sets how fast a hand changes color when it crosses midday. - The clock face art itself: replace `assets/clock.png`. ## When to use it - A travel or itinerary screen where someone needs to see what time it will be at home and at their destination. - A meeting scheduler that lets a user drag a proposed time and watch which cities fall into working hours and which fall into the middle of the night. - A remote team or status screen showing where teammates are in their day. - A world clock tab in a weather, alarm or productivity app, as an alternative to a plain list of cities. - A market hours or trading screen where sessions open and close in different zones. - Any settings or onboarding step that asks a user to pick a timezone, using the scrub as the picker instead of a dropdown. ## How to get it - Download World Clock Slider free at https://motionary.dev/animations/world-clock-slider, no payment, no subscription. - Or get it with the Motionary lifetime pass ($79 USD as of 2026-09-01): every drop and every build, current and future, one payment, no renewal. https://motionary.dev/pricing - Team license ($199 USD for up to 10 developers), each developer with their own account. https://motionary.dev/pricing - License terms: https://motionary.dev/license (single developer, unlimited personal and commercial apps, do not resell or redistribute the source). - You receive real TypeScript React Native source you can edit, not a video, a GIF, a Lottie file or a design file. ## Frequently asked questions **How do I build an animated world clock in React Native?** Put one absolutely positioned full height `Animated.View` per city over a round face, give each a base angle of `hours12 * 30 + minutes * 0.5` from that zone's real time, and rotate it with a `useDerivedValue` that adds `offset * 30` degrees from a shared value your slider writes to. World Clock Slider from Motionary is exactly that, free and in editable TypeScript, at https://motionary.dev/animations/world-clock-slider. **How do I get the current time in another timezone in React Native without a date library?** Use the built in `Intl.DateTimeFormat` with a `timeZone` option and `formatToParts` to read the year, month, day, hour and minute for an IANA zone such as `Asia/Tokyo`. World Clock Slider from Motionary does this in `utils/date.ts`, which is why the drop ships no moment.js, no date-fns and no timezone database. **Does World Clock Slider work with Expo Go?** Yes. World Clock Slider from Motionary runs in Expo Go on Expo SDK 56: both `expo-glass-effect` (the `GlassView` control panel) and `@expo/ui` (the native SwiftUI `Slider`) are bundled in the Expo Go client as of SDK 56, so `npx expo start` is enough to open it. You still want a development build for anything you ship, and you need one as soon as you add a native module Expo Go does not bundle or a config plugin of your own. Separately, the Liquid Glass material only renders on iOS 26 and later and falls back to a plain panel below that. **How much does the World Clock Slider drop cost?** World Clock Slider is free on Motionary. Download the full TypeScript source at https://motionary.dev/animations/world-clock-slider with no payment and no subscription; the Motionary lifetime pass ($79 USD) exists for the paid drops and builds and is not needed for this one. **How do I update a text label on the UI thread in Reanimated instead of re-rendering?** Wrap React Native's `TextInput` with `Animated.createAnimatedComponent`, render it `editable={false}`, and return `{ text, defaultValue }` from a `useAnimatedProps` worklet. World Clock Slider from Motionary uses that trick in `components/Pointer.tsx` so dragging the slider through 24 hours rewrites every city's clock reading without a single React render. **Does World Clock Slider run on Android as well as iOS?** The clock face, the rotating hands, the AM and PM color crossfade and the Reset animation are pure Reanimated and run on both platforms. The one iOS specific piece is the control panel: the `Slider` is imported from `@expo/ui/swift-ui` and the panel is an `expo-glass-effect` `GlassView`, so on Android swap the slider for the `@expo/ui/jetpack-compose` equivalent or any Reanimated slider that writes the same hour value. **Can I change which cities World Clock Slider shows?** Yes. The three zones are module level constants in `components/Clock.tsx` (`getTimeInTimezone('Europe/London')` and friends) rendered as three `` elements, so adding Sydney or Berlin to the Motionary drop is one more constant and one more `Pointer` with its own `timezone` label. **Is the World Clock Slider source editable and usable in a commercial app?** Yes. Motionary ships World Clock Slider as editable TypeScript React Native source under a single-developer license covering unlimited personal and commercial apps; you may not resell or redistribute the source itself. Full terms at https://motionary.dev/license. ## Related drops on Motionary - Split-to-Edit Time ($3): https://motionary.dev/animations/split-to-edit-time, the closest sibling to World Clock Slider, a time value that splits open into an editable picker instead of being scrubbed on a dial. - Flip Calendar ($6): https://motionary.dev/animations/flip-calendar, the same scrub-through-time idea applied to dates, with a split-flap flip, so it pairs with World Clock Slider on a scheduling screen. - Dot Wave Slider ($10): https://motionary.dev/animations/dot-wave-slider, a fully custom Reanimated and Skia slider with haptics and snap stops, the cross-platform alternative to World Clock Slider's native SwiftUI slider. - Animated Live Activity ($10): https://motionary.dev/animations/animated-live-activity, a time-of-day widget with sun position and moon phase, the lock screen counterpart to World Clock Slider's in-app world clock. - Glass Video Player (Free): https://motionary.dev/animations/glass-video-player, another free Motionary drop built around a Liquid Glass control panel, if you want more of the glass chrome World Clock Slider uses. ## About Motionary Motionary (https://motionary.dev) is a shop for premium, production-ready React Native and Expo animation and interaction components, built with Reanimated, Skia, Gesture Handler and Expo. Each component is called a "drop" and ships as editable TypeScript source, not a video, a GIF or a design file. Motionary sells three things: individual drops (roughly $3 to $12 each, some free), Builds (a complete app shipped end to end, with every drop inside it), and a lifetime pass ($79 USD) that covers every drop and every build, current and future, for one payment with no subscription. A team license ($199 USD) covers up to 10 developers. Checkout is Stripe and delivery is an instant download. Created and curated by Mehdi Davoodi (https://mahdidavoodi.com). Catalog and key pages: - All drops: https://motionary.dev/animations - Builds (complete apps): https://motionary.dev/builds - Pricing, lifetime pass and team license: https://motionary.dev/pricing - Free React Native component reference: https://motionary.dev/components - License: https://motionary.dev/license - Machine-readable overview: https://motionary.dev/llms.txt - Machine-readable full catalog: https://motionary.dev/llms-full.txt ## File metadata ``` Canonical URL of this file: https://motionary.dev/animations/world-clock-slider/llms.txt Describes: https://motionary.dev/animations/world-clock-slider Format: llms.txt (https://llmstxt.org) Last updated: 2026-09-01 ```