WebAR y PWA: Crea una App de AR Rápida y Sin Fricción

La Realidad Aumentada (AR) y más específicamente la WebAR (AR a través del navegador web) brilla por su accesibilidad: no requiere descargas, no hay fricción con tiendas de aplicaciones y es universalmente compatible.
Sin embargo, la WebAR a menudo se siente efímera; una experiencia de una sola vez.
- ¿Cómo podemos darle la persistencia, el rendimiento y la sensación de una aplicación nativa? La respuesta es convirtiéndola en una Progressive Web App (PWA).
Una PWA toma tu aplicación web y la «progresa» para que se comporte como una app nativa, permitiendo su instalación, uso offline y acceso a APIs avanzadas.
Veamos cómo enfocar tu proyecto de WebAR para que sea una PWA de primer nivel.
🔑 Elementos Esenciales de una PWA para AR
Estos tres elementos son la base para que cualquier navegador moderno reconozca tu aplicación de MindAR, AR.js y cualquier librería de RA como una PWA:
1 – Manifiesto de Aplicación Web (manifest.json)
Este archivo JSON proporciona al navegador la información necesaria para instalar la aplicación en la pantalla de inicio del usuario (como un icono de aplicación nativa).
Ejemplo de manifest.json
{
"name": "WebAR Astronauta",
"short_name": "WebAR",
"start_url": ".",
"display": "fullscreen",
"background_color": "#3367D6",
"theme_color": "#3367D6",
"description": "Aplicación de Realidad Aumentada PWA",
"icons": [
{
"src": "icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}2 – Service Worker
Es un script de JavaScript que se ejecuta en segundo plano, independiente de la página web. Es el motor que permite las funcionalidades sin conexión y la optimización de activos.
3 – Conexión Segura (HTTPS) y APIs de PWA para Potenciar tu WebAR
Todas las PWAs deben servirse a través de HTTPS. Esto es un requisito estricto para que los Service Workers y la API de la cámara (necesaria para la experiencia de augmented reality) funcionen correctamente.
Estos son algunos ejemplos de API que puedes utilizar: WebXR Device API, Push API (Notificaciones Push), Geolocation API, Ambient Light Sensor API, Background Sync API, Screen Wake Lock API, Screen Orientation API, IndexedDB, App Shortcuts entre muchas otras.
¿Como hago para que los usuarios ingresen a mi web de realidad aumentada (WebAR)?
- Escaneando un código QR con la cámara de su dispositivo (móvil, tablet o portátil con navegador web).
- Ingresando la dirección web en su navegador preferido.
¿Como (instalar) una app PWA en mi dispositivo?
«Instalar» una PWA (Aplicación Web Progresiva) es un proceso sencillo que la añade a tu pantalla de inicio para que se comporte como una aplicación nativa. El método varía ligeramente entre Android y iPhone.
📱 En Android (usando Google Chrome)
En Android, el proceso es muy directo y el navegador (generalmente Chrome) suele promover la instalación.
- Abre Google Chrome y visita el sitio web de la PWA.
- Si el sitio está bien configurado, es posible que veas un aviso o un botón que dice «Instalar» o «Añadir [Nombre] a la pantalla de inicio». Si lo ves, simplemente púlsalo.
- Si no aparece ningún aviso, toca el menú de tres puntos (⋮) en la esquina superior derecha.
- Busca y selecciona la opción «Instalar aplicación» o «Añadir a pantalla de inicio».
- Confirma la instalación. El icono de la PWA aparecerá en tu pantalla de inicio junto con tus otras aplicaciones
🍏 En iPhone (usando Safari)
- En iOS, el proceso es un poco más manual y debes usar el navegador Safari.
- Abre Safari y navega hasta el sitio web de la PWA. (No funcionará en Chrome para iOS).
- Toca el icono de Compartir en la barra de navegación inferior (es el cuadrado con una flecha apuntando hacia arriba).
- En el menú que aparece, desliza hacia arriba para ver todas las opciones.
- Busca y selecciona la opción «Añadir a pantalla de inicio» (o «Add to Home Screen»).
- Podrás editar el nombre de la aplicación si lo deseas. Pulsa «Añadir» (o «Add») en la esquina superior derecha.
- El icono de la PWA aparecerá en tu pantalla de inicio, listo para usarse como una app.
Nota: En algunos dispositivos dependiendo del sistema operativo y del navegador y la gama del equipo (Alta, media o baja), las aplicaciones PWA pueden ser instaladas con un solo botón creado desde el HTML, CSS y Javascript. En este tutorial vamos a realizarlo de esta manera. Así tu aplicación se verá mucho mejor.
Hagamos juntos una aplicación de realidad aumentada Gratis y fácil de hacer en minutos, pero enfocándonos a PWA
Que hace y que nos permite hacer esta aplicación:
¿Qué nos permite hacer (como usuarios)?
- Ver a la astronauta en 3D: Apuntar nuestra cámara al marcador y ver el modelo 3D de la astronauta en nuestro entorno.
- Recibir respuesta táctil: El teléfono vibrará (script.js) en el momento exacto en que la cámara reconozca el marcador.
- Instalar la app: A través de un menú, la aplicación te da un botón para «Instalar App» en tu dispositivo.
- Ver información: El menú también tiene un botón «Acerca de».
¿Qué APIs y Tecnologías utiliza?
Para funcionar, esta aplicación combina varias tecnologías y APIs web modernas:
- MindAR (Framework): Es la biblioteca principal de Realidad Aumentada. Específicamente, usa la versión de Image Tracking (reconocimiento de imágenes) para detectar el marcador (targets.mind).
- A-Frame (Framework): Es un framework de WebXR (Realidad Virtual y Aumentada en la web) que permite crear y manejar la escena 3D y los objetos usando etiquetas HTML (como <a-scene>, <a-gltf-model>). MindAR se integra sobre A-Frame en este proyecto.
- WebXR Device API (Implícita): Esta es la API nativa del navegador que A-Frame y MindAR usan «por debajo» para obtener acceso a la cámara y a los sensores de movimiento del dispositivo.
APIs de PWA (Progressive Web App):
- Web App Manifest API: Es el archivo manifest.json. Le dice al navegador el nombre de la app («WebAR Astronauta»), los iconos que debe usar (icon-192.png, icon-512.png), y que debe abrirse en pantalla completa («display»: «fullscreen»).
- BeforeInstallPromptEvent API: Se usa en script.js para detectar cuándo el navegador permite instalar la PWA y mostrar el botón «Instalar App» de forma personalizada.
- Vibration API: Se usa explícitamente en script.js (con navigator.vibrate(100)) para hacer que el teléfono vibre cuando el marcador es encontrado.
- DOM (Document Object Model) API: Es la API estándar de JavaScript que se usa en script.js para controlar los botones del menú, mostrar y ocultar elementos, y lanzar alertas (document.getElementById, addEventListener, classList.toggle, etc.).
¡¡¡COMENCEMOS!!!
- El modelo 3D que vamos a utilizar para este tutorial paso a paso de realidad aumentada será este: (4) 3D models by Realidad Aumentada Empezando Desde Cero (@realidad-aumentada) – Sketchfab
- El marcador que vamos a utilizar para esta WebAR será:

El marcador RA lo realicé utilizando la aplicación para la creación de marcadores que hice para el blog, la puedes encontrar en el siguiente link: Compilador de Marcadores AR | Crea Realidad Aumentada Gratis
La estructura de tu proyecto será la siguiente:
/tu-proyecto/
├── index.html (El archivo principal)
├── manifest.json (Configuración de la PWA)
├── script.js (Lógica del botón de instalar y vibración)
├── style.css (Estilos para el botón)
├── Female-Astronauta.glb (Tu modelo 3D)
├── Targets.mind (Tu archivo de marcadores)
├── icon-192.png (Icono para la PWA)
├── icon-512.png (Icono para la PWA)
Empecemos con el codigo Html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>WebAR PWA con MindAR</title> <link rel="manifest" href="manifest.json"> <link rel="icon" type="image/png" href="./icon-192.png"> <script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/mind-ar@1.2.5/dist/mindar-image-aframe.prod.js"></script> <link rel="stylesheet" href="style.css"> <script src="script.js" defer></script> </head> <body> <button id="menuButton" class="menu-toggle-button"> ☰ </button> <div id="menuDropdown" class="menu-dropdown-content"> <button id="installButton" class="menu-item" style="display: none;">Instalar App</button> <button id="aboutButton" class="menu-item">Acerca de</button> </div> <a-scene mindar-image="imageTargetSrc: ./Targets.mind;" color-space="sRGB" renderer="colorManagement: true, physicallyCorrectLights, useLegacyLights: false" vr-mode-ui="enabled: false" device-orientation-permission-ui="enabled: false" > <a-assets> <a-asset-item id="astronautModel" src="./Female-Astronauta.glb"></a-asset-item> </a-assets> <a-camera position="0 0 0" look-controls="enabled: false"></a-camera> <a-entity mindar-image-target="targetIndex: 0" id="target"> <a-gltf-model rotation="0 -90 0" position="0 0 0" scale="3 3 3" src="#astronautModel" animation-mixer > </a-gltf-model> </a-entity> </a-scene> </body> </html>
Continuemos con el script.js
document.addEventListener('DOMContentLoaded', () => {
let deferredPrompt;
const installButton = document.getElementById('installButton');
const menuButton = document.getElementById('menuButton');
const menuDropdown = document.getElementById('menuDropdown');
const aboutButton = document.getElementById('aboutButton');
// --- 1. LÓGICA DEL MENÚ DESPLEGABLE ---
// Abrir/Cerrar el menú
menuButton.addEventListener('click', (e) => {
e.stopPropagation(); // Evita que el clic cierre el menú inmediatamente
menuDropdown.classList.toggle('show');
});
// Lógica del botón "Acerca de"
aboutButton.addEventListener('click', () => {
alert('PWA por Realidad Aumentada Empezando Desde Cero.');
menuDropdown.classList.remove('show'); // Ocultar menú
});
// Cerrar el menú si se hace clic fuera de él
window.addEventListener('click', (e) => {
if (!menuButton.contains(e.target) && !menuDropdown.contains(e.target)) {
if (menuDropdown.classList.contains('show')) {
menuDropdown.classList.remove('show');
}
}
});
// --- 2. LÓGICA DE INSTALACIÓN PWA ---
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
// Mostrar el botón de instalación DENTRO del menú
installButton.style.display = 'block';
});
installButton.addEventListener('click', () => {
// Ocultar el botón y el menú
installButton.style.display = 'none';
menuDropdown.classList.remove('show');
// Mostrar el prompt de instalación
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('Usuario aceptó la instalación');
} else {
console.log('Usuario rechazó la instalación');
}
deferredPrompt = null;
});
});
// --- 3. LÓGICA DE VIBRACIÓN CON MINDAR ---
const target = document.querySelector('#target');
target.addEventListener('targetFound', event => {
console.log("Marcador encontrado");
if ('vibrate' in navigator) {
navigator.vibrate(200);
}
});
target.addEventListener('targetLost', event => {
console.log("Marcador perdido");
});
});Este es tu archivo manifest.json.
{
"name": "WebAR Astronauta",
"short_name": "WebAR",
"start_url": ".",
"display": "fullscreen",
"background_color": "#3367D6",
"theme_color": "#3367D6",
"description": "Aplicación de Realidad Aumentada con MindAR",
"icons": [
{
"src": "icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}Y para terminar este seria tu archivo style.css
/* Asegurar que la escena ocupe todo */
body, html {
margin: 0;
padding: 0;
overflow: hidden;
}
/* Botón para abrir el menú (hamburguesa) */
.menu-toggle-button {
position: fixed;
top: 20px;
right: 20px;
z-index: 1001; /* Encima del contenido del menú */
padding: 10px 15px;
background-color: #3367D6; /* Color del tema */
color: white;
border: none;
border-radius: 8px;
font-size: 20px;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
/* Contenedor del menú desplegable */
.menu-dropdown-content {
display: none; /* Oculto por defecto */
position: fixed;
top: 70px; /* Debajo del botón de menú */
right: 20px;
background-color: white;
border-radius: 8px;
box-shadow: 0 8px 16px rgba(0,0,0,0.2);
z-index: 1000;
overflow: hidden;
}
/* Clase para mostrar el menú (se añade con JS) */
.menu-dropdown-content.show {
display: block;
}
/* Estilos de los botones dentro del menú */
.menu-item {
display: block;
width: 100%;
padding: 12px 20px;
background-color: white;
color: black;
border: none;
border-bottom: 1px solid #ddd;
text-align: left;
font-family: Arial, sans-serif;
font-size: 16px;
cursor: pointer;
}
.menu-item:last-child {
border-bottom: none;
}
.menu-item:hover {
background-color: #f1f1f1;
}
/* Estilo especial para el botón de instalar */
#installButton.menu-item {
background-color: #3367D6;
color: white;
font-weight: bold;
}
#installButton.menu-item:hover {
background-color: #2a56b0;
}Al finalizar este tutorial deberías tener algo como esto:
Que contienen los archivos de este tutorial en patreon (Contenido Adicional):
- Index.html – Version PWA y Version PWA botón de fotos para compartir redes sociales.
- script.js
- manifest.json
- style.css
- icon-192.png
- icon-512.png
- Marcador.webp
- Female-Astronauta.glb
- Targets.mind
- Código comentado linea por linea.
- Imagenes adicionales.