Aprende JavaScript desde cero y mira cómo el código se suma hasta llegar a una experiencia WebAR con MindAR, A-Frame y Three.js.
Nivel básico
El código va creciendo paso a paso
En este nivel cada lección suma algo al proyecto. Cuando agregamos JavaScript, te diré si va en index.html o en app.js, en qué parte se coloca y cómo queda el archivo completo después del cambio.
Regla del curso
No borres lo anterior a menos que la lección diga explícitamente que vamos a reemplazar el archivo. La mayoría de pasos agregan líneas nuevas al final de app.js o modifican una zona concreta de index.html.
HTML base
Crear el primer archivo index.html
Primero creamos la página. Todavía no hay realidad aumentada. Solo estamos preparando el lugar donde JavaScript se va a ejecutar.
Dónde va este código: abre index.html y crea el archivo completo con este contenido.
Archivo completo en este puntoindex.html
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Aprendiendo JavaScript para WebAR</title>
<script src="app.js" defer></script>
</head>
<body>
<h1>Mi primera página con JavaScript</h1>
</body>
</html>
Explicación línea por línea
Línea 6: conecta app.js. Ese archivo todavía puede estar vacío, pero ya quedó enlazado.
Línea 9: crea un título visible para probar la página.
Consola
Crear app.js y escribir los primeros mensajes
Ahora sí creamos app.js. Este código no va dentro de index.html; va en un archivo separado porque el HTML ya lo está cargando en la línea 6.
Dónde va este código: abre app.js y crea el archivo y pega estas líneas desde la línea 1.
Archivo completo en este puntoapp.js
console.log("JavaScript está funcionando");
console.log("Estoy aprendiendo para usarlo luego en WebAR");
Explicación línea por línea
Línea 1: confirma en la consola que JavaScript está cargando.
Línea 2: deja claro el objetivo: primero aprender el lenguaje, luego usarlo en WebAR.
Variables y constantes
Agregar let y const debajo de los console.log
Las variables y constantes se escriben en app.js, debajo de lo que ya teníamos. No reemplaces los console.log anteriores: ahora el archivo crece.
Dónde va este código: abre app.js y pega las líneas nuevas debajo de la línea 2. El archivo completo debe quedar así.
Archivo completo acumuladoapp.js
console.log("JavaScript está funcionando");
console.log("Estoy aprendiendo para usarlo luego en WebAR");
let nombreCurso = "JavaScript para WebAR";
let escaneos = 0;
let targetVisible = false;
const rutaTarget = "targets/poster.mind";
const escalaInicial = 0.4;
console.log(nombreCurso);
console.log("Escaneos:", escaneos);
console.log("Target visible:", targetVisible);
console.log("Archivo target:", rutaTarget);
Explicación línea por línea
Líneas 4 a 6: usan let porque esos valores pueden cambiar.
Líneas 8 y 9: usan const porque son datos base del proyecto.
Líneas 11 a 14: imprimen valores para comprobarlos.
Tipos y operadores
Sumar strings, arrays, objetos y comparaciones
Seguimos trabajando en app.js. Esta lección agrega datos más ricos y operaciones simples. Todo va al final del archivo anterior.
Dónde va este código: abre app.js y agrega desde la línea 15 hacia abajo. Aquí ves el archivo completo hasta este momento.
Archivo completo acumuladoapp.js
console.log("JavaScript está funcionando");
console.log("Estoy aprendiendo para usarlo luego en WebAR");
let nombreCurso = "JavaScript para WebAR";
let escaneos = 0;
let targetVisible = false;
const rutaTarget = "targets/poster.mind";
const escalaInicial = 0.4;
console.log(nombreCurso);
console.log("Escaneos:", escaneos);
console.log("Target visible:", targetVisible);
console.log("Archivo target:", rutaTarget);
const titulo = "Producto aumentado";
const colores = ["azul", "verde", "amarillo"];
const producto = {
nombre: "Café Aurora",
modelo: "assets/cafe.glb",
precio: 8
};
escaneos = escaneos + 1;
const yaEscaneo = escaneos > 0;
const mensaje = "Escaneos realizados: " + escaneos;
console.log(titulo);
console.log(colores[0]);
console.log(producto.nombre);
console.log(yaEscaneo);
console.log(mensaje);
Explicación línea por línea
Líneas 15 a 23: agregan string, array y object.
Línea 25: actualiza una variable que ya existía.
Línea 26: crea una comparación verdadera/falsa.
Línea 27: une texto con un número.
Funciones
Agregar acciones reutilizables
Una función evita repetir instrucciones. La agregamos al final de app.js porque usa valores que ya existen, como escaneos.
Dónde va este código: abre app.js y agrega las funciones debajo de los últimos console.log. El archivo acumulado queda así.
Archivo completo acumuladoapp.js
console.log("JavaScript está funcionando");
console.log("Estoy aprendiendo para usarlo luego en WebAR");
let nombreCurso = "JavaScript para WebAR";
let escaneos = 0;
let targetVisible = false;
const rutaTarget = "targets/poster.mind";
const escalaInicial = 0.4;
console.log(nombreCurso);
console.log("Escaneos:", escaneos);
console.log("Target visible:", targetVisible);
console.log("Archivo target:", rutaTarget);
const titulo = "Producto aumentado";
const colores = ["azul", "verde", "amarillo"];
const producto = {
nombre: "Café Aurora",
modelo: "assets/cafe.glb",
precio: 8
};
escaneos = escaneos + 1;
const yaEscaneo = escaneos > 0;
const mensaje = "Escaneos realizados: " + escaneos;
console.log(titulo);
console.log(colores[0]);
console.log(producto.nombre);
console.log(yaEscaneo);
console.log(mensaje);
function mostrarMensaje(texto) {
console.log(texto);
}
function sumarEscaneo() {
escaneos = escaneos + 1;
return escaneos;
}
mostrarMensaje("Escanea el marcador");
console.log("Nuevo escaneo:", sumarEscaneo());
Explicación línea por línea
Líneas 37 a 39: crean una función que recibe texto.
Líneas 41 a 44: crean una función que cambia escaneos y devuelve el nuevo valor.
Líneas 46 y 47: ejecutan las funciones.
DOM y eventos
Modificar index.html y luego sumar código en app.js
Este es el primer paso donde tocamos dos archivos. Primero reemplaza el contenido del body en index.html. Luego agrega al final de app.js el código que selecciona esos elementos.
Qué es document.querySelector()
document representa toda la página HTML cargada en el navegador. querySelector() es una función que busca dentro de esa página y devuelve el primer elemento que coincida con el selector que escribas.
document.querySelector("#titulo") busca un elemento con id="titulo". El símbolo # significa id.
document.querySelector(".boton") busca un elemento con class="boton". El símbolo . significa clase.
document.querySelector("button") busca la primera etiqueta <button> que encuentre.
Si no encuentra nada, devuelve null. Por eso el nombre del id en HTML debe coincidir exactamente con el selector usado en JavaScript.
Qué son textContent y addEventListener()
textContent es una propiedad que permite leer o cambiar el texto interno de un elemento HTML. Si tienes <h1 id="titulo">Hola</h1>, entonces titulo.textContent = "Nuevo texto" cambia lo que el usuario ve en pantalla.
addEventListener() sirve para escuchar algo que ocurre. Por ejemplo: un clic, una tecla, la carga de un archivo o la detección de un target en MindAR. La estructura es: elemento.addEventListener("evento", función).
boton.addEventListener("click", ...) escucha clics sobre un botón.
target.addEventListener("targetFound", ...) escucha cuando MindAR reconoce una imagen.
target.addEventListener("targetLost", ...) escucha cuando MindAR pierde la imagen.
Dónde va este código: abre index.html y reemplaza el archivo completo por esta versión, que agrega id, contador y botón.
Dónde va este código: abre app.js y después agrega estas líneas al final. Aquí ves el archivo completo acumulado.
Archivo app.js completoapp.js
console.log("JavaScript está funcionando");
console.log("Estoy aprendiendo para usarlo luego en WebAR");
let nombreCurso = "JavaScript para WebAR";
let escaneos = 0;
let targetVisible = false;
const rutaTarget = "targets/poster.mind";
const escalaInicial = 0.4;
console.log(nombreCurso);
console.log("Escaneos:", escaneos);
console.log("Target visible:", targetVisible);
console.log("Archivo target:", rutaTarget);
const titulo = "Producto aumentado";
const colores = ["azul", "verde", "amarillo"];
const producto = {
nombre: "Café Aurora",
modelo: "assets/cafe.glb",
precio: 8
};
escaneos = escaneos + 1;
const yaEscaneo = escaneos > 0;
const mensaje = "Escaneos realizados: " + escaneos;
console.log(titulo);
console.log(colores[0]);
console.log(producto.nombre);
console.log(yaEscaneo);
console.log(mensaje);
function mostrarMensaje(texto) {
console.log(texto);
}
function sumarEscaneo() {
escaneos = escaneos + 1;
return escaneos;
}
mostrarMensaje("Escanea el marcador");
console.log("Nuevo escaneo:", sumarEscaneo());
const tituloPagina = document.querySelector("#titulo");
const contador = document.querySelector("#contador");
const boton = document.querySelector("#boton");
let clics = 0;
boton.addEventListener("click", () => {
clics = clics + 1;
tituloPagina.textContent = "JavaScript ya está controlando el HTML";
contador.textContent = "Clics: " + clics;
});
Explicación línea por línea
Línea 49: busca en el HTML el elemento con id="titulo" y lo guarda en la constante tituloPagina.
Línea 50: busca el elemento con id="contador".
Línea 51: busca el botón con id="boton".
Línea 54: escucha el clic del botón. Solo funciona porque la línea 51 encontró ese botón.
Líneas 56 y 57: modifican el HTML desde JavaScript usando los elementos guardados.
Puente WebAR
Reemplazar el HTML normal por una escena MindAR
Ahora hacemos un cambio grande: reemplazamos el index.html de práctica por un index.html WebAR. Esto sí reemplaza el archivo completo porque entramos a una nueva etapa.
Dónde va este código: abre index.html y reemplaza todo el archivo por esta escena base WebAR.
Líneas 20 a 22: crean el target y una caja que JavaScript controlará.
Archivo .mind
Crear el target antes de programar eventos
El HTML anterior ya apunta a targets/poster.mind. Por eso ahora debes generar ese archivo y guardarlo dentro de la carpeta targets/ con el nombre poster.mind.
Dónde va este código: abre targets/poster.mind y usa el compilador, descarga el archivo y guárdalo con ese nombre exacto.
Compilador integrado
Crear el archivo .mind para practicar WebAR
Este bloque crea el archivo que luego colocarás en la carpeta targets/. Primero cargas una imagen, luego la analizas, después la compilas y finalmente descargas el archivo .mind.
No hay imágenes seleccionadas.
Selecciona una imagen para comenzar.
Importante
El compilador solo funciona desde http://localhost o HTTPS. Si abres el curso con file://, el navegador bloquea módulos y cámara.
MindAR
Reemplazar app.js por la lógica WebAR inicial
Como pasamos de una práctica HTML a una escena WebAR, ahora sí reemplazamos app.js. Ya no necesitamos el código de consola, clics y DOM normal. Ahora usaremos el mismo conocimiento, pero aplicado a elementos de A-Frame.
Qué es setAttribute()
setAttribute() cambia un atributo de un elemento HTML. En A-Frame es muy importante porque los objetos 3D también se configuran con atributos.
Por ejemplo, box.setAttribute("visible", "true") busca el atributo visible de la caja y lo cambia a true. Eso hace que el objeto aparezca en la escena.
setAttribute("visible", "false") oculta un objeto.
setAttribute("color", "#22c55e") cambia el color.
setAttribute("position", "0 0 0") cambia la posición en X, Y, Z.
Dónde va este código: abre app.js y reemplaza todo el archivo por este código WebAR inicial.
Archivo app.js completoapp.js
const target = document.querySelector("#target");
const box = document.querySelector("#box");
const status = document.querySelector("#status");
let targetVisible = false;
let escaneos = 0;
function mostrarCaja() {
box.setAttribute("visible", "true");
}
function ocultarCaja() {
box.setAttribute("visible", "false");
}
target.addEventListener("targetFound", () => {
targetVisible = true;
escaneos = escaneos + 1;
status.textContent = "Target detectado. Escaneos: " + escaneos;
mostrarCaja();
});
target.addEventListener("targetLost", () => {
targetVisible = false;
status.textContent = "Busca otra vez el marcador";
ocultarCaja();
});
ocultarCaja();
Explicación línea por línea
Línea 1: usa document.querySelector("#target") para buscar la entidad A-Frame con id="target".
Línea 2: busca la caja 3D con id="box".
Línea 3: busca el texto de estado con id="status".
Líneas 5 y 6: guardan estados con let.
Líneas 8 a 14: crean funciones reutilizables.
Líneas 16 a 28: escuchan eventos de MindAR.
Three.js
Mejorar app.js usando object3D
Ahora no reemplazamos todo conceptualmente: mejoramos las funciones mostrarCaja() y ocultarCaja(). Para que no haya dudas, aquí tienes el archivo completo final de app.js.
Qué es object3D
object3D es la puerta desde A-Frame hacia Three.js. A-Frame te deja escribir una escena con etiquetas HTML, pero por debajo cada entidad tiene un objeto real de Three.js. Ese objeto vive en elemento.object3D.
Cuando usamos box.object3D.scale.set(...), box.object3D.rotation.y o box.object3D.visible, estamos modificando el objeto 3D directamente desde Three.js.
Dónde va este código: abre app.js y reemplaza el archivo por esta versión final que usa Three.js directamente.
Archivo app.js completoapp.js
const target = document.querySelector("#target");
const box = document.querySelector("#box");
const status = document.querySelector("#status");
let targetVisible = false;
let escaneos = 0;
function mostrarCaja() {
box.object3D.scale.set(0.5, 0.5, 0.5);
box.object3D.rotation.y = THREE.MathUtils.degToRad(25);
box.object3D.visible = true;
}
function ocultarCaja() {
box.object3D.visible = false;
}
target.addEventListener("targetFound", () => {
targetVisible = true;
escaneos = escaneos + 1;
status.textContent = "Target detectado. Escaneos: " + escaneos;
mostrarCaja();
});
target.addEventListener("targetLost", () => {
targetVisible = false;
status.textContent = "Busca otra vez el marcador";
ocultarCaja();
});
ocultarCaja();
status.textContent = "Escanea el marcador";
Explicación línea por línea
Líneas 8 a 12: muestran la caja y ajustan escala/rotación desde Three.js.
Líneas 14 a 16: ocultan la caja desde object3D.
Líneas 18 a 29: mantienen los mismos eventos de MindAR.
Código final
Archivos finales del nivel básico
Estos son los dos archivos finales. El estudiante debe poder comparar todo el camino y ver cómo pasamos de JavaScript puro a WebAR.
const target = document.querySelector("#target");
const box = document.querySelector("#box");
const status = document.querySelector("#status");
let targetVisible = false;
let escaneos = 0;
function mostrarCaja() {
box.object3D.scale.set(0.5, 0.5, 0.5);
box.object3D.rotation.y = THREE.MathUtils.degToRad(25);
box.object3D.visible = true;
}
function ocultarCaja() {
box.object3D.visible = false;
}
target.addEventListener("targetFound", () => {
targetVisible = true;
escaneos = escaneos + 1;
status.textContent = "Target detectado. Escaneos: " + escaneos;
mostrarCaja();
});
target.addEventListener("targetLost", () => {
targetVisible = false;
status.textContent = "Busca otra vez el marcador";
ocultarCaja();
});
ocultarCaja();
status.textContent = "Escanea el marcador";
Template
Descargar proyecto básico
El template contiene esta estructura final lista para practicar. Recuerda: el estudiante debe reemplazar targets/poster.mind por el archivo que compile.
Template JavaScript WebAR básico
Incluye HTML, JavaScript, carpeta de targets y base MindAR/A-Frame/Three.js.