fix camera bug in FF
This commit is contained in:
parent
867933b1de
commit
9a96d6bf66
1 changed files with 68 additions and 53 deletions
|
@ -242,7 +242,7 @@ class Camera extends App.ControllerModal
|
||||||
@button = 'Save'
|
@button = 'Save'
|
||||||
@buttonClass = 'btn--success is-disabled'
|
@buttonClass = 'btn--success is-disabled'
|
||||||
@centerButtons = [{
|
@centerButtons = [{
|
||||||
className: 'btn--success js-shoot',
|
className: 'btn--success js-shoot is-disabled',
|
||||||
text: 'Shoot'
|
text: 'Shoot'
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
@ -258,25 +258,26 @@ class Camera extends App.ControllerModal
|
||||||
onShootClick: =>
|
onShootClick: =>
|
||||||
if @photoTaken
|
if @photoTaken
|
||||||
@photoTaken = false
|
@photoTaken = false
|
||||||
@countdown = 0
|
@submitButton.addClass 'is-disabled'
|
||||||
@submitButton.addClass('is-disabled')
|
|
||||||
@shootButton
|
@shootButton
|
||||||
.removeClass('btn--danger')
|
.removeClass 'btn--danger'
|
||||||
.addClass('btn--success')
|
.addClass 'btn--success'
|
||||||
.text( App.i18n.translateInline('Shoot') )
|
.text App.i18n.translateInline('Shoot')
|
||||||
@updatePreview()
|
@updatePreview()
|
||||||
else
|
else
|
||||||
@shoot()
|
@shoot()
|
||||||
@shootButton
|
@shootButton
|
||||||
.removeClass('btn--success')
|
.removeClass 'btn--success'
|
||||||
.addClass('btn--danger')
|
.addClass 'btn--danger'
|
||||||
.text( App.i18n.translateInline('Discard') )
|
.text App.i18n.translateInline('Discard')
|
||||||
|
|
||||||
shoot: =>
|
shoot: =>
|
||||||
@photoTaken = true
|
@photoTaken = true
|
||||||
@submitButton.removeClass('is-disabled')
|
@submitButton.removeClass 'is-disabled'
|
||||||
|
|
||||||
onWebcamReady: (stream) =>
|
onWebcamReady: (stream) =>
|
||||||
|
@shootButton.removeClass 'is-disabled'
|
||||||
|
|
||||||
# in case the modal is closed before the
|
# in case the modal is closed before the
|
||||||
# request was fullfilled
|
# request was fullfilled
|
||||||
if @hidden
|
if @hidden
|
||||||
|
@ -286,14 +287,14 @@ class Camera extends App.ControllerModal
|
||||||
# cache stream so that we can later turn it off
|
# cache stream so that we can later turn it off
|
||||||
@stream = stream
|
@stream = stream
|
||||||
|
|
||||||
@video.attr 'src', window.URL.createObjectURL(stream)
|
|
||||||
|
|
||||||
# setup the offset to center the webcam image perfectly
|
# setup the offset to center the webcam image perfectly
|
||||||
# when the stream is ready
|
# when the stream is ready
|
||||||
@video.on('canplay', @setupPreview)
|
@video.on 'canplay', @setupPreview
|
||||||
|
|
||||||
# start to update the preview once its playing
|
# start to update the preview once its playing
|
||||||
@video.on('play', @updatePreview)
|
@video.on 'playing', @updatePreview
|
||||||
|
|
||||||
|
@video.attr 'src', window.URL.createObjectURL(stream)
|
||||||
|
|
||||||
# start the stream
|
# start the stream
|
||||||
@video.get(0).play()
|
@video.get(0).play()
|
||||||
|
@ -316,47 +317,56 @@ class Camera extends App.ControllerModal
|
||||||
@preview.attr
|
@preview.attr
|
||||||
width: @size
|
width: @size
|
||||||
height: @size
|
height: @size
|
||||||
@offsetX = (@video.width() - @size)/2
|
|
||||||
@centerX = @size/2
|
@centerX = @size/2
|
||||||
@centerY = @size/2
|
@centerY = @size/2
|
||||||
|
|
||||||
updatePreview: =>
|
|
||||||
@ctx.clearRect(0, 0, @preview.width(), @preview.height())
|
|
||||||
|
|
||||||
# create circle clip area
|
# create circle clip area
|
||||||
@ctx.save()
|
@ctx.translate @centerX, @centerY
|
||||||
|
|
||||||
@ctx.beginPath()
|
|
||||||
@ctx.arc(@centerX, @centerY, @size/2, 0, 2 * Math.PI, false)
|
|
||||||
@ctx.closePath()
|
|
||||||
@ctx.clip()
|
|
||||||
|
|
||||||
# flip the image to look like a mirror
|
# flip the image to look like a mirror
|
||||||
@ctx.scale(-1,1)
|
@ctx.scale -1, 1
|
||||||
|
|
||||||
# draw video frame
|
# settings for anti-aliasing
|
||||||
@ctx.drawImage(@video.get(0), @offsetX, 0, -@video.width(), @size)
|
|
||||||
|
|
||||||
# flip the image to look like a mirror
|
|
||||||
@ctx.scale(-1,1)
|
|
||||||
|
|
||||||
# add anti-aliasing
|
|
||||||
# http://stackoverflow.com/a/12395939
|
|
||||||
@ctx.strokeStyle = @backgroundColor
|
@ctx.strokeStyle = @backgroundColor
|
||||||
@ctx.lineWidth = 2
|
@ctx.lineWidth = 2
|
||||||
@ctx.arc(@centerX, @centerY, @size/2, 0, 2 * Math.PI, false)
|
|
||||||
@ctx.stroke()
|
|
||||||
|
|
||||||
# reset the clip area to be able to draw on the whole canvas
|
updatePreview: =>
|
||||||
@ctx.restore()
|
# try catch fixes a Firefox error
|
||||||
|
# were the drawImage wouldn't work
|
||||||
|
# because the video didn't get inizialized
|
||||||
|
# yet internally
|
||||||
|
# http://stackoverflow.com/questions/18580844/firefox-drawimagevideo-fails-with-ns-error-not-available-component-is-not-av
|
||||||
|
try
|
||||||
|
@ctx.globalCompositeOperation = 'source-over'
|
||||||
|
@ctx.clearRect 0, 0, @size, @size
|
||||||
|
@ctx.beginPath()
|
||||||
|
@ctx.arc 0, 0, @size/2, 0, 2 * Math.PI, false
|
||||||
|
@ctx.closePath()
|
||||||
|
@ctx.fill()
|
||||||
|
@ctx.globalCompositeOperation = 'source-atop'
|
||||||
|
|
||||||
# update the preview again as soon as
|
# draw video frame
|
||||||
# the browser is ready to draw a new frame
|
@ctx.drawImage @video.get(0), -@video.width()/2, -@size/2, @video.width(), @size
|
||||||
if not @photoTaken
|
|
||||||
requestAnimationFrame @updatePreview
|
# add anti-aliasing
|
||||||
else
|
# http://stackoverflow.com/a/12395939
|
||||||
# cache raw video data
|
@ctx.beginPath()
|
||||||
@cacheScreenshot()
|
@ctx.arc 0, 0, @size/2, 0, 2 * Math.PI, false
|
||||||
|
@ctx.closePath()
|
||||||
|
@ctx.stroke()
|
||||||
|
|
||||||
|
# update the preview again as soon as
|
||||||
|
# the browser is ready to draw a new frame
|
||||||
|
if not @photoTaken
|
||||||
|
requestAnimationFrame @updatePreview
|
||||||
|
else
|
||||||
|
# cache raw video data
|
||||||
|
@cacheScreenshot()
|
||||||
|
catch e
|
||||||
|
if e.name is "NS_ERROR_NOT_AVAILABLE"
|
||||||
|
setTimeout @updatePreview, 200
|
||||||
|
else
|
||||||
|
throw e
|
||||||
|
|
||||||
initializeCache: ->
|
initializeCache: ->
|
||||||
# create virtual canvas
|
# create virtual canvas
|
||||||
|
@ -367,18 +377,21 @@ class Camera extends App.ControllerModal
|
||||||
# reset video height
|
# reset video height
|
||||||
@video.attr height: ''
|
@video.attr height: ''
|
||||||
|
|
||||||
@cache.attr
|
# cache screenshot as big as possible (native webcam dimensions)
|
||||||
width: @video.height()
|
size = Math.min @video.height(), @video.width()
|
||||||
height: @video.height()
|
|
||||||
|
|
||||||
offsetX = (@video.width() - @video.height())/2
|
@cache.attr
|
||||||
|
width: size
|
||||||
|
height: size
|
||||||
|
|
||||||
# draw full resolution screenshot
|
# draw full resolution screenshot
|
||||||
@cacheCtx.save()
|
@cacheCtx.save()
|
||||||
|
|
||||||
# flip image
|
# transform and flip image
|
||||||
@cacheCtx.scale(-1,1)
|
@cacheCtx.translate size/2, size/2
|
||||||
@cacheCtx.drawImage(@video.get(0), offsetX, 0, -@video.width(), @video.height())
|
@cacheCtx.scale -1, 1
|
||||||
|
|
||||||
|
@cacheCtx.drawImage @video.get(0), -@video.width()/2, -@video.height()/2, @video.width(), @video.height()
|
||||||
|
|
||||||
@cacheCtx.restore()
|
@cacheCtx.restore()
|
||||||
|
|
||||||
|
@ -391,6 +404,8 @@ class Camera extends App.ControllerModal
|
||||||
|
|
||||||
onSubmit: (e) =>
|
onSubmit: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
# send picture to the
|
# send picture to the callback
|
||||||
@options.callback( @cache.get(0).toDataURL() )
|
console.log @cache.get(0).toDataURL()
|
||||||
|
window.file = @cache.get(0).toDataURL()
|
||||||
|
@options.callback @cache.get(0).toDataURL()
|
||||||
@hide()
|
@hide()
|
||||||
|
|
Loading…
Reference in a new issue