World Tracking — A-Frame
Integración de Monolook World con A-Frame para detectar superficies y anclar contenido 3D.
Requisitos
- A-Frame cargado vía CDN (sin npm install)
- License key de Monolook World
- HTTPS + Chrome en Android, o Monolook App / AppClip en iOS
HTML
html
<!doctype html>
<html>
<head>
<script src="https://aframe.io/releases/1.6.0/aframe.min.js"></script>
<style>
.a-enter-vr, .a-enter-ar { display: none !important; }
</style>
</head>
<body>
<div id="dom_overlay">
<!-- tu UI aquí -->
</div>
<a-scene id="aframeScene" embedded
vr-mode-ui="enabled: false"
renderer="alpha: true; antialias: true">
<a-entity camera position="0 1.6 0"></a-entity>
<a-box id="cube" color="#f4f4f4" width="0.35" height="0.35" depth="0.35"
position="0 0 -1.2"></a-box>
</a-scene>
<script type="module" src="main.js"></script>
</body>
</html>Oculta los botones VR/AR por defecto de A-Frame — Monolook gestiona la sesión.
Setup
Espera a que la escena de A-Frame termine de cargar antes de crear el adapter:
js
import { Monolook } from 'monolook/world'
const sceneEl = document.getElementById('aframeScene')
const cubeEl = document.getElementById('cube')
// esperar a que A-Frame esté listo
if (!sceneEl.hasLoaded) {
await new Promise(r => sceneEl.addEventListener('loaded', r, { once: true }))
}
const monolook = new Monolook({
adapter: 'aframe',
sceneEl,
domOverlayRoot: document.getElementById('dom_overlay'),
})Eventos e inicio
js
monolook.on('surfacefound', () => setStatus('Superficie detectada — toca para colocar'))
monolook.on('select', colocarCubo)
monolook.on('sessionend', resetTrasSession)
await monolook.start({ mode: 'surface', licenseKey: '<WORLD_LICENSE_KEY>' })
monolook.startTracking()
monolook.setRenderLoop(() => monolook.updateTracking())
await monolook.enterAR()Colocación
Las entidades de A-Frame aceptan la posición como objeto directamente:
js
function colocarCubo() {
if (!monolook.isPresenting() || isPlaced) return
const pose = monolook.getIndicatorPose()
if (!pose?.visible) return
isPlaced = true
cubeEl.setAttribute('position', pose.position)
cubeEl.setAttribute('visible', true)
monolook.pauseTracking()
monolook.setIndicatorVisible(false)
}Ejemplo completo
js
import { Monolook } from 'monolook/world'
const sceneEl = document.getElementById('aframeScene')
const cubeEl = document.getElementById('cube')
let monolook
let isPlaced = false
async function init() {
if (!sceneEl.hasLoaded) {
await new Promise(r => sceneEl.addEventListener('loaded', r, { once: true }))
}
monolook = new Monolook({
adapter: 'aframe',
sceneEl,
domOverlayRoot: document.getElementById('dom_overlay'),
})
monolook.on('surfacefound', () => !isPlaced && setStatus('Superficie detectada — toca para colocar'))
monolook.on('select', colocarCubo)
monolook.on('sessionend', () => {
isPlaced = false
cubeEl.setAttribute('visible', true)
})
window.addEventListener('pointerup', colocarCubo)
document.getElementById('startButton').addEventListener('click', startAR)
}
async function startAR() {
await monolook.start({ mode: 'surface', licenseKey: '<WORLD_LICENSE_KEY>' })
isPlaced = false
cubeEl.setAttribute('visible', false)
monolook.startTracking()
monolook.setRenderLoop(() => monolook.updateTracking())
await monolook.enterAR()
}
function colocarCubo() {
if (!monolook.isPresenting() || isPlaced) return
const pose = monolook.getIndicatorPose()
if (!pose?.visible) return
isPlaced = true
cubeEl.setAttribute('position', pose.position)
cubeEl.setAttribute('visible', true)
monolook.pauseTracking()
monolook.setIndicatorVisible(false)
}
init()