aeworks.tech/lab/boton-magnetico
← AE Lab

El botón que te atrae

20 oct 2026· nivel avanzadobotónfísicacanvaspartículas

Un botón de llamada a la acción con imán: se acerca al cursor estirándose como una goma, enseña el hueco de donde sale y, al soltarlo, vuelve rebotando como una gelatina. Al pulsarlo estalla en partículas que escriben «¡Hecho!» y vuelven a ser botón. En el móvil salta hacia el dedo.

// CÓMO ESTÁ HECHO

  1. Se mide la distancia del puntero al centro del botón; si entra en su radio, el objetivo es acercarse un 40 % hacia él, con la fuerza apagándose suave en el borde para que no dé tirones.
  2. Un muelle con rozamiento lleva el botón al objetivo en cada fotograma (v = (v + (objetivo − x) · 0,12) · 0,78). Al soltarlo cambia a un muelle más duro y con menos rozamiento (0,19 y 0,885): se pasa, vuelve y rebota como una gelatina.
  3. El detalle pro: el botón se estira en la dirección en la que se mueve con rotate(ángulo) scale(1 + e, 1 − e/2) rotate(−ángulo), y una silueta discontinua y una goma de luz marcan el sitio de reposo. Además se inclina en 3D y el texto se mueve un 45 % más (paralaje).
  4. Al pulsar, se dibujan a escondidas el botón y la palabra «¡Hecho!» en canvas ocultos; con getImageData se sacan sus píxeles y cada partícula viaja con un muelle de una forma a la otra y vuelve.
  5. Accesible y en móvil: es un <button> de verdad (Intro, Espacio y Tab, que también lo despierta), avisa por aria-live, en el móvil salta hacia el dedo y vibra al pulsar, y con prefers-reduced-motion solo cambia el texto. Un cursor fantasma lo enseña en bucle hasta que lo tocas.

// EL CÓDIGO

<div class="pagina" id="pagina">
  <canvas id="campo" aria-hidden="true"></canvas>
  <div class="halo" id="halo" aria-hidden="true"></div>
  <canvas id="goma" aria-hidden="true"></canvas>

  <header class="cabecera">
    <div class="marca">
      <!-- Logotipo inventado: una brújula -->
      <svg viewBox="0 0 32 32" aria-hidden="true"><circle cx="16" cy="16" r="14" fill="none" stroke="#00FF7F" stroke-width="2"/><path d="M16 6l4 10-4 10-4-10z" fill="#00FF7F"/><circle cx="16" cy="16" r="2" fill="#05070A"/></svg>
      <div>Rumbo<small>academia online</small></div>
    </div>
    <ul class="menu"><li>Cursos</li><li>Mentores</li><li>Precios</li><li>Opiniones</li></ul>
    <span class="entrar">Entrar</span>
  </header>

  <main class="portada">
    <p class="antetitulo"><i></i>Matrícula abierta · grupo de noviembre</p>
    <h1>Aprende a programar <em>sin perder el rumbo</em>.</h1>
    <p class="entradilla">12 semanas, proyectos reales y un mentor por cada ocho alumnos. Online y a tu ritmo.</p>

    <div class="iman" id="iman">
      <span class="ancla" id="ancla" aria-hidden="true"></span>
      <button class="cta" id="cta" type="button">
        <span class="cta-texto" id="ctaTexto">Reserva tu plaza
          <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h13M13 6l6 6-6 6" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/></svg>
        </span>
      </button>
    </div>
    <p class="nota">Quedan <b>14 plazas</b> · sin permanencia</p>
  </main>

  <ul class="datos">
    <li><strong>12 sem.</strong><span>de curso intensivo</span></li>
    <li><strong>1 : 8</strong><span>mentor por alumnos</span></li>
    <li><strong>94 %</strong><span>termina el curso</span></li>
  </ul>

  <canvas id="particulas" aria-hidden="true"></canvas>
  <div class="fantasma" id="fantasma" aria-hidden="true">
    <svg viewBox="0 0 26 26"><path d="M3 2l18 9.5-7.6 1.9L9.6 21z" fill="#E8F5EE" stroke="#05070A" stroke-width="1.4" stroke-linejoin="round"/></svg>
    <div class="dedo"></div>
  </div>
  <p class="solo-lector" id="aviso" aria-live="polite"></p>
</div>

Ver el vídeo ↗