Selfie With JavaScript Demo

by Ravindra Athreya

HTML

<h3>Demo: Take a Selfie With JavaScript</h3>

<div class="container">

  <div class="app">

    <a href="#" id="start-camera" class="visible">Touch here to start the app.</a>
    <video id="camera-stream"></video>
    <img id="snap">

    <p id="error-message"></p>

    <div class="controls">
      <a href="#" id="delete-photo" title="Delete Photo" class="disabled"><i class="material-icons">delete</i></a>
      <a href="#" id="take-photo" title="Take Photo"><i class="material-icons">camera_alt</i></a>
      <a href="#" id="download-photo" download="selfie.png" title="Save Photo" class="disabled"><i class="material-icons">file_download</i></a>  
    </div>

    <!-- Hidden canvas element. Used for taking snapshot of video. -->
    <canvas></canvas>

  </div>

</div>

CSS

@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
@import url('https://fonts.googleapis.com/icon?family=Material+Icons');

*{
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html{
    background-color: #fff;
    font:normal 16px/1.5 sans-serif;
    color: #333;
}

h3{
    font: normal 32px/1.5 'Open Sans', sans-serif;
    color: #2c3e50;
    margin: 50px 0;
    text-align: center;
}


.container{
    max-width: 1000px;
    margin: 50px auto;
    padding: 20px;
    background-color: #efefef;
}

.app{
    width: 100%;
    position: relative;
}

.app #start-camera{
    display: none;
    border-radius: 3px;
    max-width: 400px;
    color: #fff;
    background-color: #448AFF;
    text-decoration: none;
    padding: 15px;
    opacity: 0.8;
    margin: 50px auto;
    text-align: center;
}

.app video#camera-stream{
    display: none;
    width: 100%;
}

.app img#snap{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 10;
    display: none;
}

.app #error-message{
    width: 100%;
    background-color: #ccc;
    color: #9b9b9b;
    font-size: 28px;
    padding: 200px 100px;
    text-align: center;
    display: none;
}

.app .controls{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 20;

    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    padding: 30px;
    display: none;
}

.app .controls a{
    border-radius: 50%;
    color: #fff;
    background-color: #111;
    text-decoration: none;
    padding: 15px;
    line-height: 0;
    opacity: 0.7;
    outline: none;
    -webkit-tap-highlight-color: transparent;
}

.app .controls a:hover{
    opacity: 1;
}

.app .controls a.disabled{
    background-color: #555;
    opacity: 0.5;
    cursor: default;
    pointer-events: none;
}

.app .controls a.disabled:hover{
    opacity: 0.5;
}

.app .controls a i{
    font-size: 18px;
}

.app .controls #take-photo i{
    font-size:...

JavaScript

// References to all the element we will need.
var video = document.querySelector('#camera-stream'),
    image = document.querySelector('#snap'),
    start_camera = document.querySelector('#start-camera'),
    controls = document.querySelector('.controls'),
    take_photo_btn = document.querySelector('#take-photo'),
    delete_photo_btn = document.querySelector('#delete-photo'),
    download_photo_btn = document.querySelector('#download-photo'),
    error_message = document.querySelector('#error-message');


// The getUserMedia interface is used for handling camera input.
// Some browsers need a prefix so here we're covering all the options
navigator.getMedia = ( navigator.getUserMedia ||
                      navigator.webkitGetUserMedia ||
                      navigator.mozGetUserMedia ||
                      navigator.msGetUserMedia);


if(!navigator.getMedia){
  displayErrorMessage("Your browser doesn't have support for the navigator.getUserMedia interface.");
}
else{

  // Request the camera.
  navigator.getMedia(
    {
      video: true
    },
    // Success Callback
    function(stream){

      // Create an object URL for the video stream and
      // set it as src of our HTLM video element.
      video.src = window.URL.createObjectURL(stream);

      // Play the video element to start the stream.
      video.play();
      video.onplay = function() {
        showVideo();
      };

    },
    // Error Callback
    function(err){
      displayErrorMessage("There was an error with accessing the camera stream: " + err.name, err);
    }
  );

}



// Mobile browsers cannot play video without user input,
// so here we're using a button to start it manually.
start_camera.addEventListener("click", function(e){

  e.preventDefault();

  // Start video playback manually.
  video.play();
  showVideo();

});


take_photo_btn.addEventListener("click", function(e){

  e.preventDefault();

  var snap = takeSnapshot();

  // Show image. 
  image.setAttribute('src',...