|
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 |
} |