# Receipt Printer: React Native Dynamic Island receipt printer animation > Receipt Printer is a React Native and Expo component in which the iPhone > Dynamic Island morphs into a thermal printer and feeds a paper receipt out of > its mouth in seven stepped line-blocks, then tears the finished sheet away. > It is built on react-native-reanimated v4 shared values that run entirely on > the UI thread, and Motionary sells it as editable TypeScript source. Product page: https://motionary.dev/animations/receipt-printer Price: $7 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: react native, expo, reanimated Rarity: rare Sold by: Motionary (https://motionary.dev) ## What it is Receipt Printer is a React Native and Expo drop from Motionary that turns the iPhone Dynamic Island into a working thermal printer. At rest it is a black pill drawn at the exact hardware cutout metrics, so it disappears into the real Dynamic Island; press the PRINT RECEIPT button and the pill springs open into a full width printer bar with a dark gray mouth lip at its base. A paper receipt then feeds down out of that mouth in discrete stutters, one line-block at a time, the way a real thermal head advances the roll, with a soft gradient shadow falling from the lip onto the paper. When the sheet is finished a CLAIM PASS button appears, and pressing it drops the receipt off the roll with a slight rotation while the island snaps shut behind it. ## What it does - Runs a four stage machine, `idle` to `printing` to `done` to `tearing`, typed as `Stage` in `components/Container.tsx`. - Draws the collapsed pill at the real iPhone Dynamic Island cutout metrics (top 14, width 126, height 37) so it blends into the hardware island. - Expands that pill into a printer bar (height 84, corner radius 36, 20 point side margins) from a single `island` shared value. - Fades in the printer mouth only past `island > 0.75`: a dark gray `#2C2C2E` rounded lip with a black capsule hole inside it, so the body reads as solid before the slot appears. - Feeds the paper in 7 discrete steps (`PRINT_STEPS`), each a 250 ms `withTiming` ramp on `Easing.inOut(Easing.quad)`, separated by 90 ms pauses, after an opening 560 ms delay while the island is still springing open. - Offsets the receipt content by `paperH - receiptHeight` so the bottom of the sheet leads out of the slot and the header is the last thing to appear. - Tears the sheet off by running `paperY` to `height * 1.05` over 520 ms on `Easing.in(Easing.cubic)`, with up to 4 degrees of interpolated rotation and a fade that starts at 75 percent of the screen height. - Casts a mouth shadow onto the paper with an SVG linear gradient `Rect` whose opacity is the product of two interpolations, so it exists only while paper actually fills the slot and vanishes the instant the sheet is torn. - Ramps the paper drop shadow in over the first 10 points of feed. - Hides the status bar while a print is in flight (`hidden={stage !== 'idle'} animated`) and shows it again at idle. - Mounts the paper and shadow layers only while `stage !== 'idle'`, so no stray shadows sit under the collapsed island. - Fades the PRINT RECEIPT button out and scales it to 0.85 as the island opens, then brings the CLAIM PASS button in with `FadeInDown.delay(150).springify()` and out with `FadeOut.duration(150)`. - Renders the sheet itself in `components/Receipt.tsx`: monospace type (Menlo on iOS, `monospace` elsewhere), dashed dividers, five included line items, a subtotal / discount / total / savings block, and a 30 bar barcode drawn as SVG `Rect`s from a fixed unit-width sequence. - Sizes the sheet to the device with `Math.min(height - PAPER_TOP - 120, 640)` so it never runs off screen. - Ships with no native code, so Receipt Printer runs in Expo Go on iOS and Android; the island-blend illusion is designed for notch and Dynamic Island iPhones. ## How it works The whole Receipt Printer interaction in Motionary's drop is driven by three react-native-reanimated shared values declared in `components/Container.tsx`: `island`, `paperH` and `paperY`, all of which are read inside `useAnimatedStyle` so every frame is computed on the UI thread and never touches the JavaScript thread. The morph is one value doing four jobs at once: `island` goes 0 to 1 under `withSpring(1, { damping: 17, stiffness: 170, mass: 0.9 })` and is passed through four `interpolate` calls that animate `top`, `width`, `height` and `borderRadius` together, which is what makes a 126 by 37 pill read as growing into an 84 point tall printer bar instead of cross-fading into one. The printer mouth is a second `useAnimatedStyle` on the lip whose opacity is `interpolate(island.value, [0.75, 1], [0, 1], Extrapolation.CLAMP)`, a deliberate late reveal so the slot cannot be seen through a half formed body. The paper feed is the part worth stealing: `print()` builds an array of `withTiming` ramps in a plain `for` loop, wraps every one after the first in `withDelay(STEP_PAUSE, step)`, and hands the whole array to `withSequence(...steps)` inside `withDelay(560, ...)`, which produces the stop-start cadence of a thermal head far more convincingly than a single long easing curve. Because `paperH` is animating the container's `height` while an inner `Animated.View` is translated by `paperH - receiptHeight`, the sheet appears to be pushed out of the slot bottom edge first, with the header exiting last, rather than simply being unmasked in place. Stage transitions are handed back to React from inside the animation: the last `withTiming` in the sequence takes a `'worklet'` callback that calls `scheduleOnRN(markDone)` from react-native-worklets, which is the react-native-reanimated v4 replacement for the old `runOnJS`, and `tear()` does the same with `scheduleOnRN(markIdle)` after resetting `paperH` and `paperY` to 0 in the same worklet. The mouth shadow multiplies two clamped interpolations, `interpolate(paperH.value, [0, 10], [0, 1])` times `interpolate(paperY.value, [0, 80], [1, 0])`, so a single opacity expresses two independent conditions (paper is present, sheet has not been torn) without any conditional rendering. Everything visual is plain React Native views plus react-native-svg for the mouth gradient and the barcode `Rect`s, and `pressto` supplies the `PressableScale` press feedback on both buttons, so there is no Skia dependency and no native module in Receipt Printer. ## What you get ``` components/ Container.tsx Receipt.tsx App.tsx index.ts app.json package.json tsconfig.json README.md assets/ ``` - `Container.tsx`: the island morph plus the print and tear orchestration. - `Receipt.tsx`: the styled thermal receipt with its SVG barcode. - `App.tsx` entry, wrapped in `GestureHandlerRootView`. - README with install and usage. - MP4 preview. ## Requirements Receipt Printer is pinned in the archive's `package.json` to: - `expo` ^56.0.8 (Expo SDK 56) - `react-native` 0.85.3 - `react` 19.2.3 - `react-native-reanimated` 4.3.1 - `react-native-worklets` 0.8.3 - `react-native-gesture-handler` ~2.31.1 - `react-native-svg` ^15.15.5 - `pressto` ^0.7.0 - `@expo/vector-icons` ^15.1.1 - `expo-status-bar` ~56.0.4 - TypeScript ~6.0.3 (dev dependency) Expo Go or development build: Receipt Printer runs in **Expo Go** on Expo SDK 56. It contains no native code of its own and pulls in no native-only module (there is no `@shopify/react-native-skia`, no `expo-glass-effect`, no `react-native-vision-camera`); react-native-reanimated, react-native-worklets, react-native-gesture-handler and react-native-svg are all bundled into Expo Go. Note that react-native-reanimated 4 requires the New Architecture, which is the default on Expo SDK 56. ## Install ```bash npx expo install react-native-reanimated react-native-worklets \ react-native-gesture-handler react-native-svg expo-status-bar \ @expo/vector-icons pressto ``` ## Usage ```tsx import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { StyleSheet } from 'react-native'; import { Container } from './components/Container'; export default function App() { return ( ); } const styles = StyleSheet.create({ root: { flex: 1, }, }); ``` `Container` takes no props: it owns the whole print and tear sequence, mounts its own PRINT RECEIPT and CLAIM PASS buttons, and renders `Receipt` inside the paper. `GestureHandlerRootView` must wrap it, because the buttons are `pressto` `PressableScale` components. ## Customization Receipt Printer is tuned through named module-level constants at the top of `components/Container.tsx` rather than through props, so every number is one edit away: - `ISLAND_TOP` (14), `ISLAND_WIDTH` (126), `ISLAND_HEIGHT` (37): the collapsed pill, set to the iPhone Dynamic Island cutout metrics. - `BAR_TOP` (14), `BAR_HEIGHT` (84), `BAR_MARGIN` (20), `BAR_RADIUS` (36): the expanded printer bar. - `LIP_SIDE_INSET` (18), `LIP_BOTTOM_INSET` (20), `LIP_HEIGHT` (14), `LIP_RING` (5): the printer mouth lip and the size of its black hole. - `PRINT_STEPS` (7), `STEP_DURATION` (250), `STEP_PAUSE` (90): how many line-blocks the paper feeds in, how long each ramp lasts in milliseconds, and the pause between them. Raise `PRINT_STEPS` for a chattier printer. - `MOUTH_SHADOW_HEIGHT` (12): the height in points of the SVG gradient shadow the lip casts onto the paper. - `receiptHeight`: `Math.min(height - PAPER_TOP - 120, 640)`, the printed sheet length, capped at 640 points. - In `components/Receipt.tsx`: `ITEMS` (the five printed line items), `ACCENT` (`#FEEB00`, the dot beside a highlighted row), `BAR_SEQ` (the 30 unit widths the barcode is drawn from), and `MONO` (`Platform.select({ ios: 'Menlo', default: 'monospace' })`). ## When to use it - A checkout or order confirmation screen, where the receipt is the payload. - A paywall or pricing screen that prints the plan's line items and total, which is exactly what the shipped `Receipt.tsx` demo does. - An order-success or payment-success moment worth celebrating instead of a static checkmark. - A ticket, boarding pass, coupon or promo-code reveal that the user then tears off and claims. - The last step of an onboarding flow, printing back a summary of the choices the user just made. - Any Dynamic Island stunt in a marketing or launch app where the hardware cutout itself should do something. ## How to get it - Buy Receipt Printer on its own at https://motionary.dev/animations/receipt-printer, $7 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 animate the Dynamic Island in React Native?** You cannot animate the real hardware cutout from React Native, so Receipt Printer does what Motionary's other Dynamic Island drops do: it draws an absolutely positioned black view at the exact cutout metrics (top 14, width 126, height 37) and animates that view's `top`, `width`, `height` and `borderRadius` with react-native-reanimated, so the on-screen pill and the physical island read as one object. A true Live Activity in the system island needs a native iOS widget extension instead. **Does Receipt Printer work with Expo Go?** Yes. Receipt Printer from Motionary is pinned to Expo SDK 56 and uses only react-native-reanimated, react-native-worklets, react-native-gesture-handler, react-native-svg, expo-status-bar, `@expo/vector-icons` and `pressto`, none of which require a custom native build, so it runs in Expo Go on both iOS and Android. **How do I make an animation stutter like a thermal printer?** Receipt Printer builds an array of short `withTiming` ramps, each on `Easing.inOut(Easing.quad)`, wraps all but the first in `withDelay(STEP_PAUSE, step)` and plays them through `withSequence(...steps)`. Seven 250 ms ramps with 90 ms gaps sell a paper feed far better than one long curve, and in Motionary's Receipt Printer the step count is a single constant you can change. **Does the Receipt Printer animation work on Android?** It runs on Android, since Receipt Printer uses no iOS-only APIs, but the illusion is built for phones with a notch or Dynamic Island: on other hardware the collapsed pill reads as a floating black capsule near the top of the screen rather than as the device cutout itself. **Can I put my own receipt content in it?** Yes. `components/Receipt.tsx` is plain React Native layout, so you edit the `ITEMS` array, the totals block and the footer text directly; the barcode is generated from the `BAR_SEQ` unit-width array as SVG `Rect`s, and the whole sheet is sized by `receiptHeight` in `components/Container.tsx`. **Can I use Receipt Printer in a commercial app?** Yes. Motionary's license covers a single developer building unlimited personal and commercial apps; you may not resell or redistribute the source itself. Full terms are at https://motionary.dev/license. **How much does Receipt Printer cost?** Receipt Printer is $7 USD as of 2026-09-01 at https://motionary.dev/animations/receipt-printer, or it is included in the Motionary lifetime pass ($79 USD) which covers every drop and every build, current and future. Checkout is Stripe and delivery is an instant download of the TypeScript source. ## Related drops on Motionary - Dynamic Island Boarding Pass ($6): https://motionary.dev/animations/dynamic-island-boarding-pass The same island-as-dispenser idea, but the pass is peeled and torn off with a pan gesture instead of printed in steps. - Dynamic Island Member Card ($6): https://motionary.dev/animations/dynamic-island-member-card Another Dynamic Island dispenser: the island expands and drops a wallet card out of its mouth. - Island Genie ($11): https://motionary.dev/animations/island-genie A Skia-based genie morph from the notch into a bottom sheet, for when the island should stretch rather than print. - Animated Live Activity ($10): https://motionary.dev/animations/animated-live-activity The Dynamic Island and lock screen widget side of the same surface. - Scratch to Reveal ($7): https://motionary.dev/animations/scratch-to-reveal The other "claim your reward" moment, a scratch card with confetti, useful alongside a printed coupon or promo receipt. ## 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/receipt-printer/llms.txt Describes: https://motionary.dev/animations/receipt-printer Format: llms.txt (https://llmstxt.org) Last updated: 2026-09-01 ```