jpeg_camera 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.md +21 -0
- data/README.md +146 -0
- data/lib/jpeg_camera.rb +6 -0
- data/lib/jpeg_camera/version.rb +8 -0
- data/vendor/assets/audios/jpeg_camera/shutter.mp3 +0 -0
- data/vendor/assets/images/jpeg_camera/jpeg_camera.swf +0 -0
- data/vendor/assets/javascripts/jpeg_camera/canvas-to-blob.js +95 -0
- data/vendor/assets/javascripts/jpeg_camera/canvas-to-blob.min.js +1 -0
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera.js +736 -0
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera.min.js +4 -0
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera_no_flash.js +616 -0
- data/vendor/assets/javascripts/jpeg_camera/jpeg_camera_no_flash.min.js +4 -0
- data/vendor/assets/javascripts/jpeg_camera/swfobject.js +777 -0
- data/vendor/assets/javascripts/jpeg_camera/swfobject.min.js +4 -0
- metadata +72 -0
@@ -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);
|