webcam.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. define(function(require) {
  2. var $ = require('jquery');
  3. var elgg = require('elgg');
  4. var options = {
  5. width: 480,
  6. height: 0
  7. };
  8. /**
  9. * Normalize the vendor-prefixed media objects
  10. *
  11. * @type @exp;navigator@pro;mozGetUserMedia|@exp;navigator@pro;webkitGetUserMedia|@exp;navigator@pro;msGetUserMedia|@exp;navigator@pro;getUserMedia
  12. */
  13. var getMedia = (
  14. navigator.getUserMedia ||
  15. navigator.webkitGetUserMedia ||
  16. navigator.mozGetUserMedia ||
  17. navigator.msGetUserMedia
  18. );
  19. var init = function() {
  20. // Make sure that registration form is able to send the image
  21. $(".elgg-form-register")
  22. .attr("enctype", "multipart/form-data")
  23. .attr("encoding", "multipart/form-data");
  24. $(document).on('click', '.avatar-tabs a', changeTab);
  25. $(document).on('submit', '.elgg-form-avatar-upload', submit);
  26. $(document).on('submit', '.elgg-form-register', submit);
  27. if (getMedia) {
  28. initHtml5();
  29. } else if (hasFlash()) {
  30. initFlash();
  31. } else {
  32. $('#avatar-upload-tab > a').click();
  33. $('#avatar-acquire-tab').hide();
  34. }
  35. };
  36. var hasFlash = function() {
  37. try {
  38. var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
  39. if (fo) {
  40. return true;
  41. }
  42. } catch (e) {
  43. if (navigator.mimeTypes
  44. && navigator.mimeTypes['application/x-shockwave-flash'] != undefined
  45. && navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
  46. return true;
  47. }
  48. }
  49. return false;
  50. };
  51. var initHtml5 = function() {
  52. $(document).on('click', '#webcam-video', capturePicture);
  53. // must be called in the context of navigator or window, depending on browser
  54. getMedia.call(navigator || window,
  55. {
  56. video: true,
  57. audio: false
  58. },
  59. function(stream) {
  60. var video = $('#webcam-video').get(0);
  61. if (navigator.mozGetUserMedia) {
  62. video.mozSrcObject = stream;
  63. } else {
  64. var vendorURL = window.URL || window.webkitURL;
  65. video.src = vendorURL.createObjectURL(stream);
  66. }
  67. video.play();
  68. },
  69. function(err) {
  70. elgg.register_error(elgg.echo('webcam:webcam_error'));
  71. }
  72. );
  73. };
  74. var shutterSound = function() {
  75. var audio = document.createElement('audio');
  76. audio.src = elgg.get_site_url() + 'mod/webcam/haxe/shutter.mp3';
  77. return {
  78. play: function() {
  79. audio.play();
  80. }
  81. };
  82. };
  83. var initFlash = function() {
  84. var html = '<div id="flashContent">'
  85. + '<object type="application/x-shockwave-flash" data="' + elgg.get_site_url()
  86. // @todo make these dynamic
  87. + 'mod/webcam/haxe/take_picture.swf" width="480" height="360">'
  88. + '<param name="movie" value="take_picture.swf" />'
  89. + '<param name="quality" value="high" />'
  90. + '<param name="bgcolor" value="#ffffff" />'
  91. + '<param name="play" value="true" />'
  92. + '<param name="loop" value="true" />'
  93. + '<param name="wmode" value="transparent" />'
  94. + '<param name="scale" value="noscale" />'
  95. + '<param name="menu" value="true" />'
  96. + '<param name="devicefont" value="false" />'
  97. + '<param name="salign" value="" />'
  98. + '<param name="allowScriptAccess" value="sameDomain" />'
  99. + '<a href="http://www.adobe.com/go/getflash">'
  100. + ' <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />'
  101. + '</a>'
  102. + '</object>'
  103. + '</div>';
  104. $('#webcam').html(html);
  105. };
  106. /**
  107. * Normalize resolutions
  108. */
  109. var setRes = function(ev) {
  110. var $video = $('video');
  111. video = $video.get(0);
  112. // normalize the resolutions
  113. var canvas = $('#webcam-canvas');
  114. options.height = video.videoHeight / (video.videoWidth / options.width);
  115. $video.attr('width', options.width);
  116. $video.attr('height', options.height);
  117. canvas.attr('width', options.width);
  118. canvas.attr('height', options.height);
  119. $video.data('streaming', true);
  120. };
  121. /**
  122. * Capture a picture and save as base64 input data
  123. *
  124. * @param Obj ev Event
  125. * @returns {undefined}
  126. */
  127. var capturePicture = function(ev) {
  128. ev.preventDefault();
  129. var canvas = $('#webcam-canvas').get(0);
  130. var video = this;
  131. // if clicked on while paused, unpause
  132. if (video.paused) {
  133. video.play();
  134. $(video).removeClass('has-photo');
  135. removeBase64Input();
  136. return;
  137. }
  138. // @todo just make this return the resolution
  139. setRes();
  140. var width = options.width,
  141. height = options.height;
  142. shutterSound().play();
  143. video.pause();
  144. $(video).addClass('has-photo');
  145. canvas.width = width;
  146. canvas.height = height;
  147. canvas.getContext('2d').drawImage(video, 0, 0, width, height);
  148. // the data url format is data:<mime_type>;base64,<data>
  149. var data = canvas.toDataURL().split(',')[1];
  150. saveBase64Input(data, $(this).closest('form'));
  151. };
  152. var saveBase64Input = function(data, formElement) {
  153. var html = "<input id='webcam-image-base64' type='hidden' name='webcam-image-base64'>";
  154. $(formElement).prepend(html);
  155. $('#webcam-image-base64').attr('value', data);
  156. };
  157. var removeBase64Input = function() {
  158. $('#webcam-image-base64').remove();
  159. };
  160. var changeTab = function(ev) {
  161. ev.preventDefault();
  162. var $this = $(this);
  163. var $li = $this.closest('li');
  164. var $ul = $this.closest('ul');
  165. // change tab
  166. $ul.find('li').removeClass('elgg-state-selected');
  167. $li.addClass('elgg-state-selected');
  168. // change content
  169. $("#avatar-options > div").hide();
  170. $('#' + $li.attr('id').replace('-tab', '')).show();
  171. };
  172. var submit = function(ev) {
  173. // prevent if no data at all
  174. if (!$('#webcam-image-base64').val()
  175. && !$('input[name=avatar]').val()
  176. && !$('input[name=avatar_url]').val()
  177. ) {
  178. elgg.register_error(elgg.echo('webcam:no_avatar_selected'));
  179. ev.preventDefault();
  180. }
  181. };
  182. elgg.register_hook_handler('init', 'system', init);
  183. });