Preface ⚡
Join me in my Google Summer of Code 2023 ☀️ journey with TensorFlow as I showcase an Interactive Web Demo highlighting Touchless Interactions using the MediaPipe’s Machine Learning Library.
Presenting MediaPipe ATM Playground ✨
This project aims to test and demonstrate the capabilities of the new MediaPipe Hand Landmarker task from MediaPipe Solutions. The task provides precise and accurate hand landmark detection, generating 21 key points (i.e. hand landmarks) on the hand.

These landmarks are utilized in this interactive web app which enables users to perform contactless interactions with the interface using simple human gestures. Best experienced in well-lit environments. Ideal on larger screens.
💡For more information about the project, please visit here: Interactive Web Demos using the MediaPipe Machine Learning Library.
How the idea emerged 🤔
As technology hurtles forward, the aftermath of the COVID-19 pandemic has cast a new light on interaction. The awareness of touch-related risks is sharp, with 80% of people viewing public touchscreens as unhygienic 🦠
Touchless gesture-based systems hold the potential to reshape public spaces, workplaces, and industries. This technology’s seamless and convenient nature aligns with the post-pandemic landscape. Touchless interactions are poised to become commonplace in sectors spanning ATMs, airports, retail, healthcare, hospitality, and beyond.
So I decided to take the first step! That is how the idea for this project emerged: a response to the evolving expectations and demands of a world seeking safer, more intuitive, and advanced methods of interaction. By translating everyday hand gestures into a digital language, we can drive the wave of change toward touchless interactions.
This project is a symbol of my commitment to embracing the future, harnessing innovation, and crafting a more hygienic, efficient, and enchanting way to connect with technology! ✨
DISCLAIMER 📢
This blog aims to guide fellow developers in utilizing the MediaPipe library and implementing similar touchless interaction features in their projects.
ⓘ All data taken via input video feed is deleted after returning inference and is computed directly on the client side, making it GDPR compliant.
It’s a comprehensive read, so buckle up and enjoy the ride! 🚀
🏗️ TUTORIAL: The Interactive Web Demo

Before we start ✋
MediaPipe Solutions lets you apply machine-learning (ML) solutions to your apps. It provides a framework that lets you configure prebuilt processing pipelines that deliver immediate, engaging, and useful output to users.
📌NOTE: You can even customize these solutions with Model Maker to update the default models. I’ve covered how to use a Model Maker in another blog of the GSoC series, which can be explored 🔗here.
Hand landmarks detection is one of several ML vision tasks that MediaPipe Solutions offers. MediaPipe Tasks is available for Android, Python, and the Web. The MediaPipe Hand Landmarker task lets you detect the landmarks of the hands in an image. This Task localizes key points of the hands and render visual effects over the hands.

ⓘ If you want to delve deep into the specs of the model, feel free to explore the official docs, which can be found here. You can access the official model card for MediaPipe Hands (Lite/Full) here. It provides detailed information about the model.
You can also refer to the official research paper on the same, available 🔗here.
What you’ll learn 📝
- How to incorporate MediaPipe Hand Landmarker task in a web app.
- How to create a set of custom gestures for the Hand Landmarker task.
- How to optimize and precache the (same) web app for offline use.
What you’ll build 👨🔬
An interactive web app which enables users to perform contactless interactions with the interface using simple human gestures.
💎The ultimate product will be a web app that showcases a special ATM which showcases an augmented transaction panel, enabling users to interact accurately through intuitive gestures detected from an input video feed. Users can perform essential operations directly through the interactive floating panel (on screen) via custom simple-to-use gestures, allowing them to experience the checkout process without the need for physical touch.
What you’ll need 🛠️
- A local development environement with Node.js installed (else a CodeSandbox account also works fine)
- A device with a web browser & webcam
- Basic knowledge of React.js, JavaScript, CSS, and HTML
📢NOTE: To simply the process & to write less code, I’ve used Tailwind CSS & Redux in this project. If you’re not familiar with these, you can refer to the official docs, which can be found here & here. Most of the static assets have been handcrafted using Figma, & royalty free audio files (from Pixabay) have been used for the sound effects.
Installing Tailwind CSS with Create React App is pretty simple and straightforward. Head over to this to get started! 🤩
Get set up 🚀
To run the webapp code directly on browser, we can use CodeSandbox, a social development environment that lets you write & edit code, and can instantly reflect changes as you edit. To run it locally on your device (e.g. PC), you need to have Node.js installed.
⚠️Webcam is essential & required for hand detection and gesture recognition. Please ensure your device has a functioning webcam.
To access the code on CodeSandbox, navigate to this CodeSandbox Template. The webapp should instantly spin up in the preview panel.
🛑If your browser presents a dialog that asks you to grant access to the webcam, grant permission by clicking on “Allow”!

💡For the best experience it’s recommended to open the app in a new tab. You can do so by clicking it on this button ↓
📥You can also
forkit by clicking on Fork (as shown in the above image) or just by “Ctrl + S” (“Cmd + S” on Mac) to save a copy of the project in your CodeSandbox account. This will allow you to edit the code and save your changes.⚠️Don’t make any changes to the
.codesandboxcongifuration files. It may break the app.
Installation Process (local machine) 💻
To run the app on your local, open your terminal and follow these steps:
-
Clone the repository on your local machine:
git clone https://github.com/googlesamples/mediapipe.git -
Navigate into the project directory:
cd tutorials/atm_playground -
Install the necessary dependencies:
npm install -
Start the development server:
npm start -
Open the project in your browser at “
http://localhost:3000” to view the project.

🏷️The primary objective to use React is to have modularity. In the end, when a build is created, the application’s components, logic, and styles are bundled, minified, and optimized for production. This results in a highly efficient and performant web application that can be easily deployed to various platforms.
The use of React’s component-based architecture allows for the development of complex UIs by breaking them down into smaller, reusable components, enhancing code maintainability and reusability.
The app is quite extensive in structure, so I’ll be leading you through each file and folder, explaining the code as we go along. This approach ensures a comprehensive understanding of the application’s architecture, enabling effective collaboration and development.
🦄 View a live demo in your browser 🔗here.
Architecture Overview 🧱

UX Flow 🎨
1️⃣Once you open the app, you’ll be greeted with a landing page. The app will ask for permission to access your webcam. Click on Allow to grant permission.
2️⃣After enabling the webcam, necessary models load, and upon hand detection, a cursor appears on-screen. This cursor, controlled by hand gestures (for both hands), interacts with the interface, allowing operations through gesture-triggered interactions.
3️⃣You’ll be redirected to the login page where a walthrough is presented via app’s information modal which essentially displays that the user can perform the following operations via gestures:
- HOVER 🤚 : This is the base gesture. Use the cursor on the tip of your index finger to hover over the elements and perform specific operations.
- CLICK 👌 : This gesture is used to click on the elements you’re currently hovering over.
- UNDO ✋ : This gesture undoes the last action, handy for accidental clicks on the ATM PIN Entry Panel. Alternatively, the “Backspace” key on your keyboard achieves the same.
- GRAB ✊ : This gesture shows the app’s information modal, detailing available gesture actions and additional app details.
💡You can also use the “ESC” key to navigate back to previous screens, on certain pages.
4️⃣After logging in, you’ll see the ATM PIN Entry Panel. Use the cursor to select numbers for your PIN. On entering the correct PIN, you’ll access the main dashboard. Use the undo gesture to remove the last digit. Warnings may appear for empty/wrong PIN or trying to delete a non-existent digit.
5️⃣Now you can see your Account dashboard, where you have multiple options to choose from. You can either check your account balance, withdraw cash, or even check your mini statement. You can also logout from the dashboard by pressing “ESC” key, which will redirect you to the login page.
- Withdrawing cash is pretty simple. You can hover over the amount you want to withdraw and click on it. You’ll be presented with a confirmation tab, where you can click on “WITHDRAW” to confirm the transaction. You can also click on “CLEAR SELECTION” to reset the chosen amount. Once the transaction is confirmed, you’ll be presented with a success message. Click on “ESC” to return to the main dashboard.
Folder Structure 📁

ⓘ This has the default folder structure that comes with Create React App.
NOTE: An
.envfile has been created to setGENERATE_SOURCEMAPto False. Feel free to refer to this to know more. It’s completely optional, & is just there to remove minor dependency warnings.
Let’s start delving deep into the project! 👨💻
First, let’s take a look into the package.json file which is a configuration file for npm that defines the dependencies for the project. This is what it looks like 👇

🧙 NOTE: A package-lock.json file is a JSON file automatically generated by npm when packages are installed, and it locks the specific versions of dependencies to ensure consistent and reproducible installations across different environments, enhancing dependency management and project stability.
Let’s focus on some of the important dependencies:
| Dependency | Description |
|---|---|
| @mediapipe/tasks-vision | Provides vision tasks for MediaPipe solutions. |
| react | Library for building user interfaces. |
| react-dom | Methods for interacting with the DOM in React. |
| react-redux | React bindings for Redux state management. |
| react-scripts | Scripts and configurations for React app development. |
| react-toastify | Displays toast notifications in React apps. |
| react-confetti | Renders confetti animations for celebrations. |
| redux | State management library for applications. |
| @reduxjs/toolkit | Toolkit for efficient Redux development. |
| web-vitals | Measures user-centric web performance metrics. |
| css-loader | Resolves and loads CSS files in webpack. |
| postcss | CSS post-processor for transforming styles. |
| postcss-flexbugs-fixes | Fixes flexbox bugs in PostCSS. |
| postcss-loader | Loads and processes CSS files with PostCSS in webpack. |
| tailwindcss | Utility-first CSS framework for rapid UI development. |
🔮To implement Offline Caching, I’ve used the Workbox library. Caching assets with a service worker can speed up repeat visits and provide offline support. Workbox makes this easy and is included in React App by default. Feel free to explore this guide to know more!
| Dependency | Description |
|---|---|
| workbox-background-sync | Enables background synchronization. |
| workbox-broadcast-update | Broadcasts updates to service workers. |
| workbox-cacheable-response | Caches responses with strategies. |
| workbox-core | Core library for Workbox service workers. |
| workbox-expiration | Manages expiration policies for cached resources. |
| workbox-navigation-preload | Enables navigation preload with Workbox. |
| workbox-precaching | Precaches resources during service worker installation. |
| workbox-range-requests | Supports ranged requests in caching strategies. |
| workbox-routing | Implements routing strategies for service workers. |
| workbox-strategies | Offers caching strategies for Workbox service workers. |
| workbox-streams | Handles streams for caching with Workbox. |
Not to mention, this particular topic shall be discussed in detail later on. Let’s move on to the next.
Beside the root HTML file, the public directory contains static assets like images, favicon, and audio files. It also contains the MediaPipe HandLandmarker TASK file which is used during precaching for offline use. We’ll cover this in detail later on.

ⓘ The
publicdirectory additionally houses the manifest and robots files, which are used to provide metadata for the web app and to exclude certain files from being crawled by search engines, respectively.
Let’s navigate back to the top level:
-
The tailwind.config.js file is used to configure Tailwind CSS. It’s a configuration file that allows to customize the default settings of Tailwind CSS. It’s also used to add third-party plugins to Tailwind CSS. Feel free to explore this guide to know more!
-
The postcss.config.js file is used to configure PostCSS. It’s a configuration file that allows to customize the default settings of PostCSS. Feel free to surf this to know more!
-
The “
src” aka “Source” folder of the React app is the main source code directory containing React components, Redux logic, and utility files. Let’s preview the structure once again:
1📁./src ♦♦ 𝐌𝐞𝐚𝐧𝐢𝐧𝐠2│ |3├── App.jsx | → React Component Heirarchy4├── index.css | → CSS File (Fueled by Tailwind)5├── index.jsx | → Heart of React App6│ |7│ |8├── components | → Components Directory9│ │ |10│ ├── CustComponents | → Custom Components Directory11│ │ │ |12│ │ ├── CombinedCard.jsx | → Card Component13│ │ ├── CursorTip.jsx | → Cursor Component14│ │ ├── ModalC1.jsx | → Modal Component15│ │ ├── TimeComponent.jsx | → Time & Date Component16│ │ └── UIalert.jsx | → Notification Component17│ │ |18│ ├── Landing.jsx | → Landing Preview of App19│ ├── Kernel.jsx | → Brain of App20│ └── DashboardUI.jsx | → Main Dashboard of App21│ |22│ |23├── redux | → Redux Directory24│ │ |25│ ├── gesture |26│ │ ├── gesture.forms.js | → Gesture Types27│ │ ├── gesture.handler.js | → Gesture Reducer28│ │ └── gesture.ops.js | → Gesture Actions29│ │ |30│ ├── root.handler.js | → Root Reducer31│ └── store.js | → Redux Store32│ |33│ |34├── reportWebVitals.js | → Performance Tracking File35



