Line 0
Link Here
|
|
|
1 |
/* global __ */ |
2 |
/* exported startup */ |
3 |
|
4 |
/* Adapted from Mozilla's article "Taking still photos with WebRTC" |
5 |
* https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Taking_still_photos |
6 |
*/ |
7 |
|
8 |
var width = 480; // We will scale the photo width to this |
9 |
var height = 0; // This will be computed based on the input stream |
10 |
|
11 |
// |streaming| indicates whether or not we're currently streaming |
12 |
// video from the camera. Obviously, we start at false. |
13 |
|
14 |
var streaming = false; |
15 |
|
16 |
// The various HTML elements we need to configure or control. These |
17 |
// will be set by the startup() function. |
18 |
|
19 |
var video = null; |
20 |
var canvas = null; |
21 |
var photo = null; |
22 |
var takebutton = null; |
23 |
var retakebutton = null; |
24 |
var downloadbutton = null; |
25 |
var savebutton = null; |
26 |
var output = null; |
27 |
var camera = null; |
28 |
var uploadfiletext = null; |
29 |
|
30 |
/** |
31 |
* Initiate the camera and add some click handlers |
32 |
*/ |
33 |
|
34 |
function startup() { |
35 |
video = document.getElementById('viewfinder'); |
36 |
canvas = document.getElementById('canvas'); |
37 |
photo = document.getElementById('photo'); |
38 |
takebutton = document.getElementById('takebutton'); |
39 |
retakebutton = document.getElementById('retakebutton'); |
40 |
downloadbutton = document.getElementById('downloadbutton'); |
41 |
savebutton = document.getElementById('savebutton'); |
42 |
output = document.getElementById("output"); |
43 |
camera = document.getElementById("camera"); |
44 |
uploadfiletext = document.getElementById("uploadfiletext"); |
45 |
|
46 |
navigator.mediaDevices.getUserMedia({ |
47 |
video: true, |
48 |
audio: false |
49 |
}) |
50 |
.then(function (stream) { |
51 |
video.srcObject = stream; |
52 |
video.play(); |
53 |
}) |
54 |
.catch(function (err) { |
55 |
$("#capture-patron-image").hide(); |
56 |
$("#camera-error").css("display", "flex"); |
57 |
$("#camera-error-message").text( showMediaErrors( err ) ); |
58 |
}); |
59 |
|
60 |
video.addEventListener('canplay', function () { |
61 |
if (!streaming) { |
62 |
height = video.videoHeight / (video.videoWidth / width); |
63 |
|
64 |
// Firefox currently has a bug where the height can't be read from |
65 |
// the video, so we will make assumptions if this happens. |
66 |
|
67 |
if (isNaN(height)) { |
68 |
height = width / (4 / 3); |
69 |
} |
70 |
|
71 |
video.setAttribute('width', width); |
72 |
video.setAttribute('height', height); |
73 |
canvas.setAttribute('width', width); |
74 |
canvas.setAttribute('height', height); |
75 |
photo.setAttribute('width', width); |
76 |
photo.setAttribute('height', height); |
77 |
streaming = true; |
78 |
} |
79 |
}, false); |
80 |
|
81 |
takebutton.addEventListener('click', function (ev) { |
82 |
takepicture(); |
83 |
ev.preventDefault(); |
84 |
}, false); |
85 |
|
86 |
retakebutton.addEventListener('click', function (ev) { |
87 |
ev.preventDefault(); |
88 |
retakephoto(); |
89 |
}, false); |
90 |
|
91 |
clearphoto(); |
92 |
} |
93 |
|
94 |
function showMediaErrors( err ){ |
95 |
// Example error: "NotAllowedError: Permission denied" |
96 |
var errorcode = err.toString().split(":"); |
97 |
var output; |
98 |
switch ( errorcode[0] ) { |
99 |
case "NotFoundError": |
100 |
case "DevicesNotFoundError": |
101 |
output = __("No camera detected."); |
102 |
break; |
103 |
case "NotReadableError": |
104 |
case "TrackStartError": |
105 |
output = __("Could not access camera."); |
106 |
break; |
107 |
case "NotAllowedError": |
108 |
case "PermissionDeniedError": |
109 |
output = __("Access to camera denied."); |
110 |
break; |
111 |
default: |
112 |
output = __("An unknown error occurred: ") + err; |
113 |
break; |
114 |
} |
115 |
return output; |
116 |
} |
117 |
|
118 |
/** |
119 |
* Clear anything passed to the canvas element and the corresponding image. |
120 |
*/ |
121 |
|
122 |
function clearphoto() { |
123 |
var context = canvas.getContext('2d'); |
124 |
context.fillStyle = "#AAA"; |
125 |
context.fillRect(0, 0, canvas.width, canvas.height); |
126 |
|
127 |
var data = canvas.toDataURL('image/jpeg', 1.0); |
128 |
photo.setAttribute('src', data); |
129 |
} |
130 |
|
131 |
/** |
132 |
* Reset the interface to hide download and save buttons. |
133 |
* Redisplay camera "shutter" button. |
134 |
*/ |
135 |
|
136 |
function retakephoto(){ |
137 |
downloadbutton.href= ""; |
138 |
downloadbutton.style.display = "none"; |
139 |
takebutton.style.display = "inline-block"; |
140 |
retakebutton.style.display = "none"; |
141 |
savebutton.style.display = "none"; |
142 |
output.style.display = "none"; |
143 |
photo.src = ""; |
144 |
camera.style.display = "block"; |
145 |
uploadfiletext.value = ""; |
146 |
} |
147 |
|
148 |
/** |
149 |
* Capture the data from the user's camera and write it to the canvas element. |
150 |
* The canvas data is converted to a data-url, and that URL set as the src |
151 |
* attribute of an image. |
152 |
* Display two controls for the captured photo: Download (to save to the |
153 |
* user's computer) and Upload (save to the patron's record in Koha). |
154 |
*/ |
155 |
|
156 |
function takepicture() { |
157 |
var context = canvas.getContext('2d'); |
158 |
var cardnumber = document.getElementById("cardnumber").value; |
159 |
camera.style.display = "none"; |
160 |
downloadbutton.style.display = ''; |
161 |
output.style.display = "block"; |
162 |
takebutton.style.display = "none"; |
163 |
retakebutton.style.display = "inline-block"; |
164 |
savebutton.style.display = "inline-block"; |
165 |
if (width && height) { |
166 |
canvas.width = width; |
167 |
canvas.height = height; |
168 |
context.drawImage(video, 0, 0, width, height); |
169 |
|
170 |
var data = canvas.toDataURL('image/jpeg', 1.0); |
171 |
photo.setAttribute('src', data); |
172 |
if( cardnumber !== '' ){ |
173 |
// Download a file which the patrons card number as its name |
174 |
downloadbutton.download = cardnumber + ".jpg"; |
175 |
} else { |
176 |
downloadbutton.download = "patron-photo.jpg"; |
177 |
} |
178 |
downloadbutton.href = data; |
179 |
uploadfiletext.value = data; |
180 |
|
181 |
} else { |
182 |
clearphoto(); |
183 |
} |
184 |
} |