<h3>Background</h3>
<p>The ImageCapture Web API allows web developers to change the zoom setting of
the camera.</p>

<video autoplay></video>
<input type="range" hidden>

<div>
    <canvas id='takePhotoCanvas'></canvas>
    <button id='takePhotoButton' disabled>Take Photo</button>
  </div>
video {
  background: #263238;
  height: 198px;
  width: 100%;
}

input {
  width: 100%;
}
var imageCapture;

navigator.mediaDevices.getUserMedia({video: true})
.then(async mediaStream => {
  document.querySelector('video').srcObject = mediaStream;

  // Once crbug.com/711524 is fixed, we won't need to wait anymore. This is
  // currently needed because capabilities can only be retrieved after the
  // device starts streaming. This happens after and asynchronously w.r.t.
  // getUserMedia() returns.
  await sleep(1000);

  const track = mediaStream.getVideoTracks()[0];  
  imageCapture = new ImageCapture(track);
  const capabilities = track.getCapabilities();
  const settings = track.getSettings();

  const input = document.querySelector('input[type="range"]');

  // Check whether zoom is supported or not.
  if (!('zoom' in capabilities)) {
    return Promise.reject('Zoom is not supported by ' + track.label);
  }

  // Map zoom to a slider element.
  input.min = capabilities.zoom.min;
  input.max = capabilities.zoom.max;
  input.step = capabilities.zoom.step;
  input.value = settings.zoom;
  console.log( capabilities.zoom);
  input.oninput = function(event) {
    track.applyConstraints({advanced: [ {zoom: event.target.value} ]});
  }
  input.hidden = false;
})
.catch(error => ChromeSamples.log('Argh!', error.name || error));

/* Utils */

function sleep(ms = 0) {
  return new Promise(r => setTimeout(r, ms));
}

function onTakePhotoButtonClick() {
  imageCapture.takePhoto()
  .then(blob => createImageBitmap(blob))
  .then(imageBitmap => {
    const canvas = document.querySelector('#takePhotoCanvas');
    drawCanvas(canvas, imageBitmap);
  })
  .catch(error => console.error(error));
}

function drawCanvas(canvas, img) {
  canvas.width = getComputedStyle(canvas).width.split('px')[0];
  canvas.height = getComputedStyle(canvas).height.split('px')[0];
  let ratio  = Math.min(canvas.width / img.width, canvas.height / img.height);
  let x = (canvas.width - img.width * ratio) / 2;
  let y = (canvas.height - img.height * ratio) / 2;
  canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
  canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height,
      x, y, img.width * ratio, img.height * ratio);
}

document.querySelector('#takePhotoButton').addEventListener('click', onTakePhotoButtonClick);

document.querySelector('video').addEventListener('play', function() {
  document.querySelector('#takePhotoButton').disabled = false;
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.