Skip to content

Commit

Permalink
Merge pull request #574 from transloadit/improvement/webcam-flip
Browse files Browse the repository at this point in the history
[wip] Add `mirror: true` opt that flips webcam picture to act like mirror
  • Loading branch information
arturi authored Feb 9, 2018
2 parents 8d4fd52 + 3a30f53 commit f9f0357
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 23 deletions.
3 changes: 1 addition & 2 deletions src/plugins/Webcam/CameraScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ class CameraScreen extends Component {
return (
<div class="uppy uppy-Webcam-container">
<div class="uppy-Webcam-videoContainer">
<video class="uppy-Webcam-video" autoplay muted src={this.props.src || ''} />
<video class={`uppy-Webcam-video ${this.props.mirror ? 'uppy-Webcam-video--mirrored' : ''}`} autoplay muted playsinline srcObject={this.props.src || ''} />
</div>
<div class="uppy-Webcam-buttonContainer" ref={(el) => { this.btnContainer = el }}>
{shouldShowSnapshotButton ? SnapshotButton(this.props) : null}
{' '}
{shouldShowRecordButton ? RecordButton(this.props) : null}
</div>
<canvas class="uppy-Webcam-canvas" style="display: none;" />
</div>
)
}
Expand Down
32 changes: 23 additions & 9 deletions src/plugins/Webcam/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ module.exports = class Webcam extends Plugin {
'video-only',
'audio-only',
'picture'
]
],
mirror: true,
facingMode: 'user'
}

// merge default options with the ones set by user
Expand Down Expand Up @@ -108,7 +110,7 @@ module.exports = class Webcam extends Plugin {

return {
audio: acceptsAudio,
video: acceptsVideo
video: acceptsVideo ? { facingMode: this.opts.facingMode } : false
}
}

Expand All @@ -125,8 +127,7 @@ module.exports = class Webcam extends Plugin {
return this.mediaDevices.getUserMedia(constraints)
.then((stream) => {
this.stream = stream
console.log(stream)
this.streamSrc = URL.createObjectURL(this.stream)
// this.streamSrc = URL.createObjectURL(this.stream)
this.setPluginState({
cameraReady: true
})
Expand Down Expand Up @@ -191,7 +192,6 @@ module.exports = class Webcam extends Plugin {
})
this.webcamActive = false
this.stream = null
this.streamSrc = null
}

getVideoElement () {
Expand Down Expand Up @@ -251,10 +251,23 @@ module.exports = class Webcam extends Plugin {
const name = `webcam-${Date.now()}.jpg`
const mimeType = 'image/jpeg'

const width = video.videoWidth
const height = video.videoHeight

// const scaleH = this.opts.mirror ? -1 : 1 // Set horizontal scale to -1 if flip horizontal
// const scaleV = 1
// const posX = this.opts.mirror ? width * -1 : 0 // Set x position to -100% if flip horizontal
// const posY = 0

const canvas = document.createElement('canvas')
canvas.width = video.videoWidth
canvas.height = video.videoHeight
canvas.getContext('2d').drawImage(video, 0, 0)
canvas.width = width
canvas.height = height
const ctx = canvas.getContext('2d')
ctx.drawImage(video, 0, 0)
// ctx.save() // Save the current state
// ctx.scale(scaleH, scaleV) // Set scale to flip the image
// ctx.drawImage(video, posX, posY, width, height) // draw the image
// ctx.restore() // Restore the last saved state

return canvasToBlob(canvas, mimeType).then((blob) => {
return {
Expand Down Expand Up @@ -313,7 +326,8 @@ module.exports = class Webcam extends Plugin {
modes: this.opts.modes,
supportsRecording: supportsMediaRecorder(),
recording: webcamState.isRecording,
src: this.streamSrc
mirror: this.opts.mirror,
src: this.stream
}))
}

Expand Down
24 changes: 13 additions & 11 deletions src/scss/_webcam.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
// @import '_variables.scss';
// @import '_utils.scss';
// @import '_animation.scss';
// @import '_common.scss';

.uppy-Webcam-container {
width: 100%;
height: 100%;
Expand All @@ -12,20 +7,27 @@
}

.uppy-Webcam-videoContainer {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
// display: flex;
// justify-content: center;
// align-items: center;
}

.uppy-Dashboard--wide .uppy-Webcam-videoContainer {
height: initial;
}

.uppy-Webcam-video {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
}

// .uppy-Webcam-canvas {
// display: none;
// }
.uppy-Webcam-video--mirrored {
transform: scaleX(-1);
}

.uppy-Webcam-buttonContainer {
position: absolute;
Expand Down
19 changes: 18 additions & 1 deletion website/src/docs/webcam.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ title: "Webcam"
permalink: docs/webcam/
---

The Webcam plugin lets you take photos and record videos with a built-in camera on desktop and mobile devices.

[Try it live](/examples/dashboard/) - The Informer is included in the Dashboard by default.
[Try live!](/examples/dashboard/)

## Options

Expand All @@ -20,6 +21,8 @@ uppy.use(Webcam, {
'audio-only',
'picture'
],
mirror: true,
facingMode: 'user',
locale: {
strings: {
smile: 'Smile!'
Expand Down Expand Up @@ -52,6 +55,20 @@ The types of recording modes to allow.

By default, all modes are allowed, and the Webcam plugin will show controls for recording video as well as taking pictures.

### `mirror: true`

Whether to mirror preview image from the camera. This option is useful when taking a selfie with a front camera: when you wave your right hand, you will see your hand on the right on the preview screen, like in the mirror. But when you actually take a picture, it will not be mirrored. This is how smartphone selfie cameras behave.

### `facingMode: 'user'`

Devices sometimes have multiple cameras, front and back, for example. There’s a browser API to set which camera will be used, [facingMode](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/facingMode):

- `user`: The video source is facing toward the user; this includes, for example, the front-facing camera on a smartphone.
- `environment`: The video source is facing away from the user, thereby viewing their environment. This is the back camera on a smartphone.
- `left`: The video source is facing toward the user but to their left, such as a camera aimed toward the user but over their left shoulder.
- `right`: The video source is facing toward the user but to their right, such as a camera aimed toward the user but over their right shoulder.


### `locale: {}`

There is only one localizable string: `strings.smile`. It's shown before a picture is taken, when the `countdown` option is set to true.

0 comments on commit f9f0357

Please sign in to comment.