Nell'animazione precedente ho aggiunto l'interazione con la tastiera, adesso vediamo come gestire il movimento del mouse per muovere più oggetti contemporaneamente.
Usa i tasti cursore per muovere il quadrato bianco e i tasti WDSA per muovere il cerchio viola. Usa il mouse per muovere i 5 cerchi verdi.

Riprendo l'oggetto UserInput aggiungo le coordinate del mouse:
/* gestione eventi da tastiera e mouse */
function UserInput() {
  ...
  this.mouse = {
    x: 0,
    y: 0
  };
}
e gestisco l'evento mousemove per salvare le coordinate:
//aggancio l'evento mouse move
function handleMouseMove(event) {
  userInput.mouse.x = event.offsetX;
  userInput.mouse.y = event.offsetY;
  //console.log(userInput.mouse);
}
canvas.addEventListener('mousemove', handleMouseMove);
Come nel caso della tastiera, anche per il mouse devo gestire in modo specifico la posizione dell'animazione:
function updatePosition() {
  arena.sprites.forEach(sprite => {
    if (sprite.animationType === AnimationType.MOUSE) {
      // in caso di movivento con il mosue, semplicemente associo le coordinate del mouse
      sprite.x = userInput.mouse.x + sprite.deltaX;
      sprite.y = userInput.mouse.y + sprite.deltaY;
    }
    else if (sprite.animationType === AnimationType.KEYBOARD_LEFT || sprite.animationType === AnimationType.KEYBOARD_RIGHT) {
      //gestisco lo spostamento da tastiera tramite i tasti cursore
      const keyBoard = sprite.animationType === AnimationType.KEYBOARD_LEFT ? userInput.keyboardLeft : userInput.keyboardRight;
      if (keyBoard.up)
        sprite.y -= Math.abs(sprite.deltaY);
      if (keyBoard.right)
        sprite.x += Math.abs(sprite.deltaX);
      if (keyBoard.down)
        sprite.y += Math.abs(sprite.deltaY);
      if (keyBoard.left)
        sprite.x -= Math.abs(sprite.deltaX);
    } else if (sprite.animationType === AnimationType.LINEAR) {
      //normale animazione
      sprite.x += sprite.deltaX;
      sprite.y += sprite.deltaY;
    }
  });
}
e aggiorno la gestione della collisione con i bordi:
function checkCollision() {
  //verifico la collisione con i bordi
  arena.sprites.forEach(sprite => {
    // in caso di movivento con il mosue, semplicemente associo le coordinate del mouse
    //il movimento del mouse lo gestisco come la tastiera
    if (sprite.animationType === AnimationType.KEYBOARD_LEFT || sprite.animationType === AnimationType.KEYBOARD_RIGHT
      || sprite.animationType === AnimationType.MOUSE) {
      switch (sprite.type) {
        case SpriteType.RECTANGLE:
          const w2 = sprite.w / 2;
          const h2 = sprite.h / 2;
          if (sprite.x - w2 < 0 || sprite.x + w2 > innerWidth) {
            //se è mosso dalla tastiera non devo invertire il moto
            sprite.x = sprite.x - w2 < 0 ? w2 : innerWidth - w2;
          }
          if (sprite.y - h2 < 0 || sprite.y + h2 > innerHeight) {
            //se è mosso dalla tastiera non devo invertire il moto
            sprite.y = sprite.y - h2 < 0 ? h2 : innerHeight - h2;
          }
          break;

        case SpriteType.CIRCLE:
          if (sprite.x - sprite.radius < 0 || sprite.x + sprite.radius > innerWidth) {
            sprite.x = sprite.x - sprite.radius < 0 ? sprite.radius : innerWidth - sprite.radius;
          }
          if (sprite.y - sprite.radius < 0 || sprite.y + sprite.radius > innerHeight) {
            sprite.y = sprite.y - sprite.radius < 0 ? sprite.radius : innerHeight - sprite.radius;
          }
          break;
      }

    } else if (sprite.animationType !== AnimationType.NONE) {
      switch (sprite.type) {
        case SpriteType.RECTANGLE:
          const w2 = sprite.w / 2;
          const h2 = sprite.h / 2;
          if (sprite.x - w2 < 0 || sprite.x + w2 > innerWidth) {
            sprite.deltaX = -sprite.deltaX;
            sprite.x += sprite.deltaX;
          }
          if (sprite.y - h2 < 0 || sprite.y + h2 > innerHeight) {
            sprite.deltaY = -sprite.deltaY;
            sprite.y += sprite.deltaY;
          }
          break;

        case SpriteType.CIRCLE:
          if (sprite.x - sprite.radius < 0 || sprite.x + sprite.radius > innerWidth) {
            sprite.deltaX = -sprite.deltaX;
            sprite.x += sprite.deltaX;
          }
          if (sprite.y - sprite.radius < 0 || sprite.y + sprite.radius > innerHeight) {
            sprite.deltaY = -sprite.deltaY;
            sprite.Y += sprite.deltaY;
          }
          break;
      }
    }
  });
}
Infine aggiungo gli sprite mossi con il mouse:
function createSprites() {
  ...


  //aggiungo un cerchio VERDE controllato dal mouse
  const circlMouse = new SpriteCircle(cx, cy, 10, null, '#0f0');
  //cambio il tipo di animazione
  circlMouse.animationType = AnimationType.MOUSE;
  arena.addSprite(circlMouse);
  //gestisco altri sprite "speculari" econtrollati dal mouse
  const circlMouse2 = new SpriteCircle(cx, cy, 10, null, '#080', 20, 20);
  circlMouse2.animationType = AnimationType.MOUSE;
  arena.addSprite(circlMouse2);
  const circlMouse3 = new SpriteCircle(cx, cy, 10, null, '#080', -20, 20);
  circlMouse3.animationType = AnimationType.MOUSE;
  arena.addSprite(circlMouse3);
  const circlMouse4 = new SpriteCircle(cx, cy, 10, null, '#080', -20, -20);
  circlMouse4.animationType = AnimationType.MOUSE;
  arena.addSprite(circlMouse4);
  const circlMouse5 = new SpriteCircle(cx, cy, 10, null, '#080', 20, -20);
  circlMouse5.animationType = AnimationType.MOUSE;
  arena.addSprite(circlMouse5);  
  //setto un default per le coordinate del mouse al centro dello schermo
  userInput.mouse.x = cx;
  userInput.mouse.y = cy;

  ...
}
Il risultato è l'animazione a inizio pagina.