JavaScript

Web APIs

Webcam

Por explorar otras de las muchas APIs Web disponibles, vamos a utilizar las de la Webcam y Canvas para hacernos una foto.

<body>
<div class="card">
  <div class="card-body row">
    <div class="col-12">
      <video id="video">Cámara no disponible</video>
      <canvas id="canvas" hidden></canvas>
    </div>
    <div class="col-12 text-center mt-3">
      <button id="foto" type="button" class="btn btn-outline-secondary">
        <i class="bi bi-camera-fill"></i> Foto
      </button>
    </div>
  </div>
</div>
</body>
html { font-size: 50%; padding: 2rem; }
video, canvas { width: 30em; border-radius: 1em; padding: 0.5em; border: 1px dashed; }
canvas { border-color: black; }
video { border-color: transparent; }
.card { width: 32.2rem;}
// El elemento vídeo muestra el stream de la cámara
const video = document.getElementById("video");
// El elemento canvas pinta una instantánea del stream
const canvas = document.getElementById("canvas");
const foto = document.getElementById("foto");
// API de la webcam para obtener su stream
navigator.mediaDevices
  .getUserMedia({ video: true, audio: false })
  .then((stream) => {
    video.srcObject = stream;
    video.play();
  }).catch((err) => {
    foto.disabled = true;
    foto.innerHTML = 
      '<i class="bi bi-exclamation-triangle-fill"></i> Pulsa en "Edit on Codepen"';
  });
// API del canvas que pinta la imagen actual del vídeo
const hazFoto = function() {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  const context = canvas.getContext("2d");
  context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
}
// Para descargar la imagen capturada
const descargar = function() {
  const link = document.createElement('a');
  link.download = 'foto.png';
  link.href = canvas.toDataURL();
  link.click();
}
// Para alternar el botón entre foto y descarga
foto.onclick = function() {
  const modoFoto = foto.textContent.indexOf('Foto') > -1;
  modoFoto ? hazFoto() : descargar();
  video.hidden = modoFoto;
  canvas.hidden = !modoFoto;
  foto.innerHTML = modoFoto ? 
    '<i class="bi bi-file-earmark-arrow-down-fill"></i> Descargar' : 
    '<i class="bi bi-camera-fill"></i> Foto';
};