jpeg_camera 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ /*! JpegCamera 1.0.0 | 2013-07-29
2
+ (c) 2013 Adam Wrobel
3
+ http://amw.github.io/jpeg_camera */
4
+ !function(){var a,b,c,d,e,f,g,h={}.hasOwnProperty,i=function(a,b){function c(){this.constructor=a}for(var d in b)h.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};a=function(){function a(a,b){if(this.container="string"==typeof a?document.querySelector(a):a,!this.container||!this.container.offsetWidth)throw"JpegCamera: invalid container";this.container.innerHTML="",this.options=this._extend({},this.constructor.DefaultOptions,b),this._engine_init()}return a.DefaultOptions={shutter_url:"/jpeg_camera/shutter.mp3",swf_url:"/jpeg_camera/jpeg_camera.swf",on_debug:function(a){return console&&console.log?console.log("JpegCamera: "+a):void 0},quality:.9,shutter:!0,mirror:!1,timeout:0},a.prototype.ready=function(a){return this.options.on_ready=a,this.options.on_ready&&this._is_ready&&this.options.on_ready.call(this),this},a.prototype._is_ready=!1,a.prototype.error=function(a){return this.options.on_error=a,this.options.on_error&&this._error_occured&&this.options.on_error.call(this,this._error_occured),this},a.prototype._error_occured=!1,a.prototype.capture=function(a){var b,c;return null==a&&(a={}),b=new d(this,a),this._snapshots[b.id]=b,c=b._options(),c.shutter&&this._engine_play_shutter_sound(),this._engine_capture(b,c.mirror,c.quality),b},a.prototype._snapshots={},a.prototype.show_stream=function(){return this._engine_show_stream(),this._displayed_snapshot=null,this},a.prototype.discard_all=function(){var a,b,c;this._displayed_snapshot&&this.show_stream(),c=this._snapshots;for(a in c)b=c[a],this._engine_discard(b),b._discarded=!0;return this._snapshots={},this},a.prototype._extend=function(a){var b,c,d,e,f,g;for(d=Array.prototype.slice.call(arguments,1),f=0,g=d.length;g>f;f++)if(c=d[f])for(b in c)e=c[b],a[b]=e;return a},a.prototype._debug=function(a){return this.options.on_debug?this.options.on_debug.call(this,a):void 0},a.prototype._view_width=function(){return parseInt(this.container.offsetWidth,10)},a.prototype._view_height=function(){return parseInt(this.container.offsetHeight,10)},a.prototype._display=function(a){return this._engine_display(a),this._displayed_snapshot=a},a.prototype._displayed_snapshot=null,a.prototype._upload=function(a,b,c,d){return this._engine_upload(a,b,c,d)},a.prototype._discard=function(a){return this._displayed_snapshot===a&&this.show_stream(),this._engine_discard(a),a._discarded=!0,delete this._snapshots[a.id]},a.prototype._prepared=function(){return this._is_ready=!0,this.options.on_ready?this.options.on_ready.call(this):void 0},a.prototype._got_error=function(a){return this._debug("Error - "+a),this._error_occured=a,this.options.on_error?this.options.on_error.call(this,this._error_occured):void 0},a}(),navigator.getUserMedia||(navigator.getUserMedia=navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia),navigator.getUserMedia&&(c=function(a){function b(){return f=b.__super__.constructor.apply(this,arguments)}return i(b,a),b.prototype._engine_init=function(){var a,b,c,d;return this._debug("Using HTML5 engine"),this.internal_container=document.createElement("div"),this.internal_container.style.width="100%",this.internal_container.style.height="100%",this.internal_container.style.position="relative",this.container.appendChild(this.internal_container),d=Math.floor(.2*this._view_height()),b=Math.floor(.2*this._view_width()),this.message=document.createElement("div"),this.message["class"]="message",this.message.style.width="100%",this.message.style.height="100%",this._add_prefixed_style(this.message,"boxSizing","border-box"),this.message.style.overflow="hidden",this.message.style.textAlign="center",this.message.style.paddingTop=""+d+"px",this.message.style.paddingBottom=""+d+"px",this.message.style.paddingLeft=""+b+"px",this.message.style.paddingRight=""+b+"px",this.message.style.position="absolute",this.message.style.zIndex=3,this.message.innerHTML="Please allow camera access when prompted by the browser.",this.internal_container.appendChild(this.message),this.video_container=document.createElement("div"),this.video_container.style.width=""+this._view_width()+"px",this.video_container.style.height=""+this._view_height()+"px",this.video_container.style.overflow="hidden",this.video_container.style.position="absolute",this.video_container.style.zIndex=1,this.internal_container.appendChild(this.video_container),this.video=document.createElement("video"),this.video.autoplay=!0,this._add_prefixed_style(this.video,"transform","scalex(-1.0)"),window.AudioContext||(window.AudioContext=window.webkitAudioContext),window.AudioContext&&this._load_shutter_sound(),a={video:{optional:[{minWidth:1280},{minWidth:640},{minWidth:480},{minWidth:360}]}},c=this,navigator.getUserMedia(a,function(a){return c._remove_message(),c.video.src=window.URL?URL.createObjectURL(a):a,c._wait_for_video_ready()},function(a){var b,d,e;b=a.code;for(d in a)if(e=a[d],"code"!==d)return c._got_error(d),void 0;return c._got_error("UNKNOWN ERROR")})},b.prototype._engine_play_shutter_sound=function(){var a;if(this.shutter_buffer)return a=this.audio_context.createBufferSource(),a.buffer=this.shutter_buffer,a.connect(this.audio_context.destination),a.start(0)},b.prototype._engine_capture=function(a,b,c){var d,e,f;return f=this._get_capture_crop(),d=document.createElement("canvas"),d.width=f.width,d.height=f.height,e=d.getContext("2d"),e.drawImage(this.video,f.x_offset,f.y_offset,f.width,f.height,0,0,f.width,f.height),a._canvas=d,a._mirror=b,a._quality=c},b.prototype._engine_display=function(a){return this.displayed_canvas&&this.internal_container.removeChild(this.displayed_canvas),this.displayed_canvas=a._canvas,this.displayed_canvas.style.width=""+this._view_width()+"px",this.displayed_canvas.style.height=""+this._view_height()+"px",this.displayed_canvas.style.top=0,this.displayed_canvas.style.left=0,this.displayed_canvas.style.position="absolute",this.displayed_canvas.style.zIndex=2,this._add_prefixed_style(this.displayed_canvas,"transform","scalex(-1.0)"),this.internal_container.appendChild(this.displayed_canvas)},b.prototype._engine_discard=function(a){return a._xhr&&a._xhr.abort(),delete a._xhr,delete a._canvas,delete a._jpeg_blob},b.prototype._engine_show_stream=function(){return this.displayed_canvas&&(this.internal_container.removeChild(this.displayed_canvas),this.displayed_canvas=null),this.video_container.style.display="block"},b.prototype._engine_upload=function(a,b,c,d){var e,f,g,h,i;return h=this,a._jpeg_blob?(this._debug("Uploading the file"),g=function(b){return delete a._xhr,a._status=b.target.status,a._response=b.target.responseText,a._status>=200&&a._status<300?a._upload_done():(a._error_message=b.target.statusText||"Unknown error",a._upload_fail())},i=new XMLHttpRequest,i.open("POST",b),i.timeout=d,c&&i.setRequestHeader("X-CSRF-Token",c),i.onload=g,i.onerror=g,i.onabort=g,i.send(a._jpeg_blob),a._xhr=i):(this._debug("Generating JPEG file"),a._mirror?(e=document.createElement("canvas"),e.width=a._canvas.width,e.height=a._canvas.height,f=e.getContext("2d"),f.setTransform(1,0,0,1,0,0),f.translate(e.width,0),f.scale(-1,1),f.drawImage(a._canvas,0,0)):e=a._canvas,e.toBlob(function(e){return a._jpeg_blob=e,h._engine_upload(a,b,c,d)},"image/jpeg",this.quality))},b.prototype._remove_message=function(){return this.message.style.display="none"},b.prototype._load_shutter_sound=function(){var a,b;if(!this.audio_context)return this.audio_context=new AudioContext,a=new XMLHttpRequest,a.open("GET",this.options.shutter_url,!0),a.responseType="arraybuffer",b=this,a.onload=function(){return b.audio_context.decodeAudioData(a.response,function(a){return b.shutter_buffer=a})},a.send()},b.prototype._wait_for_video_ready=function(){var a,b,c,d;return d=parseInt(this.video.videoWidth),c=parseInt(this.video.videoHeight),d>0&&c>0?(this.video_container.appendChild(this.video),this.video_width=d,this.video_height=c,this._debug("Camera resolution "+this.video_width+"x"+this.video_height+"px"),a=this._get_video_crop(),this.video.style.position="relative",this.video.style.width=""+a.width+"px",this.video.style.height=""+a.height+"px",this.video.style.left=""+a.x_offset+"px",this.video.style.top=""+a.y_offset+"px",this._prepared()):this._status_checks_count>100?this._got_error("Camera failed to initialize in 10 seconds"):(this._status_checks_count++,b=this,setTimeout(function(){return b._wait_for_video_ready()},100))},b.prototype._status_checks_count=0,b.prototype._add_prefixed_style=function(a,b,c){var d;return d=b.charAt(0).toUpperCase()+b.slice(1),a.style[b]=c,a.style["Webkit"+d]=c,a.style["Moz"+d]=c,a.style["ms"+d]=c,a.style["O"+d]=c},b.prototype._get_video_crop=function(){var a,b,c,d,e,f,g;return g=this._view_width(),e=this._view_height(),c=this.video_width/this.video_height,f=g/e,c>=f?(this._debug("Filling height"),d=e/this.video_height,b=Math.round(this.video_width*d),{width:b,height:e,x_offset:-Math.floor((b-g)/2),y_offset:0}):(this._debug("Filling width"),d=g/this.video_width,a=Math.round(this.video_height*d),{width:g,height:a,x_offset:0,y_offset:-Math.floor((a-e)/2)})},b.prototype._get_capture_crop=function(){var a,b,c,d,e,f;return f=this._view_width(),d=this._view_height(),c=this.video_width/this.video_height,e=f/d,c>=e?(b=Math.round(this.video_height*e),{width:b,height:this.video_height,x_offset:Math.floor((this.video_width-b)/2),y_offset:0}):(a=Math.round(this.video_width/e),{width:this.video_width,height:a,x_offset:0,y_offset:Math.floor((this.video_height-a)/2)})},b}(a),window.JpegCamera=c),e="9",!window.JpegCamera&&window.swfobject&&swfobject.hasFlashPlayerVersion(e)&&(b=function(a){function b(){return g=b.__super__.constructor.apply(this,arguments)}return i(b,a),b._send_message=function(a,b){var c,d;return(d=this._instances[parseInt(a)])?(c=Array.prototype.slice.call(arguments,2),this.prototype[b].apply(d,c)):void 0},b._instances={},b._next_id=1,b.prototype._engine_init=function(){var a,b,c,d,e,f,g,h;return this._debug("Using Flash engine"),this._id=this.constructor._next_id++,this.constructor._instances[this._id]=this,h=this._view_width(),e=this._view_height(),215>h||138>e?(this._got_error("camera is too small to display privacy dialog"),void 0):(c="flash_object_"+this._id,f={loop:"false",allowScriptAccess:"always",allowFullScreen:"false",quality:"best",wmode:"opaque",menu:"false"},a={id:c,align:"middle"},d={id:this._id,width:h,height:e,shutter_url:this.options.shutter_url},g=this,b=function(a){return a.success?(g._debug("Flash loaded"),g._flash=document.getElementById(c)):g._got_error("Flash loading failed.")},this.internal_container=document.createElement("div"),this.internal_container.id="jpeg_camera_flash_"+this._id,this.internal_container.style.width="100%",this.internal_container.style.height="100%",this.container.appendChild(this.internal_container),swfobject.embedSWF(this.options.swf_url,this.internal_container.id,h,e,"9",null,d,f,a,b))},b.prototype._engine_play_shutter_sound=function(){return this._flash._play_shutter()},b.prototype._engine_capture=function(a,b,c){return this._flash._capture(a.id,b,c)},b.prototype._engine_display=function(a){return this._flash._display(a.id)},b.prototype._engine_discard=function(a){return this._flash._discard(a.id)},b.prototype._engine_show_stream=function(){return this._flash._show_stream()},b.prototype._engine_upload=function(a,b,c,d){return this._flash._upload(a.id,b,c,d)},b.prototype._flash_prepared=function(){return this._prepared()},b.prototype._flash_upload_complete=function(a,b,c,d){var e;return a=parseInt(a),e=this._snapshots[a],e._status=parseInt(b),e._response=d,e._status>=200&&e._status<300?e._upload_done():(e._error_message=c,e._upload_fail())},b}(a),window.JpegCamera=b),d=function(){function a(a,b){this.camera=a,this.options=b,this.id=this.constructor._next_snapshot_id++}return a._next_snapshot_id=1,a.prototype._discarded=!1,a.prototype.show=function(){return this._discarded&&raise("discarded snapshot cannot be used"),this.camera._display(this),this},a.prototype.hide=function(){return this.camera.displayed_snapshot()===this&&this.camera.show_stream(),this},a.prototype.upload=function(a){var b,c;if(null==a&&(a={}),this._discarded&&raise("discarded snapshot cannot be used"),this._uploading)return this._debug("Upload already in progress"),void 0;if(this._uploading=!0,this._upload_options=a,b=this._options(),!b.api_url)throw this.camera._debug("Snapshot#upload called without valid api_url"),"Snapshot#upload called without valid api_url";return c="string"==typeof b.csrf_token&&b.csrf_token.length>0?b.csrf_token:null,this._done=!1,this._response=null,this._fail=!1,this._status=null,this._error_message=null,this.camera._upload(this,b.api_url,c,b.timeout),this},a.prototype._upload_options={},a.prototype._uploading=!1,a.prototype.done=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_done=a,b=this._options(),b.on_upload_done&&this._done&&b.on_upload_done.call(this,this._response),this},a.prototype._done=!1,a.prototype._response=null,a.prototype.fail=function(a){var b;return this._discarded&&raise("discarded snapshot cannot be used"),this._upload_options.on_upload_fail=a,b=this._options(),b.on_upload_fail&&this._fail&&b.on_upload_fail.call(this,this._status,this._error_message,this._response),this},a.prototype._fail=!1,a.prototype._status=null,a.prototype._error_message=null,a.prototype.discard=function(){return this.camera._discard(this),void 0},a.prototype._options=function(){return this.camera._extend({},this.camera.options,this.options,this._upload_options)},a.prototype._upload_done=function(){var a;return this.camera._debug("Upload completed"),this._uploading=!1,this._done=!0,a=this._options(),a.on_upload_done?a.on_upload_done.call(this,this._response):void 0},a.prototype._upload_fail=function(){var a;return this.camera._debug("Upload failed with status "+this._status),this._uploading=!1,this._fail=!0,a=this._options(),a.on_upload_fail?a.on_upload_fail.call(this,this._status,this._error_message,this._response):void 0},a}()}.call(this);
@@ -0,0 +1,616 @@
1
+ /*! JpegCamera 1.0.0 | 2013-07-29
2
+ (c) 2013 Adam Wrobel
3
+ http://amw.github.io/jpeg_camera */
4
+ (function() {
5
+ var JpegCamera, JpegCameraHtml5, Snapshot, _ref,
6
+ __hasProp = {}.hasOwnProperty,
7
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
8
+
9
+ JpegCamera = (function() {
10
+ JpegCamera.DefaultOptions = {
11
+ shutter_url: "/jpeg_camera/shutter.mp3",
12
+ swf_url: "/jpeg_camera/jpeg_camera.swf",
13
+ on_debug: function(message) {
14
+ if (console && console.log) {
15
+ return console.log("JpegCamera: " + message);
16
+ }
17
+ },
18
+ quality: 0.9,
19
+ shutter: true,
20
+ mirror: false,
21
+ timeout: 0
22
+ };
23
+
24
+ function JpegCamera(container, options) {
25
+ if ("string" === typeof container) {
26
+ this.container = document.querySelector(container);
27
+ } else {
28
+ this.container = container;
29
+ }
30
+ if (!(this.container && this.container.offsetWidth)) {
31
+ throw "JpegCamera: invalid container";
32
+ }
33
+ this.container.innerHTML = "";
34
+ this.options = this._extend({}, this.constructor.DefaultOptions, options);
35
+ this._engine_init();
36
+ }
37
+
38
+ JpegCamera.prototype.ready = function(callback) {
39
+ this.options.on_ready = callback;
40
+ if (this.options.on_ready && this._is_ready) {
41
+ this.options.on_ready.call(this);
42
+ }
43
+ return this;
44
+ };
45
+
46
+ JpegCamera.prototype._is_ready = false;
47
+
48
+ JpegCamera.prototype.error = function(callback) {
49
+ this.options.on_error = callback;
50
+ if (this.options.on_error && this._error_occured) {
51
+ this.options.on_error.call(this, this._error_occured);
52
+ }
53
+ return this;
54
+ };
55
+
56
+ JpegCamera.prototype._error_occured = false;
57
+
58
+ JpegCamera.prototype.capture = function(options) {
59
+ var snapshot, _options;
60
+ if (options == null) {
61
+ options = {};
62
+ }
63
+ snapshot = new Snapshot(this, options);
64
+ this._snapshots[snapshot.id] = snapshot;
65
+ _options = snapshot._options();
66
+ if (_options.shutter) {
67
+ this._engine_play_shutter_sound();
68
+ }
69
+ this._engine_capture(snapshot, _options.mirror, _options.quality);
70
+ return snapshot;
71
+ };
72
+
73
+ JpegCamera.prototype._snapshots = {};
74
+
75
+ JpegCamera.prototype.show_stream = function() {
76
+ this._engine_show_stream();
77
+ this._displayed_snapshot = null;
78
+ return this;
79
+ };
80
+
81
+ JpegCamera.prototype.discard_all = function() {
82
+ var id, snapshot, _ref;
83
+ if (this._displayed_snapshot) {
84
+ this.show_stream();
85
+ }
86
+ _ref = this._snapshots;
87
+ for (id in _ref) {
88
+ snapshot = _ref[id];
89
+ this._engine_discard(snapshot);
90
+ snapshot._discarded = true;
91
+ }
92
+ this._snapshots = {};
93
+ return this;
94
+ };
95
+
96
+ JpegCamera.prototype._extend = function(object) {
97
+ var key, source, sources, value, _i, _len;
98
+ sources = Array.prototype.slice.call(arguments, 1);
99
+ for (_i = 0, _len = sources.length; _i < _len; _i++) {
100
+ source = sources[_i];
101
+ if (source) {
102
+ for (key in source) {
103
+ value = source[key];
104
+ object[key] = value;
105
+ }
106
+ }
107
+ }
108
+ return object;
109
+ };
110
+
111
+ JpegCamera.prototype._debug = function(message) {
112
+ if (this.options.on_debug) {
113
+ return this.options.on_debug.call(this, message);
114
+ }
115
+ };
116
+
117
+ JpegCamera.prototype._view_width = function() {
118
+ return parseInt(this.container.offsetWidth, 10);
119
+ };
120
+
121
+ JpegCamera.prototype._view_height = function() {
122
+ return parseInt(this.container.offsetHeight, 10);
123
+ };
124
+
125
+ JpegCamera.prototype._display = function(snapshot) {
126
+ this._engine_display(snapshot);
127
+ return this._displayed_snapshot = snapshot;
128
+ };
129
+
130
+ JpegCamera.prototype._displayed_snapshot = null;
131
+
132
+ JpegCamera.prototype._upload = function(snapshot, api_url, csrf_token, timeout) {
133
+ return this._engine_upload(snapshot, api_url, csrf_token, timeout);
134
+ };
135
+
136
+ JpegCamera.prototype._discard = function(snapshot) {
137
+ if (this._displayed_snapshot === snapshot) {
138
+ this.show_stream();
139
+ }
140
+ this._engine_discard(snapshot);
141
+ snapshot._discarded = true;
142
+ return delete this._snapshots[snapshot.id];
143
+ };
144
+
145
+ JpegCamera.prototype._prepared = function() {
146
+ this._is_ready = true;
147
+ if (this.options.on_ready) {
148
+ return this.options.on_ready.call(this);
149
+ }
150
+ };
151
+
152
+ JpegCamera.prototype._got_error = function(error) {
153
+ this._debug("Error - " + error);
154
+ this._error_occured = error;
155
+ if (this.options.on_error) {
156
+ return this.options.on_error.call(this, this._error_occured);
157
+ }
158
+ };
159
+
160
+ return JpegCamera;
161
+
162
+ })();
163
+
164
+ navigator.getUserMedia || (navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);
165
+
166
+ if (navigator.getUserMedia) {
167
+ JpegCameraHtml5 = (function(_super) {
168
+ __extends(JpegCameraHtml5, _super);
169
+
170
+ function JpegCameraHtml5() {
171
+ _ref = JpegCameraHtml5.__super__.constructor.apply(this, arguments);
172
+ return _ref;
173
+ }
174
+
175
+ JpegCameraHtml5.prototype._engine_init = function() {
176
+ var get_user_media_options, horizontal_padding, that, vertical_padding;
177
+ this._debug("Using HTML5 engine");
178
+ this.internal_container = document.createElement("div");
179
+ this.internal_container.style.width = "100%";
180
+ this.internal_container.style.height = "100%";
181
+ this.internal_container.style.position = "relative";
182
+ this.container.appendChild(this.internal_container);
183
+ vertical_padding = Math.floor(this._view_height() * 0.2);
184
+ horizontal_padding = Math.floor(this._view_width() * 0.2);
185
+ this.message = document.createElement("div");
186
+ this.message["class"] = "message";
187
+ this.message.style.width = "100%";
188
+ this.message.style.height = "100%";
189
+ this._add_prefixed_style(this.message, "boxSizing", "border-box");
190
+ this.message.style.overflow = "hidden";
191
+ this.message.style.textAlign = "center";
192
+ this.message.style.paddingTop = "" + vertical_padding + "px";
193
+ this.message.style.paddingBottom = "" + vertical_padding + "px";
194
+ this.message.style.paddingLeft = "" + horizontal_padding + "px";
195
+ this.message.style.paddingRight = "" + horizontal_padding + "px";
196
+ this.message.style.position = "absolute";
197
+ this.message.style.zIndex = 3;
198
+ this.message.innerHTML = "Please allow camera access when prompted by the browser.";
199
+ this.internal_container.appendChild(this.message);
200
+ this.video_container = document.createElement("div");
201
+ this.video_container.style.width = "" + (this._view_width()) + "px";
202
+ this.video_container.style.height = "" + (this._view_height()) + "px";
203
+ this.video_container.style.overflow = "hidden";
204
+ this.video_container.style.position = "absolute";
205
+ this.video_container.style.zIndex = 1;
206
+ this.internal_container.appendChild(this.video_container);
207
+ this.video = document.createElement('video');
208
+ this.video.autoplay = true;
209
+ this._add_prefixed_style(this.video, "transform", "scalex(-1.0)");
210
+ window.AudioContext || (window.AudioContext = window.webkitAudioContext);
211
+ if (window.AudioContext) {
212
+ this._load_shutter_sound();
213
+ }
214
+ get_user_media_options = {
215
+ video: {
216
+ optional: [
217
+ {
218
+ minWidth: 1280
219
+ }, {
220
+ minWidth: 640
221
+ }, {
222
+ minWidth: 480
223
+ }, {
224
+ minWidth: 360
225
+ }
226
+ ]
227
+ }
228
+ };
229
+ that = this;
230
+ return navigator.getUserMedia(get_user_media_options, function(stream) {
231
+ that._remove_message();
232
+ if (window.URL) {
233
+ that.video.src = URL.createObjectURL(stream);
234
+ } else {
235
+ that.video.src = stream;
236
+ }
237
+ return that._wait_for_video_ready();
238
+ }, function(error) {
239
+ var code, key, value;
240
+ code = error.code;
241
+ for (key in error) {
242
+ value = error[key];
243
+ if (key === "code") {
244
+ continue;
245
+ }
246
+ that._got_error(key);
247
+ return;
248
+ }
249
+ return that._got_error("UNKNOWN ERROR");
250
+ });
251
+ };
252
+
253
+ JpegCameraHtml5.prototype._engine_play_shutter_sound = function() {
254
+ var source;
255
+ if (!this.shutter_buffer) {
256
+ return;
257
+ }
258
+ source = this.audio_context.createBufferSource();
259
+ source.buffer = this.shutter_buffer;
260
+ source.connect(this.audio_context.destination);
261
+ return source.start(0);
262
+ };
263
+
264
+ JpegCameraHtml5.prototype._engine_capture = function(snapshot, mirror, quality) {
265
+ var canvas, context, crop;
266
+ crop = this._get_capture_crop();
267
+ canvas = document.createElement("canvas");
268
+ canvas.width = crop.width;
269
+ canvas.height = crop.height;
270
+ context = canvas.getContext("2d");
271
+ context.drawImage(this.video, crop.x_offset, crop.y_offset, crop.width, crop.height, 0, 0, crop.width, crop.height);
272
+ snapshot._canvas = canvas;
273
+ snapshot._mirror = mirror;
274
+ return snapshot._quality = quality;
275
+ };
276
+
277
+ JpegCameraHtml5.prototype._engine_display = function(snapshot) {
278
+ if (this.displayed_canvas) {
279
+ this.internal_container.removeChild(this.displayed_canvas);
280
+ }
281
+ this.displayed_canvas = snapshot._canvas;
282
+ this.displayed_canvas.style.width = "" + (this._view_width()) + "px";
283
+ this.displayed_canvas.style.height = "" + (this._view_height()) + "px";
284
+ this.displayed_canvas.style.top = 0;
285
+ this.displayed_canvas.style.left = 0;
286
+ this.displayed_canvas.style.position = "absolute";
287
+ this.displayed_canvas.style.zIndex = 2;
288
+ this._add_prefixed_style(this.displayed_canvas, "transform", "scalex(-1.0)");
289
+ return this.internal_container.appendChild(this.displayed_canvas);
290
+ };
291
+
292
+ JpegCameraHtml5.prototype._engine_discard = function(snapshot) {
293
+ if (snapshot._xhr) {
294
+ snapshot._xhr.abort();
295
+ }
296
+ delete snapshot._xhr;
297
+ delete snapshot._canvas;
298
+ return delete snapshot._jpeg_blob;
299
+ };
300
+
301
+ JpegCameraHtml5.prototype._engine_show_stream = function() {
302
+ if (this.displayed_canvas) {
303
+ this.internal_container.removeChild(this.displayed_canvas);
304
+ this.displayed_canvas = null;
305
+ }
306
+ return this.video_container.style.display = "block";
307
+ };
308
+
309
+ JpegCameraHtml5.prototype._engine_upload = function(snapshot, api_url, csrf_token, timeout) {
310
+ var canvas, context, handler, that, xhr;
311
+ that = this;
312
+ if (snapshot._jpeg_blob) {
313
+ this._debug("Uploading the file");
314
+ handler = function(event) {
315
+ delete snapshot._xhr;
316
+ snapshot._status = event.target.status;
317
+ snapshot._response = event.target.responseText;
318
+ if (snapshot._status >= 200 && snapshot._status < 300) {
319
+ return snapshot._upload_done();
320
+ } else {
321
+ snapshot._error_message = event.target.statusText || "Unknown error";
322
+ return snapshot._upload_fail();
323
+ }
324
+ };
325
+ xhr = new XMLHttpRequest();
326
+ xhr.open('POST', api_url);
327
+ xhr.timeout = timeout;
328
+ if (csrf_token) {
329
+ xhr.setRequestHeader("X-CSRF-Token", csrf_token);
330
+ }
331
+ xhr.onload = handler;
332
+ xhr.onerror = handler;
333
+ xhr.onabort = handler;
334
+ xhr.send(snapshot._jpeg_blob);
335
+ return snapshot._xhr = xhr;
336
+ } else {
337
+ this._debug("Generating JPEG file");
338
+ if (snapshot._mirror) {
339
+ canvas = document.createElement("canvas");
340
+ canvas.width = snapshot._canvas.width;
341
+ canvas.height = snapshot._canvas.height;
342
+ context = canvas.getContext("2d");
343
+ context.setTransform(1, 0, 0, 1, 0, 0);
344
+ context.translate(canvas.width, 0);
345
+ context.scale(-1, 1);
346
+ context.drawImage(snapshot._canvas, 0, 0);
347
+ } else {
348
+ canvas = snapshot._canvas;
349
+ }
350
+ return canvas.toBlob(function(blob) {
351
+ snapshot._jpeg_blob = blob;
352
+ return that._engine_upload(snapshot, api_url, csrf_token, timeout);
353
+ }, "image/jpeg", this.quality);
354
+ }
355
+ };
356
+
357
+ JpegCameraHtml5.prototype._remove_message = function() {
358
+ return this.message.style.display = "none";
359
+ };
360
+
361
+ JpegCameraHtml5.prototype._load_shutter_sound = function() {
362
+ var request, that;
363
+ if (this.audio_context) {
364
+ return;
365
+ }
366
+ this.audio_context = new AudioContext();
367
+ request = new XMLHttpRequest();
368
+ request.open('GET', this.options.shutter_url, true);
369
+ request.responseType = 'arraybuffer';
370
+ that = this;
371
+ request.onload = function() {
372
+ return that.audio_context.decodeAudioData(request.response, function(buffer) {
373
+ return that.shutter_buffer = buffer;
374
+ });
375
+ };
376
+ return request.send();
377
+ };
378
+
379
+ JpegCameraHtml5.prototype._wait_for_video_ready = function() {
380
+ var crop, that, video_height, video_width;
381
+ video_width = parseInt(this.video.videoWidth);
382
+ video_height = parseInt(this.video.videoHeight);
383
+ if (video_width > 0 && video_height > 0) {
384
+ this.video_container.appendChild(this.video);
385
+ this.video_width = video_width;
386
+ this.video_height = video_height;
387
+ this._debug("Camera resolution " + this.video_width + "x" + this.video_height + "px");
388
+ crop = this._get_video_crop();
389
+ this.video.style.position = "relative";
390
+ this.video.style.width = "" + crop.width + "px";
391
+ this.video.style.height = "" + crop.height + "px";
392
+ this.video.style.left = "" + crop.x_offset + "px";
393
+ this.video.style.top = "" + crop.y_offset + "px";
394
+ return this._prepared();
395
+ } else if (this._status_checks_count > 100) {
396
+ return this._got_error("Camera failed to initialize in 10 seconds");
397
+ } else {
398
+ this._status_checks_count++;
399
+ that = this;
400
+ return setTimeout((function() {
401
+ return that._wait_for_video_ready();
402
+ }), 100);
403
+ }
404
+ };
405
+
406
+ JpegCameraHtml5.prototype._status_checks_count = 0;
407
+
408
+ JpegCameraHtml5.prototype._add_prefixed_style = function(element, style, value) {
409
+ var uppercase_style;
410
+ uppercase_style = style.charAt(0).toUpperCase() + style.slice(1);
411
+ element.style[style] = value;
412
+ element.style["Webkit" + uppercase_style] = value;
413
+ element.style["Moz" + uppercase_style] = value;
414
+ element.style["ms" + uppercase_style] = value;
415
+ return element.style["O" + uppercase_style] = value;
416
+ };
417
+
418
+ JpegCameraHtml5.prototype._get_video_crop = function() {
419
+ var scaled_video_height, scaled_video_width, video_ratio, video_scale, view_height, view_ratio, view_width;
420
+ view_width = this._view_width();
421
+ view_height = this._view_height();
422
+ video_ratio = this.video_width / this.video_height;
423
+ view_ratio = view_width / view_height;
424
+ if (video_ratio >= view_ratio) {
425
+ this._debug("Filling height");
426
+ video_scale = view_height / this.video_height;
427
+ scaled_video_width = Math.round(this.video_width * video_scale);
428
+ return {
429
+ width: scaled_video_width,
430
+ height: view_height,
431
+ x_offset: -Math.floor((scaled_video_width - view_width) / 2.0),
432
+ y_offset: 0
433
+ };
434
+ } else {
435
+ this._debug("Filling width");
436
+ video_scale = view_width / this.video_width;
437
+ scaled_video_height = Math.round(this.video_height * video_scale);
438
+ return {
439
+ width: view_width,
440
+ height: scaled_video_height,
441
+ x_offset: 0,
442
+ y_offset: -Math.floor((scaled_video_height - view_height) / 2.0)
443
+ };
444
+ }
445
+ };
446
+
447
+ JpegCameraHtml5.prototype._get_capture_crop = function() {
448
+ var snapshot_height, snapshot_width, video_ratio, view_height, view_ratio, view_width;
449
+ view_width = this._view_width();
450
+ view_height = this._view_height();
451
+ video_ratio = this.video_width / this.video_height;
452
+ view_ratio = view_width / view_height;
453
+ if (video_ratio >= view_ratio) {
454
+ snapshot_width = Math.round(this.video_height * view_ratio);
455
+ return {
456
+ width: snapshot_width,
457
+ height: this.video_height,
458
+ x_offset: Math.floor((this.video_width - snapshot_width) / 2.0),
459
+ y_offset: 0
460
+ };
461
+ } else {
462
+ snapshot_height = Math.round(this.video_width / view_ratio);
463
+ return {
464
+ width: this.video_width,
465
+ height: snapshot_height,
466
+ x_offset: 0,
467
+ y_offset: Math.floor((this.video_height - snapshot_height) / 2.0)
468
+ };
469
+ }
470
+ };
471
+
472
+ return JpegCameraHtml5;
473
+
474
+ })(JpegCamera);
475
+ ({
476
+ video_width: null,
477
+ video_height: null
478
+ });
479
+ window.JpegCamera = JpegCameraHtml5;
480
+ }
481
+
482
+ Snapshot = (function() {
483
+ Snapshot._next_snapshot_id = 1;
484
+
485
+ function Snapshot(camera, options) {
486
+ this.camera = camera;
487
+ this.options = options;
488
+ this.id = this.constructor._next_snapshot_id++;
489
+ }
490
+
491
+ Snapshot.prototype._discarded = false;
492
+
493
+ Snapshot.prototype.show = function() {
494
+ if (this._discarded) {
495
+ raise("discarded snapshot cannot be used");
496
+ }
497
+ this.camera._display(this);
498
+ return this;
499
+ };
500
+
501
+ Snapshot.prototype.hide = function() {
502
+ if (this.camera.displayed_snapshot() === this) {
503
+ this.camera.show_stream();
504
+ }
505
+ return this;
506
+ };
507
+
508
+ Snapshot.prototype.upload = function(options) {
509
+ var cache, csrf_token;
510
+ if (options == null) {
511
+ options = {};
512
+ }
513
+ if (this._discarded) {
514
+ raise("discarded snapshot cannot be used");
515
+ }
516
+ if (this._uploading) {
517
+ this._debug("Upload already in progress");
518
+ return;
519
+ }
520
+ this._uploading = true;
521
+ this._upload_options = options;
522
+ cache = this._options();
523
+ if (!cache.api_url) {
524
+ this.camera._debug("Snapshot#upload called without valid api_url");
525
+ throw "Snapshot#upload called without valid api_url";
526
+ }
527
+ if ("string" === typeof cache.csrf_token && cache.csrf_token.length > 0) {
528
+ csrf_token = cache.csrf_token;
529
+ } else {
530
+ csrf_token = null;
531
+ }
532
+ this._done = false;
533
+ this._response = null;
534
+ this._fail = false;
535
+ this._status = null;
536
+ this._error_message = null;
537
+ this.camera._upload(this, cache.api_url, csrf_token, cache.timeout);
538
+ return this;
539
+ };
540
+
541
+ Snapshot.prototype._upload_options = {};
542
+
543
+ Snapshot.prototype._uploading = false;
544
+
545
+ Snapshot.prototype.done = function(callback) {
546
+ var cache;
547
+ if (this._discarded) {
548
+ raise("discarded snapshot cannot be used");
549
+ }
550
+ this._upload_options.on_upload_done = callback;
551
+ cache = this._options();
552
+ if (cache.on_upload_done && this._done) {
553
+ cache.on_upload_done.call(this, this._response);
554
+ }
555
+ return this;
556
+ };
557
+
558
+ Snapshot.prototype._done = false;
559
+
560
+ Snapshot.prototype._response = null;
561
+
562
+ Snapshot.prototype.fail = function(callback) {
563
+ var cache;
564
+ if (this._discarded) {
565
+ raise("discarded snapshot cannot be used");
566
+ }
567
+ this._upload_options.on_upload_fail = callback;
568
+ cache = this._options();
569
+ if (cache.on_upload_fail && this._fail) {
570
+ cache.on_upload_fail.call(this, this._status, this._error_message, this._response);
571
+ }
572
+ return this;
573
+ };
574
+
575
+ Snapshot.prototype._fail = false;
576
+
577
+ Snapshot.prototype._status = null;
578
+
579
+ Snapshot.prototype._error_message = null;
580
+
581
+ Snapshot.prototype.discard = function() {
582
+ this.camera._discard(this);
583
+ return void 0;
584
+ };
585
+
586
+ Snapshot.prototype._options = function() {
587
+ return this.camera._extend({}, this.camera.options, this.options, this._upload_options);
588
+ };
589
+
590
+ Snapshot.prototype._upload_done = function() {
591
+ var cache;
592
+ this.camera._debug("Upload completed");
593
+ this._uploading = false;
594
+ this._done = true;
595
+ cache = this._options();
596
+ if (cache.on_upload_done) {
597
+ return cache.on_upload_done.call(this, this._response);
598
+ }
599
+ };
600
+
601
+ Snapshot.prototype._upload_fail = function() {
602
+ var cache;
603
+ this.camera._debug("Upload failed with status " + this._status);
604
+ this._uploading = false;
605
+ this._fail = true;
606
+ cache = this._options();
607
+ if (cache.on_upload_fail) {
608
+ return cache.on_upload_fail.call(this, this._status, this._error_message, this._response);
609
+ }
610
+ };
611
+
612
+ return Snapshot;
613
+
614
+ })();
615
+
616
+ }).call(this);