--- type: Resumen title: "Estudio de MindAR — Casos de Estudio (Image, Face, React, Despliegue)" description: "Estudio de mindar publicado como sitio: scripts minimalistas para implementarlo y cómo se conecta con el OKF." resource: "https://gerardoesquivia.com/mindar/" status: publicado tags: [estudio, mindar, scripts-minimalistas, documentacion, okf] timestamp: 2026-10-04 creator: "Gerardo Esquivia Zapata" grafo: datos --- # Estudio de MindAR — Casos de Estudio (Image, Face, React, Despliegue) > **Sitio publicado:** https://gerardoesquivia.com/mindar/ > **Nota generada del sitio** para que el estudio regrese al OKF (REGLA del ciclo: > la documentación no está completa hasta estar publicada **Y** registrada). ## Cómo usarla Los **scripts minimalistas** de abajo se copian y funcionan. Esa es la parte que vale: la prosa se lee y se olvida; un script se pega y arranca. --- ## 1 · Image Tracking (A-Frame y Three.js) Anclar contenido 3D/video a imágenes físicas. CDN: mindar-image.prod.js + mindar-image-aframe.prod.js. ### 1.1 · Básico: marcador → modelo 3D (GLTF) + video A-Frame ``` — 3 scripts: SDK image + A-Frame + extensión image-aframe ``` 🔁 Cómo funciona: mindar-image-target se ancla al marcador detectado; los hijos (a-plane, a-gltf-model, a-video) se posicionan sobre él en coordenadas relativas. ### 1.2 · Multi-targets (varios marcadores independientes) A-Frame ``` ``` 🔁 Cómo funciona: un solo .mind puede contener varias imágenes; cada targetIndex enlaza el contenido a un marcador distinto (tarjetas, posters, museos). ### 1.3 · Three.js puro (MindARThree, sin A-Frame) Three.js ``` ``` 🔁 Cómo funciona: MindARThree expone renderer/scene/camera; añades mallas con Three.js puro (geometría procedural, animaciones, luces) y setAnimationLoop renderiza. Base de casos tipo preplanter-ar (planta procedural). ### 1.4 · Video anclado al marcador (overlay de póster) Video ``` ``` ``` const ok = video.canPlayType('video/webm; codecs="vp9"') !== ''; video.src = ok ? 'v.webm' : 'v.mp4'; ``` 💡 Nota OKF (AR Membrillal): para videos transparentes, verificar si el navegador soporta WebM con canal alfa; si no (Safari iOS), alternar a MP4: ## 2 · Face Tracking y React Superponer contenido sobre el rostro (mediapipe face mesh, 468 puntos) y embeker MindAR en React con ciclo de vida correcto. ### 2.1 · Probador de gafas (face target + ancla) A-Frame ``` ``` 🔁 Cómo funciona: mindar-face detecta la cara y mindar-face-target expone anclas (anchorIndex) por zona facial (10 = nariz, 4 = ojo…). El contenido se posiciona relativo a la ancla. ### 2.2 · Face mesh con Three.js puro Three.js ``` // mindar-face-three.prod.js (import map con "three") const mindarThree = new MindARThree({ container: document.body, filterMinCF: 0.002, filterBeta: 0.1, // estabilización (reduce jitter) }); const {renderer, scene, camera} = mindarThree; // malla del face mesh (468 puntos) y superponer accesorios… await mindarThree.start(); renderer.setAnimationLoop(() => renderer.render(scene, camera)); ``` 🔁 Cómo funciona: expone los 468 puntos 3D del face mesh (mediapipe) para anclar mallas, sombreros o efectos 2D sobre la cara. ### 2.3 · React + A-Frame (mindar-viewer) React ``` import {useEffect, useRef} from 'react'; function Viewer() { const ref = useRef(null); useEffect(() => { const el = ref.current; el.setAttribute('mindar-image', 'imageTargetSrc: /targets/card.mind'); return () => { // cleanup: detener cámara + liberar WebGL (SPA) const c = el.components['mindar-image'].controller; c.stop(); renderer.dispose?.(); }; }, []); return ; } ``` 🔁 Cómo funciona: se envuelve la inicialización imperativa en hooks. El cleanup (controller.stop() + renderer.dispose()) es crítico al navegar fuera de la pestaña AR en una SPA. ### 2.4 · React + Three.js (mindar-three-viewer) React ``` useEffect(() => { const mindarThree = new MindARThree({container: el, imageTargetSrc: '/targets/card.mind'}); mindarThree.start(); el.appendChild(mindarThree.renderer.domElement); return () => { mindarThree.stop(); }; // libera cámara y WebGL }, []); ``` 🔁 Cómo funciona: versión Three.js pura (sin A-Frame) con control granular de animaciones y luces; el cleanup evita que la cámara siga activa al desmontar. ## 3 · Casos Avanzados (UI, audio, dual, sin código) Pulir la experiencia AR y producir targets sin escribir código. ### 3.1 · UI de escaneo personalizada (overlay premium) UI ``` /* CSS: oculta el overlay nativo de MindAR */ .mindar-ui-overlay { display: none !important; }

Apunta la cámara al marcador

``` 🔁 Cómo funciona: uiScanning apunta a un elemento propio; con !important se oculta el overlay nativo. Base del custom-ui.html de la doc oficial (usado en AR Membrillal). ### 3.2 · Audio y estado interactivo (targetFound / targetLost) Audio ``` const target = document.querySelector('[mindar-image-target]'); const audio = document.querySelector('#narracion'); target.addEventListener('targetFound', () => { audio.play(); status.textContent = '🎯 ¡Contenido encontrado!'; }); target.addEventListener('targetLost', () => { audio.pause(); status.textContent = '🔍 Buscando el marcador…'; }); ``` 🔁 Cómo funciona: los eventos targetFound/targetLost permiten disparar audio, animaciones o UI cuando el marcador aparece/desaparece (patrón del browser-ar-runtime). ### 3.3 · Arquitectura dual Image + Face (modos conmutable) Dual ``` function cambiarModo(modo) { if (modo === 'image') { escenaImagen.style.display = 'block'; escenaRostro.style.display = 'none'; } else { escenaImagen.style.display = 'none'; escenaRostro.style.display = 'block'; } } ``` 🔁 Cómo funciona: cargar ambos SDK (image + face) y conmutar visibilidad entre escenas. Patrón del browser-ar-runtime (7 targets + face filters, usado en 30+ instituciones culturales). ### 3.4 · Producción de targets sin código Tools ``` 1. Compilador en el navegador → https://hiukim.github.io/mind-ar-js-doc/tools/compile (subes una imagen → obtienes el .mind + el marcador imprimible) 2. MindAR Studio → https://studio.mindar.org (face tracking sin código, export estático) 3. Pictarize → https://pictarize.com (image tracking sin código, hosting) 4. Por CLI: npm install mind-ar-js y usar el compilador de la doc ``` 🔁 Cómo funciona: el .mind es un descriptor de features de la imagen; se genera con el compilador (web o CLI) y se referencia en imageTargetSrc. ## 4 · Despliegue — 4 Arquitecturas Cómo publicar una experiencia MindAR según el contexto (skills OKF despliegue-ar-*). ### 4.1 · Arq 1 — 100% local (sin internet) Offline ``` # Paquete standalone: HTML + SDK + .mind + assets todo embebido cd experiencia python -m http.server 8080 # abre http://localhost:8080 (necesita webcam) ``` Cuándo: ferias sin conectividad, demo en un solo equipo, respaldo offline. Clave: SDK y assets locales (no CDN). ### 4.2 · Arq 2 — WiFi local (portátil = servidor) ⭐ educación Aula ``` # pip install flask — el portátil sirve y los celulares entran por IP local from flask import Flask, send_from_directory app = Flask(__name__, static_folder='experiencia') @app.route('/') def home(): return send_from_directory('experiencia', 'index.html') app.run(host='0.0.0.0', port=8282) # celular: http://:8282 ``` Cuándo: aula sin internet, taller con celulares. Clave: host='0.0.0.0' para acceso por IP local en el mismo WiFi. ### 4.3 · Arq 3 — Hosting (internet obligatorio) ⭐ distribución Producción ``` # Subir a gerardoesquivia.com (cPanel/FTPS), GitHub Pages u otro hosting. # El celular accede por URL pública desde cualquier lugar. # Ruta: /mindar/ → https://gerardoesquivia.com/mindar/ # Clave: CDN de MindAR o SDK local; rutas relativas para .mind + assets. ``` Cuándo: proyecto terminado, portafolio, distribución global. ### 4.4 · Arq 4 — Híbrida (local + CDN) Transición ``` # assets/videos locales + librerías del motor desde CDN (o viceversa). Requiere internet parcial. # CDN # local ``` Cuándo: transición, prototipos, cuando no se puede empaquetar todo. Clave: decidir qué va local (pesado/propietario) y qué va CDN (librerías). ## 5 · Grafo animado — del marcador a la publicación El token 🟠 recorre: compilar target → image → face → React → contenido → desplegar. Clic reinicia. Iniciando… ## 6 · Referencia y regla de librerías | Script / concepto | Qué hace | | --- | --- | | mindar-image.prod.js + -aframe | SDK image tracking + extensión A-Frame | | mindar-face.prod.js + -aframe | SDK face tracking (mediapipe face mesh) | | mindar-image-three.prod.js | Integración Three.js directa (import map) | | .mind + targetIndex | Target compilado + índice del marcador | | mindar-image-target / mindar-face-target | Entidad anclada al marcador / rostro | | anchorIndex | Zona facial de anclaje (10 = nariz) | | targetFound / targetLost | Eventos de detección (audio/UI) | | uiScanning / .mindar-ui-overlay | Overlay custom / nativo | | MindARThree · controller.stop() | Three.js puro · cleanup React | 📦 Regla de librerías (local primero): para Arq 1/2 usar el SDK descargado desde C:\Users\TUF\Documents\librerías\local\mind-ar-js\; para Arq 3/4 CDN. Docs: https://hiukim.github.io/mind-ar-js-doc/. Compilador: .../tools/compile. 📱 Escanéalo para abrir la documentación https://gerardoesquivia.com/mindar/ MindAR · Estudio en Casos de Uso · OKF de Gerardo Esquivia Zapata · 2026-08-30 --- type: Resumen title: "🕶️ MindAR — Estudio en Casos de Uso (Resumen minimalista)" description: "Resumen de MindAR (WebAR open source): image tracking (A-Frame/Three.js), face tracking, React, casos avanzados (UI, audio, dual) y las 4 arquitecturas de despliegue. Integra el conocimiento del OKF (repos, análisis de 15 repos, proyectos AR)." fuente: "https://github.com/hiukim/mind-ar-js · https://hiukim.github.io/mind-ar-js-doc/" sitio: "https://gerardoesquivia.com/mindar/" tags: [resumen, mindar, webar, image-tracking, face-tracking, react, threejs, despliegue, okf] timestamp: 2026-08-30 creator: "Gerardo Esquivia Zapata" --- # 🕶️ MindAR — Resumen (para OKF) > **Para qué:** Realidad Aumentada web (Image + Face tracking) en el navegador móvil, open source. > **Cómo:** SDK `mindar-image`/`mindar-face` + A-Frame (~10 líneas) o Three.js (`MindARThree`). Se ancla contenido a marcadores `.mind` o al rostro (468 puntos). > **Skill de implementación:** `mindar-minimal` (image/face con A-Frame/Three.js, React, video, UI custom y las 4 arquitecturas de despliegue). ## 1 · Image Tracking (A-Frame) ```html ``` Multi-targets: varios `` con un solo `.mind`. ## 2 · Three.js puro ```js import {MindARThree} from 'mind-ar'; const m = new MindARThree({container: document.body, imageTargetSrc: './targets/card.mind'}); const {renderer, scene, camera} = m; scene.add(new THREE.Mesh(new THREE.PlaneGeometry(1, .552), new THREE.MeshBasicMaterial({color:'#f6ad55'}))); await m.start(); renderer.setAnimationLoop(() => renderer.render(scene, camera)); ``` ## 3 · Face Tracking (probador) ```html ``` ## 4 · React (cleanup crítico) ```jsx useEffect(() => { const controller = new MindARThree({container: el, imageTargetSrc: '/targets/card.mind'}); controller.start(); return () => { controller.stop(); renderer.dispose(); }; // evita fugas de cámara/WebGL }, []); ``` ## 5 · Avanzado - UI custom: `uiScanning: #mi-overlay` + `.mindar-ui-overlay { display:none !important; }`. - Audio: `target.addEventListener('targetFound'/'targetLost', …)`. - Dual image+face: conmutar escenas. - Targets sin código: compilador web (…/tools/compile) · MindAR Studio (face) · Pictarize (image). ## 6 · Despliegue (4 arquitecturas) | Arq | Internet | Servidor | Uso | |---|---|---|---| | 1 Local | No | `python -m http.server` | Demo offline | | 2 WiFi local | No | Flask `0.0.0.0:8282` | Aula/taller | | 3 Hosting | Sí | cPanel/FTPS/GitHub Pages | Producción | | 4 Híbrida | Parcial | local + CDN | Transición | ## 🔑 Conceptos clave | Concepto | Qué es | |---|---| | `mindar-image/face.prod.js` | SDK core (TF.js webgl) | | `-aframe` / `-three` | Extensiones de render | | `.mind` + `targetIndex` | Target + marcador | | `anchorIndex` | Zona facial (10 = nariz) | | `targetFound/targetLost` | Eventos de detección | | `MindARThree` | Three.js puro (import map) | ## 🔗 Fuente https://github.com/hiukim/mind-ar-js · https://hiukim.github.io/mind-ar-js-doc/ · Sitio: https://gerardoesquivia.com/mindar/ · OKF: 🧠 Técnicas/📦 Repositorios (mind-ar-js·doc·react) · 📚 Referencias/📦 Librerías Mind AR — Análisis de 15 Repos · Proyectos AR · skills despliegue-ar-* ## 📥 Cómo agregar esto a tu OKF (para el agente) 1. Guarda este archivo en tu vault (ej. `📋 Proyectos/`). 2. El frontmatter ya es OKF: no modifiques `type` ni `creator`. 3. Implementa directo: copia los scripts y ajusta targets/assets. No necesitas investigar más. function descargarMD(){const md=document.getElementById('md-resumen').textContent.trim();const b=new Blob([md],{type:'text/markdown;charset=utf-8'});const u=URL.createObjectURL(b);const a=document.createElement('a');a.href=u;a.download='resumen-mindar.md';document.body.appendChild(a);a.click();a.remove();URL.revokeObjectURL(u);} (function(){const nodes=[{id:"c",label:"Compilar target",sub:".mind",x:90,y:140},{id:"i",label:"Image tracking",sub:"A-Frame / Three",x:270,y:140},{id:"f",label:"Face tracking",sub:"468 puntos",x:450,y:140},{id:"r",label:"React",sub:"cleanup",x:630,y:140},{id:"x",label:"Contenido",sub:"3D · video · audio",x:810,y:140},{id:"d",label:"Desplegar",sub:"Arq 1-4",x:810,y:330},{id:"u",label:"Usuarios",sub:"cámara + web",x:540,y:330}];const edges=[{from:"c",to:"i",label:"imagen"},{from:"c",to:"f",label:"rostro"},{from:"i",to:"r",label:"SPA"},{from:"f",to:"r",label:"SPA"},{from:"r",to:"x",label:"monta"},{from:"i",to:"x",label:"ancla"},{from:"x",to:"d",label:"publica"},{from:"d",to:"u",label:"sirve"},{from:"u",to:"x",label:"interactúa"}];const pos=Object.fromEntries(nodes.map(n=>[n.id,{x:n.x,y:n.y}]));const svg=document.getElementById("grafo-mindar");const NS="http://www.w3.org/2000/svg";function el(t,a){const e=document.createElementNS(NS,t);for(const k in a)e.setAttribute(k,a[k]);return e;}const edgePaths=[],edgeArrows=[]; edges.forEach((ed)=>{const a=pos[ed.from],b=pos[ed.to];let d,mid;if(a.y!==b.y&&Math.abs(a.x-b.x)>60){const cx=(a.x+b.x)/2;d=`M ${a.x} ${a.y} C ${cx} ${a.y}, ${cx} ${b.y}, ${b.x} ${b.y}`;mid={x:cx,y:(a.y+b.y)/2};}else if(ed.from==="u"){d=`M ${a.x} ${a.y} C ${(a.x+b.x)/2} 440, ${(a.x+b.x)/2} 440, ${b.x} ${b.y}`;mid={x:(a.x+b.x)/2,y:410};}else{const mx=(a.x+b.x)/2;d=`M ${a.x} ${a.y} C ${mx} ${a.y}, ${mx} ${b.y}, ${b.x} ${b.y}`;mid={x:mx,y:(a.y+b.y)/2};}const p=el("path",{class:"edge",d});svg.appendChild(p);edgePaths.push(p);const ang=Math.atan2(b.y-mid.y,b.x-mid.x);const tx=b.x-18*Math.cos(ang),ty=b.y-18*Math.sin(ang);const ar=el("path",{class:"arrow",d:`M ${tx} ${ty} l 8 -4 l -8 -4 z`,transform:`rotate(${ang*180/Math.PI} ${tx} ${ty})`});svg.appendChild(ar);edgeArrows.push(ar);}); const nodeGroups={};nodes.forEach(n=>{const g=el("g",{class:"node"});g.appendChild(el("rect",{x:n.x-85,y:n.y-29,width:170,height:58}));const t=el("text",{class:"t",x:n.x,y:n.y-4,"text-anchor":"middle"});t.textContent=n.label;const s=el("text",{class:"s",x:n.x,y:n.y+16,"text-anchor":"middle"});s.textContent=n.sub;g.appendChild(t);g.appendChild(s);svg.appendChild(g);nodeGroups[n.id]=g;}); const travel=el("circle",{class:"travel",r:6,opacity:0});svg.appendChild(travel);const caption=document.getElementById("caption-mindar");const N=edges.length;let i=0,raf=null; function clearActive(){nodes.forEach(n=>nodeGroups[n.id].classList.remove("active"));edgePaths.forEach(p=>p.classList.remove("active"));edgeArrows.forEach(a=>a.classList.remove("active"));} function animateEdge(idx){const ed=edges[idx];clearActive();edgePaths[idx].classList.add("active");edgeArrows[idx].classList.add("active");nodeGroups[ed.from].classList.add("active");caption.innerHTML=`Paso ${idx+1}/${N}: ${ed.from} → ${ed.to} (${ed.label})`;const path=edgePaths[idx],len=path.getTotalLength();const t0=performance.now(),dur=800;function step(now){let p=(now-t0)/dur;if(p>1)p=1;const pt=path.getPointAtLength(p*len);travel.setAttribute("cx",pt.x);travel.setAttribute("cy",pt.y);travel.setAttribute("opacity",1);if(panimateEdge(i),300);}}raf=requestAnimationFrame(step);} function start(){cancelAnimationFrame(raf);i=0;animateEdge(0);}svg.addEventListener("click",start);start(); })(); --- ## Cómo se conecta con el OKF - **Sitio:** https://gerardoesquivia.com/mindar/ - **Nota:** esta (bajada del sitio, para consulta del agente) - **Fuente:** https://gerardoesquivia.com/mindar/ ## Aprendizajes - Los scripts minimalistas son el activo: **el ejemplo más corto que demuestra el uso**. - Este estudio forma parte del ciclo: **estudiar → publicar → registrar en el OKF**.