Skip to content

Commit

Permalink
Merge pull request #247 from Tangerine-Community/implement-camera-swi…
Browse files Browse the repository at this point in the history
…tcher-photo-capture

implemented camera switcher for photo capture
  • Loading branch information
chrisekelley committed Jun 17, 2021
2 parents 17733fe + 6817ecd commit 3cff641
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 10 deletions.
2 changes: 1 addition & 1 deletion demo/tangy-photo-capture.html
Expand Up @@ -71,7 +71,7 @@
<h3>tangy-photo-capture demo</h3>
<demo-snippet>
<template>
<tangy-photo-capture name="test-photo" max-size-in-kb='128'></tangy-photo-capture>
<tangy-photo-capture name="test-photo" max-size-in-kb='512' label="Take a Photo" ></tangy-photo-capture>
</template>
</demo-snippet>
</div>
Expand Down
75 changes: 66 additions & 9 deletions input/tangy-photo-capture.js
Expand Up @@ -16,6 +16,7 @@ import ImageBlobReduce from 'image-blob-reduce'
* @demo demo/index.html
*/
export class TangyPhotoCapture extends PolymerElement {

static get template () {
return html`
<style include="tangy-common-styles"></style>
Expand Down Expand Up @@ -46,13 +47,15 @@ export class TangyPhotoCapture extends PolymerElement {
<div class="flex-container m-y-25">
<div id="qnum-number"></div>
<div id="qnum-content">
<label id="label"></label>
<div>
<video autoplay id="video"></video>
<img src="[[value]]" style='display:none' id="image"/>
</div>
<div id="buttons">
<paper-button id="capture-button" on-click="capturePhoto"><iron-icon icon="camera-enhance"></iron-icon> [[t.capture]] </paper-button>
<paper-button id="accept-button" on-click="acceptPhoto" disabled><iron-icon icon="done"></iron-icon> [[t.accept]] </paper-button>
<paper-button id="toggle-button" on-click="toggleCamera"><iron-icon icon="image:switch-camera"></iron-icon> [[t.switch]] </paper-button>
<paper-button id="clear-button" on-click="clearPhoto" disabled><iron-icon icon="delete"></iron-icon> [[t.clear]] </paper-button>
</div>
Expand Down Expand Up @@ -81,6 +84,11 @@ export class TangyPhotoCapture extends PolymerElement {
value: 256,
reflectToAttribute: true
},
label: {
type: String,
observer: 'reflect',
value: ''
},
hintText: {
type: String,
observer: 'onHintTextChange',
Expand Down Expand Up @@ -152,7 +160,12 @@ export class TangyPhotoCapture extends PolymerElement {
type: Boolean,
value: false,
reflectToAttribute: true
}
},
front: {
type: Boolean,
value: false,
reflectToAttribute: true
},
}
}

Expand All @@ -161,6 +174,11 @@ export class TangyPhotoCapture extends PolymerElement {
this.shadowRoot.querySelector('#qnum-number').innerHTML = this.hasAttribute('question-number')
? `<label>${this.getAttribute('question-number')}</label>`
: ''
let supportedConstraints = navigator.mediaDevices.getSupportedConstraints();
let devices = navigator.mediaDevices.enumerateDevices().then(function(devices) {
var arrayLength = devices.length;
})
this.constraints = {video: { facingMode: { exact: "environment" } }}
}

ready() {
Expand All @@ -170,13 +188,27 @@ export class TangyPhotoCapture extends PolymerElement {
accept: t('accept'),
clear: t('clear')
}
this.shadowRoot.querySelector('#label').innerHTML = this.label
// Start streaming video
navigator.mediaDevices.getUserMedia({video: { facingMode: { exact: "environment" } }})
const constraints = this.getConstraints()
navigator.mediaDevices.getUserMedia(constraints)
.then(mediaStream => {
this.shadowRoot.querySelector('video').srcObject = mediaStream;
const track = mediaStream.getVideoTracks()[0];
this.imageCapture = new ImageCapture(track);
})
}).catch(error => {
if (error.constraint && error.constraint === 'facingMode') {
navigator.mediaDevices.getUserMedia({video: true})
.then(mediaStream => {
this.shadowRoot.querySelector('video').srcObject = mediaStream;
const track = mediaStream.getVideoTracks()[0];
this.imageCapture = new ImageCapture(track);
});
} else {
console.log("error: " + error)
}
}
)

if (this.value) {
this.shadowRoot.querySelector('video').style.display = 'none'
Expand Down Expand Up @@ -253,17 +285,42 @@ export class TangyPhotoCapture extends PolymerElement {

async acceptPhoto() {
// Convert blob to base64 string
// https://stackoverflow.com/questions/18650168/convert-blob-to-base64/61226119#61226119
const reader = new FileReader();
reader.readAsDataURL(this.blob);
this.value = await new Promise(resolve => {
reader.onloadend = () => resolve(reader.result);
});
const arrayBuffer = await this.blob.arrayBuffer()
// convert arrayBuffer to a base64String
const base64String = window.btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
// turn it into a data:image
const nudata = 'data:image/jpeg;base64,' + base64String
this.value = nudata

this.shadowRoot.querySelector('#capture-button').setAttribute('disabled', '')
this.shadowRoot.querySelector('#accept-button').setAttribute('disabled', '')
}



getConstraints() {
if (this.front) {
return {video: { facingMode: { exact: "user" } }}
} else {
return {video: { facingMode: { exact: "environment" } }}
}
}

toggleCamera() {
if (this.front) {
this.front = false
} else {
this.front = true
}
const constraints = this.getConstraints()
navigator.mediaDevices.getUserMedia(constraints)
.then(mediaStream => {
this.shadowRoot.querySelector('video').srcObject = mediaStream;
const track = mediaStream.getVideoTracks()[0];
this.imageCapture = new ImageCapture(track);
})
}

onDiscrepancyChange(value) {
this.shadowRoot.querySelector('#discrepancy-text').innerHTML = this.hasDiscrepancy
? `<iron-icon icon="flag"></iron-icon> <div> ${ this.hasAttribute('discrepancy-text') ? this.getAttribute('discrepancy-text') : ''} </div>`
Expand Down

0 comments on commit 3cff641

Please sign in to comment.