# Freeze Card: React Native bank card that ices over, drawn with a Skia frost shader > Freeze Card is a React Native and Expo component that freezes a bank card on > tap: an SkSL runtime shader in `@shopify/react-native-skia` grows a dendritic > frost front in from the four corners, refracts the card art through crystal > facets, and creeps a matching ice lattice onto the background behind it, all > driven by `react-native-reanimated` shared values on the UI thread. Sold by > Motionary as editable TypeScript source. Product page: https://motionary.dev/animations/freeze-card Price: $9 USD (price as of 2026-09-01, live price on the product page) License: single developer, unlimited personal and commercial apps Delivery: instant download of the full TypeScript source after checkout Stack: expo, reanimated, shaders, react native skia, react native Rarity: legendary Sold by: Motionary (https://motionary.dev) ## What it is Freeze Card is a React Native card-lock interaction for fintech and banking apps. In the included wallet screen the card sits in a scrolling list under a balance and above a transaction feed; tap it and it lifts out of the list, scales up and springs to the middle of the screen while the rest of the app dims behind a scrim and the list stops scrolling. A focus bar slides up from the bottom with two circular actions, Freeze and Delete. Tap Freeze and ice takes about two seconds to crawl in from the four corners of the card: the artwork, the wordmark and the masked digits all bend and blur behind the crystal instead of the frost floating on top of them, a snowflake settles and breathes in the middle, and the cold keeps spreading out past the card's edges onto the black screen behind it as a lattice of ice lines with a shadow and a bright contact line where the card meets it. The Freeze action cross-fades to an amber Unfreeze face, and tapping anywhere off the card puts it back in the list. ## What it does - Freezes and thaws on one shared value, `progress`, running 0 to 1 on an overdamped spring (`damping: 22, stiffness: 16, mass: 1`) that reaches full ice in roughly two seconds with no bounce; thawing uses a brisker spring (`damping: 18, stiffness: 42, mass: 1`). - Grows the ice as a distance field to the card's four corners, warped by fbm and eroded by two higher-frequency octaves, so four expanding circles read as four dendritic frost blooms that meet in the middle. - Refracts the real card contents: the frost effect takes the rasterised card face as a child shader and displaces it along Voronoi facet vectors plus fine grain, so the print refracts with the artwork. - Scatters light through the ice with a six tap blur ring, jittered per pixel so it never bands, mixed 0.78 against the displaced sample. - Adds crystal seams, a bright crystalline lip riding the advancing front, and a twinkling sparkle field driven by a clock uniform. - Creeps a second, separate effect onto the background over 5600 ms (`AURA_MS`), reaching 92 dp past the card edge (`AURA_SPREAD`), drawing the same Voronoi lattice at a coarser grain plus a downward drop shadow and a tight bright contact line, composited in premultiplied alpha. - Paints the card face itself with a third shader: a procedural domain-warped violet aurora with a light shaft from the lower left, so the art stays crisp at any card width and gives the frost something rich to refract. - Settles a procedural snowflake, built from an SVG path re-centred and scaled to 30 percent of the card width, that scales and un-rotates in between `progress` 0.34 and 0.92 and then sways on a sine. - Lifts the card out of the list with a spring on a `focus` shared value: scrim opacity, close-button scale, focus-bar slide, scroll lock and hit testing all interpolate from that one value. - Cross-fades the Freeze action to Unfreeze (snow icon to sunny icon, cold blue `#9fd8ff` to warm `#ffd479`) straight off the freeze shared value, so the label tracks state with no React state. - Fires `expo-haptics` impact feedback: light on picking a card up or putting it down, heavy on freezing. - Stops the sparkle clock whenever the card is clear, which lets the Skia canvas stop repainting entirely instead of burning a draw call per frame. - Ships a full wallet demo screen: brand header, chips, balance, three account actions, a monthly-limit spend bar and a static transaction list. ## How it works Freeze Card is rendered by three SkSL runtime effects compiled with `Skia.RuntimeEffect.Make` in `src/card/shaders.ts`: `auroraEffect` (the card artwork), `frostEffect` (the ice on the card) and `auraEffect` (the ice on the background). `src/card/cardFace.ts` draws the whole face, aurora artwork, brand mark, wordmark, masked digits and scheme mark, straight onto a Skia canvas, and `src/card/FreezeCard.tsx` rasterises that once inside a `useMemo` with `createPicture` plus `drawAsImageFromPicture` at `PixelRatio.get()`, so freezing never re-renders the card's contents. That image is fed back in as an `` child of ``, which is why the shader can call `card.eval(fc + disp)` and refract the printed text along with the artwork. Uniforms are not props but `useDerivedValue` objects from `react-native-reanimated`, so `progress`, `aura` and `time` reach the GPU without a React render. `src/wallet/WalletScreen.tsx` owns every shared value (`focus`, `progress`, `aura`, `scrollY`, `cardTop`, `time`) and holds zero React state: `useAnimatedStyle` moves the card between its measured slot in the `Animated.ScrollView` and the centre of the screen, `useAnimatedScrollHandler` keeps `scrollY` current, `useAnimatedProps` flips `scrollEnabled` while a card is focused, and hit testing is animated too because `pointerEvents` is written as a style property inside `useAnimatedStyle` rather than a prop. Gestures are `Gesture.Tap()` detectors from `react-native-gesture-handler` whose `onEnd` callbacks are worklets, so a freeze never crosses to the JavaScript thread except for the `runOnJS` call that fires `expo-haptics`. The sparkle clock is gated by a `useAnimatedReaction` on `progress.value > 0.002`: when ice appears it starts a linear `withRepeat(withTiming(...))` ramp calibrated so the uniform equals elapsed seconds, and when the card clears it calls `cancelAnimation` and resets to 0, which is what lets the canvas idle. Inside `frostEffect` the ice mask is `1.0 - smoothstep(reach - feather, reach, d)` where `d` is the fbm warped minimum distance to the four corners and `reach` scales with `progress`, and the shader early-returns the untouched card when `progress < 0.0015` or the mask is negligible, so an unfrozen card costs almost nothing. The background `auraEffect` runs in its own `` inset by `AURA_SPREAD` behind the card with `pointerEvents="none"`, uses a signed-distance rounded rect to stay outside the card, and returns premultiplied alpha, which is what a Skia runtime shader has to produce. ## What you get ``` App.tsx index.ts src/ theme.ts brand.ts transactions.ts card/ FreezeCard.tsx cardFace.ts shaders.ts snowflake.ts wallet/ WalletScreen.tsx AccountSummary.tsx MonthlyLimit.tsx TransactionList.tsx FocusBar.tsx app.json babel.config.js package.json tsconfig.json README.md ``` - TypeScript source (`FreezeCard.tsx`) - SkSL runtime shaders (frost, aura, procedural aurora card art) - Procedural snowflake path builder - Full wallet demo screen (summary, monthly limit, transactions, focus bar) - Theme and brand token files - README with install and usage - MP4 preview ## Requirements Freeze Card is pinned in its `package.json` to: - `expo` ~56.0.11 (Expo SDK 56) - `react-native` 0.85.3 - `react` 19.2.3 - `@shopify/react-native-skia` 2.6.2 - `react-native-reanimated` 4.3.1 - `react-native-worklets` 0.8.3 - `react-native-gesture-handler` ~2.31.1 - `react-native-safe-area-context` ~5.7.0 - `expo-haptics` ~56.0.3 (impact feedback on pick-up and freeze) - `expo-linear-gradient` ~56.0.4 (the monthly-limit bar) - `@expo/vector-icons` ^15.0.3 (focus bar and demo screen icons) - `expo-status-bar` ~56.0.4, `expo-asset` ~56.0.14, `expo-font` ~56.0.5 - TypeScript ~6.0.3 (devDependency) Freeze Card runs in Expo Go on Expo SDK 56. The module people assume rules Expo Go out, `@shopify/react-native-skia`, is bundled in Expo Go as of SDK 56, and Freeze Card imports nothing else Expo Go leaves out (Reanimated, Gesture Handler, Safe Area Context, `expo-haptics`, `expo-linear-gradient` and `@expo/vector-icons` are all in there), so `npx expo start` plus the Expo Go app is enough to hold a frozen card in your hand. A development build (`npx expo run:ios` or `npx expo run:android`) is still what you would ship to production, and it becomes required the moment you add a native module Expo Go does not bundle, or a config plugin that changes the native project. Freeze Card itself adds no custom native code. The drop runs on both iOS and Android; its `app.json` sets `CADisableMinimumFrameDurationOnPhone` so the shader animates at the full ProMotion refresh rate on iPhone, and enables the React Compiler experiment. That Info.plist key is a native build setting, so the 120 Hz unlock only applies in a build; inside Expo Go on iOS the freeze still runs, just capped at 60 Hz. As the README notes, the card is drawn by SkSL shaders, so the freeze does not show up in a plain browser preview. ## Install ```bash npx expo install @shopify/react-native-skia react-native-reanimated react-native-worklets react-native-gesture-handler react-native-safe-area-context expo-haptics expo-linear-gradient expo-status-bar @expo/vector-icons ``` ## Usage ```tsx import { Pressable } from 'react-native'; import { Easing, useSharedValue, withRepeat, withSpring, withTiming, } from 'react-native-reanimated'; import { FreezeCard } from './src/card/FreezeCard'; const CREEP = { duration: 5600, easing: Easing.out(Easing.cubic) }; const CLOCK = { duration: 1e8, easing: Easing.linear }; export default function CardScreen() { const progress = useSharedValue(0); // 0 = clear, 1 = frozen const aura = useSharedValue(0); // the cold creeping onto the background const time = useSharedValue(0); // elapsed seconds, drives the sparkle const freeze = () => { progress.value = withSpring(1, { damping: 22, stiffness: 16, mass: 1 }); aura.value = withTiming(1, CREEP); time.value = withRepeat(withTiming(1e5, CLOCK), -1, false); }; return ( ); } ``` ## Customization `FreezeCard` in Freeze Card from Motionary takes four props: - `width: number`: the card's width in dp. Height is derived as `width / CARD_RATIO`, and every measurement on the face is a fraction of the width, so the card holds together at any size. - `progress: SharedValue`: 0 is clear, 1 is fully frozen. Drives the frost front, the refraction amount, the snowflake and the tint. - `aura: SharedValue`: 0 is no chill around the card, 1 is fully crept out onto the background. Deliberately slower than `progress`. - `time: SharedValue`: elapsed seconds, drives the sparkle twinkle. Only needs to tick while there is ice on screen. Constants exported or declared at the top of `src/card/FreezeCard.tsx`: - `CARD_RATIO` (1.62, exported): the card's width to height ratio. - `CARD_RADIUS` (22, exported): the corner radius, also passed to the aura shader so the background lattice hugs the same shape. - `AURA_SPREAD` (92): how far the cold reaches past the card edge, in dp. - `FLAKE_SCALE` (0.3): the snowflake's size as a fraction of card width. Constants in `src/wallet/WalletScreen.tsx` tune the choreography: `FREEZE_SPRING` (`{ damping: 22, stiffness: 16, mass: 1 }`), `THAW_SPRING` (`{ damping: 18, stiffness: 42, mass: 1 }`), `AURA_MS` (5600), `AURA_RETRACT_MS` (460), `FOCUS_CENTER` (0.5, where the picked-up card lands) and `CLOCK_SECONDS` (1e5). The look is edited in two more places: `AURORA_SEED` (3.7) in `src/card/cardFace.ts` reshapes the procedural artwork, any other value gives a different aurora, and `src/theme.ts` holds the whole palette including `colors.freeze` (`#9fd8ff`), `colors.thaw` (`#ffd479`) and `SCREEN_PADDING` (20). ## When to use it - A banking or fintech app's card screen that needs a real freeze or card-lock toggle rather than a greyed-out card image. - A virtual card management screen where locking, unlocking and deleting a card live in a focus bar under the card. - A crypto or neobank wallet where tapping a card should lift it out of the list onto a scrim before showing destructive actions. - A security or account-suspended state that needs to feel physical and irreversible enough that the user notices it happened. - A seasonal or promotional freeze effect over any card-shaped surface, since the frost shader samples whatever face you rasterise. - A reference implementation for sampling a rasterised Skia picture as a child shader in React Native, which is the pattern behind any refraction, glass or heat-haze effect over real UI. ## How to get it - Buy Freeze Card on its own at https://motionary.dev/animations/freeze-card for $9 USD, instant download, secure Stripe checkout, no subscription and no account renewal. - 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 a card freeze animation in React Native?** Freeze Card from Motionary does it with an SkSL runtime shader in `@shopify/react-native-skia`: the card face is rasterised once into a Skia picture, fed back into the frost effect as an `` child, and the ice mask is a smoothstep over an fbm-warped distance field to the card's four corners, so the artwork and the print refract instead of being covered by a white overlay. A single `react-native-reanimated` shared value spring drives the whole thing through `useDerivedValue` uniforms. **Does Freeze Card work with Expo Go?** Yes. Freeze Card from Motionary runs in Expo Go on Expo SDK 56: `@shopify/react-native-skia`, the module most people assume blocks it, is bundled in Expo Go as of SDK 56, and the rest of the drop is standard Expo SDK 56, Reanimated 4, Gesture Handler and `expo-haptics`, all of which Expo Go carries too. You would still use a development build (`npx expo run:ios` or `npx expo run:android`) 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 that changes the native project; Freeze Card adds no custom native code of its own. One Expo Go caveat: the `CADisableMinimumFrameDurationOnPhone` key in `app.json` only takes effect in a build, so ProMotion iPhones run the freeze at 60 Hz in Expo Go. **How do I add a card lock toggle to a banking app UI in React Native?** Freeze Card from Motionary ships the whole interaction, not just the effect: tap the card to lift it out of the wallet list onto a dimmed scrim, then hit Freeze in the focus bar, which cross-fades to Unfreeze off the same shared value. Wire your own lock API call next to the `toggleFreeze` worklet in `src/wallet/WalletScreen.tsx`. **Can I use my own card artwork instead of the procedural aurora?** Yes. `drawCardFace` in `src/card/cardFace.ts` draws the artwork, brand mark, wordmark and digits onto a plain Skia canvas, and Freeze Card rasterises whatever that function produces. Swap the aurora shader for your own image or paint and the frost will refract it, because the frost effect samples the finished face as a child shader. **Is the freeze effect fast enough for a production React Native app?** Freeze Card holds zero React state in the screen: taps, labels, scroll locking and hit testing all resolve on the UI thread from Reanimated shared values, the card face is rasterised once rather than per frame, the frost shader early-returns when `progress` is near zero, and the sparkle clock is cancelled whenever the card is clear so the Skia canvas stops repainting entirely. **Does Freeze Card run on Android as well as iOS?** Yes. Freeze Card from Motionary is Expo SDK 56 with `react-native` 0.85.3 and `@shopify/react-native-skia` 2.6.2, runs on both iOS and Android with no custom native code, and its `app.json` sets `CADisableMinimumFrameDurationOnPhone` so the ice animates at the full ProMotion refresh rate on iPhone. **How much does Freeze Card cost and what do I get?** Freeze Card is $9 USD on Motionary at https://motionary.dev/animations/freeze-card (price as of 2026-09-01), or it is included in the $79 USD Motionary lifetime pass. You get the full editable TypeScript source: `FreezeCard.tsx`, the three SkSL shaders, the snowflake path builder and the complete wallet demo screen, as an instant download. ## Related drops on Motionary - Holographic Card ($9): https://motionary.dev/animations/holographic-card the other card-surface effect, a foil sheen and 3D tilt instead of ice. - Glass Magnifier ($10): https://motionary.dev/animations/glass-magnifier the closest sibling technically, an SkSL shader refracting the real UI underneath it. - Gyro Parallax Card ($7): https://motionary.dev/animations/gyro-parallax-card another card that reacts physically, driven by the gyroscope. - Scrubbable Chart ($6): https://motionary.dev/animations/scrubbable-chart the fintech screen that goes next to a frozen card, a Skia bar chart you scrub. - Copy Card Field ($5): https://motionary.dev/animations/copy-card-field credit-card details with a reveal and copy interaction, for the screen behind the card. ## 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/freeze-card/llms.txt Describes: https://motionary.dev/animations/freeze-card Format: llms.txt (https://llmstxt.org) Last updated: 2026-09-01 ```