K. Asociaciones

Salida

Ábrelo en otra pestaña.

Revísalo en gilpgedit.

<!DOCTYPE html>
<html lang="es">

<head>
 <meta charset="UTF-8">
 <meta name="viewport"
   content="width=device-width">
 <title>Asociaciones</title>
 <script>
  /**
   * Devuelve un número
   * aleatorio entre el valor
   * menor y el valor mayor.
   * @param {number} menor el
   *  menor valor que se puede
   *  generar
   * @param {number} mayor el
   *  mayor valor que se puede
   *  generar
   * @returns {number} un
   *  número aleatorio entre
   *  menor y mayor.
   */
  function
   aleatorio(menor, mayor) {
   /* Math.floor(x): elimina
    *  los decimales.
    * Math.random(): genera
    *  un número aleatorio
    *  >= 0 y < 1. */
   return menor +
    Math.floor(
     Math.random() *
     (mayor - menor + 1))
  }

  class PerroWeb
   extends HTMLElement {
   connectedCallback() {
    this.x = 0
    this.y = 0
    this.innerHTML = "🐕"
    this.style.position = "fixed"
    this.style.fontSize = "2rem"
    this.style.right =
     `${this.x}px`
    this.style.bottom =
     `${this.y}px`
   }

   muevete() {
    this.x = (this.x + 30) %
     innerWidth
    this.style.right =
     `${this.x}px`
   }
  }
  customElements.define(
   "perro-web", PerroWeb)

  class AguilaWeb
   extends HTMLElement {
   connectedCallback() {
    this.x = aleatorio(0,
     Math.floor(innerWidth))
    this.y = aleatorio(0,
     Math.floor(innerHeight))
    this.innerHTML = "🦅"
    this.style.position = "fixed"
    this.style.fontSize = "2.5rem"
    this.style.left = `${this.x}px`
    this.style.top = `${this.y}px`
   }

   muevete() {
    this.y = (this.y + 10) %
     innerHeight
    this.style.top = `${this.y}px`
   }
  }
  customElements.define(
   "aguila-web", AguilaWeb)

  class ControladorWeb
   extends HTMLElement {
   connectedCallback() {
    this.muevete =
     this.muevete.bind(this)
    this.innerHTML = /* html */
     `<button onclick="this.
        parentElement.muevete()">
       Mueve
      </button>`
    this.perro = new PerroWeb()
    this.aguilas = [
     new AguilaWeb(),
     new AguilaWeb()]
    this.append(this.perro)
    for (const a of this.aguilas) {
     this.append(a)
    }
   }

   muevete() {
    this.perro.muevete()
    for (let a of this.aguilas) {
     a.muevete()
    }
   }
  }
  customElements.define(
   "controlador-web",
   ControladorWeb)
 </script>
</head>

<body>
 <h1>Asociaciones</h1>
 <controlador-web>
 </controlador-web>
</body>

</html>