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';
};