2

I'd like to add a new subpage to my Angular app at which I could snap a photo from a webcam. I found the working example of taking a photo by using HTML5 here. For routing within the app I'm using ng-view.

And here's the problem: when I paste html part from the example directly into my index.html everything works perfectly (but there is no routing). And when I paste it into subpage.html it's not working -> there is no permission pop-up and I cannot see webcam feed.

I modified my project as follows:

Added to index.html:

  <script src="js/vendor/jquery.min.js"></script>
  <script src="js/scripts/camera.js"></script> 

camera.js contains the <script> part from the example.

subpage.html:

<div class="camcontent">
    <video id="video" autoplay></video>
    <canvas id="canvas" width="640" height="480">
</div>
<div class="cambuttons">
    <button id="snap" style="display:none;">  Capture </button> 
    <button id="reset" style="display:none;">  Reset  </button>     

 </div>

In general routing works but I'm guessing that a problem is in using ng-view and camera.js.

Any idea how can I fix it?

camera.js:

// Put event listeners into place
    window.addEventListener("DOMContentLoaded", function() {
        // Grab elements, create settings, etc.
        var canvas = document.getElementById("canvas"),
            context = canvas.getContext("2d"),
            video = document.getElementById("video"),
            videoObj = { "video": true },
            image_format= "jpeg",
            jpeg_quality= 85,
            errBack = function(error) {
                console.log("Video capture error: ", error.code); 
            };


        // Put video listeners into place
        if(navigator.getUserMedia) { // Standard
            navigator.getUserMedia(videoObj, function(stream) {
                video.src = stream;
                video.play();
                $("#snap").show();
            }, errBack);
        } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
            navigator.webkitGetUserMedia(videoObj, function(stream){
                video.src = window.webkitURL.createObjectURL(stream);
                video.play();
                $("#snap").show();
            }, errBack);
        } else if(navigator.mozGetUserMedia) { // moz-prefixed
            navigator.mozGetUserMedia(videoObj, function(stream){
                video.src = window.URL.createObjectURL(stream);
                video.play();
                $("#snap").show();
            }, errBack);
        }
              // video.play();       these 2 lines must be repeated above 3 times
              // $("#snap").show();  rather than here once, to keep "capture" hidden
              //                     until after the webcam has been activated.  

        // Get-Save Snapshot - image 
        document.getElementById("snap").addEventListener("click", function() {
            context.drawImage(video, 0, 0, 640, 480);
            // the fade only works on firefox?
            $("#video").fadeOut("slow");
            $("#canvas").fadeIn("slow");
            $("#snap").hide();
            $("#reset").show();
            $("#upload").show();
        });
        // reset - clear - to Capture New Photo
        document.getElementById("reset").addEventListener("click", function() {
            $("#video").fadeIn("slow");
            $("#canvas").fadeOut("slow");
            $("#snap").show();
            $("#reset").hide();
            $("#upload").hide();
        });

    }, false);
LukSy
  • 23
  • 3
  • 1
    Just for reference - angular directives for camera, such as https://github.com/jonashartmann/webcam-directive , https://github.com/onemightyroar/angular-camera , http://www.ng-newsletter.com/advent2013/#!/day/13 – Ori Drori Aug 09 '15 at 19:31
  • Thanks @OriDrori. I tried webcam-directive and it works like a charm. – LukSy Aug 10 '15 at 08:40

1 Answers1

1

The DomContentLoaded DOM event does not fire when ng-view content is loaded. As this is what is used by the camera.js code, it's just never getting initialized. This is why it only works when it's included in index.html.

One option is to use the $viewContentLoaded event:

 $scope.$on('$viewContentLoaded', function(){
    //Could do stuff here
  });

Or, better yet, create a directive to do the work. This would be the best option as it was designed for just this purpose.

You don't need to reinvent the wheel though. Check out the directives highlighted by @OriDrori in the comments:

Matt Tester
  • 4,663
  • 4
  • 29
  • 32