Skip to content

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()