77// Workflow:
88// The HTML5 functionality (on mobille) is to prompt for either
99// a realtime camera capture , OR a selection from images already ont the device
10- // (eg camera roll). The solid alternative is to either take a phtoto
10+ // (eg camera roll).
11+ //
12+ // The solid alternative is to either take a phtoto
1113// or access cemra roll (etc) OR to access solid cloud storage of favorite photo almbums.
1214// (Especially latest taken ones)
1315//
14- /* global alert confirm */
16+ /* global alert */
1517
1618/** @module mediaCapture */
1719
@@ -30,72 +32,125 @@ var UI = {
3032 widgets : require ( './widgets' )
3133}
3234
35+ const cameraIcon = require ( './noun_Camera_1618446_000000' ) // load it in JS
36+ // const cameraIcon = UI.icons.iconBase + 'noun_479395.svg' // Get it from github
37+
38+ const canvasWidth = '640'
39+ const canvasHeight = '480'
40+
41+ const controlStyle = `border-radius: 0.5em; margin: 0.8em; width: ${ canvasWidth } ; height:${ canvasHeight } ;`
42+ // const controlStyle = 'border-radius: 0.5em; margin: 0.8em; width: 320; height:240;'
43+ const contentType = 'image/png'
44+
3345/** A control to capture a picture using camera
3446 * @param {Docuemnt } dom - The Document object
3547 * @param {IndexedForumla } store - The quadstore to store data in
3648 * @param {NamedNode } getImageDoc() - NN of the image file to be created
3749 * @param {function } doneCallback - Called when a picture has been taken
3850 */
39- function cameraCaptureControl ( dom , store , getImageDoc , doneCallback ) {
51+ module . exports . cameraCaptureControl = function cameraCaptureControl ( dom , store , getImageDoc , doneCallback ) {
4052 const div = dom . createElement ( 'div' )
41- const player = div . appendChild ( dom . createElement ( 'video' ) )
42- const controlStyle = 'border-radius: 0.5em; margin: 0.8em; width: 320; height:240;'
43- const contentType = 'image/png'
44- // player.setAttribute('controls', '1')
45- player . setAttribute ( 'autoplay' , '1' )
46- const button = div . appendChild ( dom . createElement ( 'button' ) )
47- button . textContent = 'Capture'
48- player . setAttribute ( 'style' , controlStyle )
49- var canvas
53+ var destination , imageBlob , player , canvas
54+
55+ const table = div . appendChild ( dom . createElement ( 'table' ) )
56+ const mainTR = table . appendChild ( dom . createElement ( 'tr' ) )
57+ const main = mainTR . appendChild ( dom . createElement ( 'td' ) )
58+ main . setAttribute ( 'colspan' , '4' )
59+
60+ const buttons = table . appendChild ( dom . createElement ( 'tr' ) )
61+
62+ buttons . appendChild ( dom . createElement ( 'td' ) ) // Cancel button
63+ . appendChild ( UI . widgets . cancelButton ( dom ) )
64+ . addEventListener ( 'click' , e => {
65+ stopVideo ( )
66+ doneCallback ( null )
67+ } )
68+
69+ buttons . appendChild ( dom . createElement ( 'td' ) ) // Retake button
70+ . appendChild ( UI . widgets . button ( dom , cameraIcon , 'Retake' ) )
71+ . addEventListener ( 'click' , e => {
72+ retake ( )
73+ } )
74+
75+ buttons . appendChild ( dom . createElement ( 'td' ) ) // Trigger capture button
76+ . appendChild ( UI . widgets . button ( dom , UI . icons . iconBase + 'noun_10636.svg' , 'Snap' ) )
77+ . addEventListener ( 'click' , grabCanvas )
78+
79+ buttons . appendChild ( dom . createElement ( 'td' ) ) // Confirm and save button
80+ . appendChild ( UI . widgets . continueButton ( dom ) ) // @@ or send icon??
81+ . addEventListener ( 'click' , e => {
82+ saveBlob ( imageBlob , destination )
83+ } )
84+
85+ function displayPlayer ( ) {
86+ player = main . appendChild ( dom . createElement ( 'video' ) )
87+ player . setAttribute ( 'controls' , '1' )
88+ player . setAttribute ( 'autoplay' , '1' )
89+ player . setAttribute ( 'style' , controlStyle )
90+ navigator . mediaDevices . getUserMedia ( constraints )
91+ . then ( ( stream ) => {
92+ player . srcObject = stream
93+ } )
94+ }
5095
5196 const constraints = {
5297 video : true
5398 }
5499
100+ function retake ( ) {
101+ main . removeChild ( canvas )
102+ displayPlayer ( ) // Make new one as old one is stuck black
103+ }
104+
55105 function grabCanvas ( ) {
56106 // Draw the video frame to the canvas.
57107 canvas = dom . createElement ( 'canvas' )
58- canvas . setAttribute ( 'width' , '320' )
59- canvas . setAttribute ( 'height' , '240' )
108+ canvas . setAttribute ( 'width' , canvasWidth )
109+ canvas . setAttribute ( 'height' , canvasHeight )
60110 canvas . setAttribute ( 'style' , controlStyle )
61- player . parentNode . appendChild ( canvas )
111+ main . appendChild ( canvas )
62112
63113 const context = canvas . getContext ( '2d' )
64114 context . drawImage ( player , 0 , 0 , canvas . width , canvas . height )
65115
66- // Stop all video streams.
67- player . srcObject . getVideoTracks ( ) . forEach ( track => track . stop ( ) )
68116 player . parentNode . removeChild ( player )
69117
70118 canvas . toBlob ( blob => {
71119 let msg = `got blob type ${ blob . type } size ${ blob . size } `
72120 console . log ( msg )
73- let destination = getImageDoc ( )
74- saveBlob ( blob , destination )
121+ destination = getImageDoc ( )
122+ imageBlob = blob // save for review
123+ reviewImage ( )
75124 // alert(msg)
76125 } , contentType ) // toBlob
77126 }
78127
128+ function reviewImage ( ) {
129+ // @@ Enable continue button
130+ // @@ Enable retake button
131+ }
132+
133+ function stopVideo ( ) {
134+ if ( player && player . srcObject ) {
135+ player . srcObject . getVideoTracks ( ) . forEach ( track => track . stop ( ) )
136+ }
137+ }
79138 function saveBlob ( blob , destination ) {
80139 let contentType = blob . type
81- if ( ! confirm ( 'Save picture to ' + destination + ' ?' ) ) return
140+ // if (!confirm('Save picture to ' + destination + ' ?')) return
82141 console . log ( 'Putting ' + blob . size + ' bytes of ' + contentType + ' to ' + destination )
83142 store . fetcher . webOperation ( 'PUT' , destination . uri , { data : blob , contentType : contentType } ) . then ( resp => {
84143 console . log ( 'ok saved ' + destination )
144+ stopVideo ( )
85145 doneCallback ( destination )
86- alert ( 'saved ok: ' + destination )
87146 } , err => {
147+ stopVideo ( )
88148 alert ( err )
89149 } )
90150 }
91151
92- button . addEventListener ( 'click' , grabCanvas )
93-
94152 // Attach the video stream to the video element and autoplay.
95- navigator . mediaDevices . getUserMedia ( constraints )
96- . then ( ( stream ) => {
97- player . srcObject = stream
98- } )
153+ displayPlayer ( )
99154 return div
100155}
101156
@@ -108,9 +163,10 @@ function cameraCaptureControl (dom, store, getImageDoc, doneCallback) {
108163 *
109164 * This expacts the buttton to a large control when it is pressed
110165 */
111- function cameraButton ( dom , store , getImageDoc , doneCallback ) {
166+
167+ module . exports . cameraButton = function cameraButton ( dom , store , getImageDoc , doneCallback ) {
112168 const div = dom . createElement ( 'div' )
113- const but = UI . widgets . button ( dom , UI . icons . iconBase + 'noun_383448 .svg' , 'Take picture' )
169+ const but = UI . widgets . button ( dom , UI . icons . iconBase + 'noun_Camera_1618446_000000 .svg' , 'Take picture' )
114170 var control
115171 function restoreButton ( imageDoc ) {
116172 div . removeChild ( control )
@@ -120,15 +176,12 @@ function cameraButton (dom, store, getImageDoc, doneCallback) {
120176 div . appendChild ( but )
121177 but . addEventListener ( 'click' , event => {
122178 div . removeChild ( but )
123- control = control || cameraCaptureControl ( dom , store , getImageDoc , restoreButton )
179+ control = UI . media . cameraCaptureControl ( dom , store , getImageDoc , restoreButton )
124180 div . appendChild ( control )
125181 } )
126182 return div
127183}
128184
129- media . cameraButton = cameraButton
130- media . cameraCaptureControl = cameraCaptureControl
131-
132185/// /////////////////////////////////////// OLD BROKEN
133186
134187// Put up a video stream and take a picture
@@ -149,7 +202,7 @@ UI.media.cameraOLD = function (context, gotBlob) {
149202 ctx = canvas . getContext ( '2d' )
150203 ctx . drawImage ( video , 0 , 0 , width , height )
151204
152- img . src = canvas . toDataURL ( 'image/png' ) // @@@
205+ img . src = canvas . toDataURL ( contentType ) // @@@
153206 context . div . appendChild ( img )
154207 }
155208
0 commit comments