Eventos y motor
El SDK expone dos mecanismos para reaccionar a lo que ocurre en el visor: callbacks en StartOptions y eventos mediante vto.on(). Adicionalmente, el objeto VtoEngine que devuelve OBVto.init() ofrece métodos para controlar el motor desde el exterior.
Callbacks en start()
Se pasan como campos de StartOptions y se invocan una sola vez por ocurrencia.
| Callback | Firma | Cuándo se invoca |
|---|---|---|
onReady | () => void | El módulo está listo y el loop de renderizado ha arrancado. |
onError | (err: Error) => void | Ocurrió un error durante el arranque (ej. cámara denegada). |
onCapture | (dataUrl: string) => void | El usuario o el código llamó a capture(). |
onAddToCart | (color: Color) => void | El usuario pulsó "Añadir al carrito" en la card del producto. |
onClose | () => void | El visor se cerró y el overlay de cierre terminó (botón ✕ → "Listo"). |
onHome | () => void | El usuario pulsó el botón de inicio en la barra del visor. |
onProductClick | (p: Product) => void | El usuario pulsó "Ver el producto" en la card. |
onFavorite | (p: Product) => void | El usuario añadió un producto a favoritos. |
onUnfavorite | (p: Product) => void | El usuario quitó un producto de favoritos. |
onNps | (result: NpsResult) => void | El usuario envió el formulario NPS (ver 07-cierre-y-nps.md). |
Todos los callbacks son opcionales. Los tipos Color, Product y NpsResult están en 10-referencia-de-tipos.md.
Eventos con vto.on()
Alternativa basada en eventos al estilo EventEmitter. Útil cuando el host no controla start() directamente o necesita múltiples oyentes para el mismo evento.
vto.on(name: VtoEventName, cb: (payload?: VtoEventPayload) => void): void
| Nombre | Payload | Equivale al callback |
|---|---|---|
'ready' | undefined | onReady |
'error' | Error | onError |
'shade_selected' | Color | — (sin callback directo) |
'capture' | string (dataURL) | onCapture |
'add_to_cart' | Color | onAddToCart |
shade_selected se emite cada vez que el usuario elige un tono (incluye la selección del tono inicial al arrancar).
Ejemplo
const vto = await OBVto.init({ modules: ['hair-color'], container: '#vto' })
vto.on('ready', () => console.log('motor listo'))
vto.on('shade_selected', (color) => console.log('tono elegido', color))
vto.on('capture', (dataUrl) => enviarAlServidor(dataUrl))
await vto.start({ module: 'hair-color', colors: TONOS })
Métodos del motor
El objeto VtoEngine devuelto por OBVto.init() expone los siguientes métodos públicos.
| Método | Firma exacta | Descripción |
|---|---|---|
on | on(name: VtoEventName, cb: (payload?: VtoEventPayload) => void): void | Suscribe un oyente a un evento del motor. |
setColor | setColor(id: string): void | Cambia el tono activo por su id. Emite shade_selected. |
setIntensity | setIntensity(v: number): void | Ajusta la intensidad del efecto (0 = sin efecto, 1 = máximo). |
compare | compare(on: boolean): void | Activa o desactiva el modo «Antes | Después» (split de pantalla). |
capture | capture(): string | Captura el visual actual como PNG y devuelve un dataURL. Aplica marca de agua si la licencia lo exige. Invoca onCapture. |
download | download(filename = 'vto.png'): void | Descarga el PNG del visual actual. Internamente llama capture(). |
stop | stop(): void | Detiene el loop de renderizado, libera la cámara y destruye la UI. |
analyze | analyze(): Promise<unknown> | Ejecuta el análisis del módulo activo (si lo soporta). Lanza error si el módulo no implementa analyze. |
Notas de uso
capture()devuelve el composite del split «Antes | Después» cuando está activo, no el canvas crudo.download()llama acapture()internamente: el fichero descargado respeta el watermark de licencia y el composite del split.analyze()lanzaErrorsi no hay módulo activo o si el módulo no implementa la operación. Comprueba la disponibilidad antes de llamarlo si no estás seguro del módulo.stop()es idempotente: llamarlo múltiples veces no produce errores.
Ejemplo
const vto = await OBVto.init({ modules: ['hair-color'], container: '#vto' })
await vto.start({ module: 'hair-color', colors: TONOS })
// Cambiar tono programáticamente
vto.setColor('rubio-dorado')
// Ajustar intensidad al 60 %
vto.setIntensity(0.6)
// Activar modo comparación
vto.compare(true)
// Capturar y compartir
const dataUrl = vto.capture()
compartirImagen(dataUrl)
// Descargar como fichero
vto.download('mi-look-aura.png')
// Detener el motor al salir de la página
window.addEventListener('beforeunload', () => vto.stop())