aeworks.tech/lab/portal-imagen
← AE Lab

La foto que es un portal

21 oct 2026· nivel avanzadoView Transitions3D y paralajegalería

Una galería de destinos de viaje donde cada foto es una puerta: al tocarla crece hasta llenar la pantalla y la cámara se mete dentro del paisaje, con las capas separándose en 3D. Al volver, sales del portal y la foto regresa a su tarjeta.

// CÓMO ESTÁ HECHO

  1. Cada paisaje se dibuja con SVG en 5 capas (cielo, lejos, medio, niebla, primer plano) generadas por código con números aleatorios con semilla.
  2. Dentro del portal cada capa se aleja con translateZ y se agranda con scale lo justo para verse plana: así la foto pequeña y la escena 3D coinciden.
  3. document.startViewTransition pasa el view-transition-name de la foto de la tarjeta a la escena: el navegador la hace crecer hasta llenar la pantalla.
  4. A la vez, una animación (Web Animations) avanza el mundo en Z: las capas cercanas crecen más que las lejanas y el primer plano pasa de largo.
  5. Sin View Transitions, un FLIP con transform hace el mismo viaje; con «reducir movimiento», un fundido; teclado completo (Enter abre, Esc vuelve).

// EL CÓDIGO

<div class="app" id="app">
  <header class="cabecera">
    <div>
      <p class="marca"><i></i>UMBRAL · VIAJES</p>
      <h1>¿A dónde te <em>llevamos</em>?</h1>
    </div>
    <p class="pista">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 11V5a2 2 0 0 1 4 0v6m0-2a2 2 0 0 1 4 0v4a7 7 0 0 1-7 7h-.5a6 6 0 0 1-5-2.7L3 15a2 2 0 0 1 3.3-2.2L9 15"/></svg>
      <span class="dedo">Toca una foto y entra en ella</span><span class="raton">Haz clic en una foto y entra en ella</span>
    </p>
  </header>
  <main class="galeria" id="galeria" aria-label="Destinos"></main>
</div>

<div class="portal" id="portal" hidden>
  <div class="oscuro" id="oscuro"></div>
  <div class="escena" id="escena"><div class="camara" id="camara"><div class="mundo" id="mundo"></div></div></div>
  <div class="velo"></div>
  <p class="portal-marca"><i></i>UMBRAL · <span id="f-num">01 / 06</span></p>
  <section class="ficha" id="ficha" role="dialog" aria-modal="true" aria-labelledby="f-nombre">
    <p class="f-region" id="f-region"></p>
    <h2 id="f-nombre" tabindex="-1"></h2>
    <p class="f-texto" id="f-texto"></p>
    <ul class="f-datos" id="f-datos"></ul>
    <div class="f-botones">
      <button class="reservar" id="reservar" type="button">Reservar</button>
      <button id="volver" type="button">← Volver</button>
    </div>
    <p class="f-aviso" id="f-aviso" role="status"></p>
    <p class="f-pista"><kbd>Esc</kbd> para volver</p>
  </section>
</div>