fix camera bug in FF

This commit is contained in:
Felix Niklas 2015-03-13 12:38:16 +01:00
parent 867933b1de
commit 9a96d6bf66

View file

@ -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()