From 0c24932ae3b47d1f994a43640b45cd3602bce6fa Mon Sep 17 00:00:00 2001 From: Cynni Jong Date: Tue, 8 May 2018 15:33:14 +0800 Subject: [PATCH 1/4] Changed the camera constraint for QRcode scanning, use back camera instead of front camera in mobile devices. --- qr-scanner.js | 157 ++++++++++++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 74 deletions(-) diff --git a/qr-scanner.js b/qr-scanner.js index 6f3a309..637a051 100644 --- a/qr-scanner.js +++ b/qr-scanner.js @@ -1,84 +1,93 @@ -if (require){ - if (!angular) var angular = require('angular'); - if (!qrcode) var qrcode = require('jsqrcode'); +if (require) { + if (!angular) var angular = require('angular'); + if (!qrcode) var qrcode = require('jsqrcode'); } -(function() { -'use strict'; +(function () { + 'use strict'; -angular.module('qrScanner', ["ng"]).directive('qrScanner', ['$interval', '$window', function($interval, $window) { - return { - restrict: 'E', - scope: { - ngSuccess: '&ngSuccess', - ngError: '&ngError', - ngVideoError: '&ngVideoError' - }, - link: function(scope, element, attrs) { - - window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL; - navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; - - var height = attrs.height || 300; - var width = attrs.width || 250; - - var video = $window.document.createElement('video'); - video.setAttribute('width', width); - video.setAttribute('height', height); - video.setAttribute('style', '-moz-transform:rotateY(-180deg);-webkit-transform:rotateY(-180deg);transform:rotateY(-180deg);'); - var canvas = $window.document.createElement('canvas'); - canvas.setAttribute('id', 'qr-canvas'); - canvas.setAttribute('width', width); - canvas.setAttribute('height', height); - canvas.setAttribute('style', 'display:none;'); - - angular.element(element).append(video); - angular.element(element).append(canvas); - var context = canvas.getContext('2d'); - var stopScan; - - var scan = function() { - if ($window.localMediaStream) { - context.drawImage(video, 0, 0, 307,250); - try { - qrcode.decode(); - } catch(e) { - scope.ngError({error: e}); - } - } - } + angular.module('qrScanner', ["ng"]).directive('qrScanner', ['$interval', '$window', '$timeout', function ($interval, $window, $timeout) { + return { + restrict: 'E', + scope: { + ngSuccess: '&ngSuccess', + ngError: '&ngError', + ngVideoError: '&ngVideoError' + }, + link: function (scope, element, attrs) { - var successCallback = function(stream) { - video.src = (window.URL && window.URL.createObjectURL(stream)) || stream; - $window.localMediaStream = stream; + window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; - scope.video = video; - video.play(); - stopScan = $interval(scan, 500); - } + var height = attrs.height || 300; + var width = attrs.width || 250; - // Call the getUserMedia method with our callback functions - if (navigator.getUserMedia) { - navigator.getUserMedia({video: true}, successCallback, function(e) { - scope.ngVideoError({error: e}); - }); - } else { - scope.ngVideoError({error: 'Native web camera streaming (getUserMedia) not supported in this browser.'}); - } + var video = $window.document.createElement('video'); + video.setAttribute('width', width); + video.setAttribute('height', height); + video.setAttribute('style', '-moz-transform:rotateY(-180deg);-webkit-transform:rotateY(-180deg);transform:rotateY(-180deg);'); + var canvas = $window.document.createElement('canvas'); + canvas.setAttribute('id', 'qr-canvas'); + canvas.setAttribute('width', width); + canvas.setAttribute('height', height); + canvas.setAttribute('style', 'display:none;'); - qrcode.callback = function(data) { - scope.ngSuccess({data: data}); - }; + angular.element(element).append(video); + angular.element(element).append(canvas); + var context = canvas.getContext('2d'); + var stopScan; - element.bind('$destroy', function() { - if ($window.localMediaStream) { - $window.localMediaStream.stop(); - } - if (stopScan) { - $interval.cancel(stopScan); + var scan = function () { + if ($window.localMediaStream) { + context.drawImage(video, 0, 0, 307, 250); + try { + qrcode.decode(); + } catch (e) { + scope.ngError({ error: e }); + } + } + } + + var successCallback = function (stream) { + video.src = (window.URL && window.URL.createObjectURL(stream)) || stream; + $window.localMediaStream = stream; + + scope.video = video; + + $timeout(function () { + video.play(); + stopScan = $interval(scan, 500); + }); + } + + // Call the getUserMedia method with our callback functions + if (navigator.getUserMedia) { + var constraint = { + video: { + facingMode: { ideal: "environment" } + } + }; + + navigator.getUserMedia(constraint, successCallback, function (e) { + scope.ngVideoError({ error: e }); + }); + } else { + scope.ngVideoError({ error: 'Native web camera streaming (getUserMedia) not supported in this browser.' }); + } + + qrcode.callback = function (data) { + scope.ngSuccess({ data: data }); + }; + + element.bind('$destroy', function () { + if ($window.localMediaStream) { + $window.localMediaStream.getVideoTracks()[0].stop(); + } + if (stopScan) { + $interval.cancel(stopScan); + } + }); + } } - }); - } - } -}]); + }]); })(); From 0bb6237ee7f4cd100741d8619c2cb740cf9802ac Mon Sep 17 00:00:00 2001 From: Cynni Jong Date: Tue, 8 May 2018 15:40:41 +0800 Subject: [PATCH 2/4] Remove unnecessary changes --- qr-scanner.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/qr-scanner.js b/qr-scanner.js index 637a051..730e4c4 100644 --- a/qr-scanner.js +++ b/qr-scanner.js @@ -1,12 +1,12 @@ -if (require) { +if (require){ if (!angular) var angular = require('angular'); if (!qrcode) var qrcode = require('jsqrcode'); } -(function () { +(function() { 'use strict'; - angular.module('qrScanner', ["ng"]).directive('qrScanner', ['$interval', '$window', '$timeout', function ($interval, $window, $timeout) { + angular.module('qrScanner', ["ng"]).directive('qrScanner', ['$interval', '$window', '$timeout', function($interval, $window, $timeout) { return { restrict: 'E', scope: { @@ -14,7 +14,7 @@ if (require) { ngError: '&ngError', ngVideoError: '&ngVideoError' }, - link: function (scope, element, attrs) { + link: function(scope, element, attrs) { window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL; navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; @@ -37,18 +37,18 @@ if (require) { var context = canvas.getContext('2d'); var stopScan; - var scan = function () { + var scan = function() { if ($window.localMediaStream) { - context.drawImage(video, 0, 0, 307, 250); + context.drawImage(video, 0, 0, 307,250); try { qrcode.decode(); - } catch (e) { - scope.ngError({ error: e }); + } catch(e) { + scope.ngError({error: e}); } } } - var successCallback = function (stream) { + var successCallback = function(stream) { video.src = (window.URL && window.URL.createObjectURL(stream)) || stream; $window.localMediaStream = stream; @@ -68,18 +68,18 @@ if (require) { } }; - navigator.getUserMedia(constraint, successCallback, function (e) { - scope.ngVideoError({ error: e }); + navigator.getUserMedia(constraint, successCallback, function(e) { + scope.ngVideoError({error: e}); }); } else { - scope.ngVideoError({ error: 'Native web camera streaming (getUserMedia) not supported in this browser.' }); + scope.ngVideoError({error: 'Native web camera streaming (getUserMedia) not supported in this browser.'}); } - qrcode.callback = function (data) { - scope.ngSuccess({ data: data }); + qrcode.callback = function(data) { + scope.ngSuccess({data: data}); }; - element.bind('$destroy', function () { + element.bind('$destroy', function() { if ($window.localMediaStream) { $window.localMediaStream.getVideoTracks()[0].stop(); } From 8d1dd1a71ea7baadec67995fa2f58006f85eb713 Mon Sep 17 00:00:00 2001 From: Cynni Jong Date: Tue, 8 May 2018 17:35:08 +0800 Subject: [PATCH 3/4] Improve performance --- qr-scanner.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qr-scanner.js b/qr-scanner.js index 730e4c4..05f1a2e 100644 --- a/qr-scanner.js +++ b/qr-scanner.js @@ -6,7 +6,7 @@ if (require){ (function() { 'use strict'; - angular.module('qrScanner', ["ng"]).directive('qrScanner', ['$interval', '$window', '$timeout', function($interval, $window, $timeout) { + angular.module('qrScanner', ["ng"]).directive('qrScanner', ['$interval', '$window', function($interval, $window) { return { restrict: 'E', scope: { @@ -25,7 +25,9 @@ if (require){ var video = $window.document.createElement('video'); video.setAttribute('width', width); video.setAttribute('height', height); + video.setAttribute('autoplay', true); video.setAttribute('style', '-moz-transform:rotateY(-180deg);-webkit-transform:rotateY(-180deg);transform:rotateY(-180deg);'); + var canvas = $window.document.createElement('canvas'); canvas.setAttribute('id', 'qr-canvas'); canvas.setAttribute('width', width); @@ -49,15 +51,13 @@ if (require){ } var successCallback = function(stream) { - video.src = (window.URL && window.URL.createObjectURL(stream)) || stream; + video.srcObject = stream; $window.localMediaStream = stream; scope.video = video; - $timeout(function () { - video.play(); - stopScan = $interval(scan, 500); - }); + video.play(); + stopScan = $interval(scan, 500); } // Call the getUserMedia method with our callback functions From 779c211df13776eae8c58419add5d3814a1048e2 Mon Sep 17 00:00:00 2001 From: Cynni Jong Date: Tue, 8 May 2018 18:50:03 +0800 Subject: [PATCH 4/4] remove require --- qr-scanner.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/qr-scanner.js b/qr-scanner.js index 05f1a2e..29145ec 100644 --- a/qr-scanner.js +++ b/qr-scanner.js @@ -1,8 +1,3 @@ -if (require){ - if (!angular) var angular = require('angular'); - if (!qrcode) var qrcode = require('jsqrcode'); -} - (function() { 'use strict';