Skip to content

Instantly share code, notes, and snippets.

@wegorich
Created August 31, 2013 19:09
Show Gist options
  • Save wegorich/6400027 to your computer and use it in GitHub Desktop.
Save wegorich/6400027 to your computer and use it in GitHub Desktop.
load avatar from file, url, camera in rails
.avatar-picker
.header
%span.descr
Загрузить фото
%span.radio
= radio_button_tag :option, :file, checked: true
= label_tag :option_file, 'Как файл'
%span.radio
= radio_button_tag :option, :link
= label_tag :option_link, 'Как ссылку'
%span.radio
= radio_button_tag :option, :camera
= label_tag :option_camera, 'С камеры'
= simple_form_for current_user, url: profile_cv_user_avatar_path, remote: true do |f|
.content
#file-block
= user_avatar(current_user, 'big')
%label.btn-avatar{for: :avatar}
.btn.grad-gray
Выбрать новое фото
= f.file_field :avatar, accept: 'image/jpeg,image/png'
%span.filename
Файл не выбран
%p
Возможный формат файла:
%em
%span.green .jpeg
или
%span.green .png
%p
Вы сможете увидеть изменения после сохранения.
#link-block.hide
= f.text_field :remote_avatar_url, placeholder: 'Ссылка на фото', type: 'url'
%p
Вы сможете увидеть изменения после сохранения изменений.
#camera-block.hide
= hidden_field_tag :avatar_data
.avatar.big.r
%i.icon-camera
%img.camera-avatar{src: ''}
.avatar.big
%i.icon-videocam
%video{autoplay: true}
%canvas{width: '120', height: 120}
= link_to 'Сделать фото c камеры', '#', class: 'btn grad-blue snap'
%p Не забудьте сохранить изменения!
.footer
= f.submit 'Сохранить изменения', class: 'btn grad-green', disable_with: t('common.links.submit_state')
@avatarUploader =
hasGetUserMedia: ->
!!(navigator.getUserMedia or navigator.webkitGetUserMedia or navigator.mozGetUserMedia or navigator.msGetUserMedia)
localMediaStream: null
stopCam: ()->
if avatarUploader.localMediaStream
avatarUploader.localMediaStream.stop();
initWebCam: (picker)->
navigator.getUserMedia = navigator.getUserMedia or navigator.webkitGetUserMedia or navigator.mozGetUserMedia or navigator.msGetUserMedia
video = picker.find("video")
canvas = picker.find("canvas")
image = picker.find('.camera-avatar')
snapshot = ->
if avatarUploader.localMediaStream
canvas.attr('width', video.width())
ctx = canvas[0].getContext("2d")
ctx.drawImage video[0], 0 , 0, video.width(), 120
# "image/webp" works in Chrome 18. In other browsers, this will fall back to image/png.
image.attr('src', canvas[0].toDataURL("image/jpeg"))
picker.find('[name="avatar_data"]').val(canvas[0].toDataURL("image/png"))
onFailSoHard = ->
picker.find('.header').children().last().hide()
video.on 'click', snapshot
picker.find('.snap').on 'click', snapshot
# Not showing vendor prefixes or code that works cross-browser.
navigator.getUserMedia
video: true
, ((stream) ->
video.attr('src', window.URL.createObjectURL(stream))
avatarUploader.localMediaStream = stream
), onFailSoHard
avatarUploader.webCamInited = true
init: ()->
picker = $('.avatar-picker')
picker.on 'change', '.btn-avatar input[type=file]', ()->
$in=$(this)
$in.closest('.btn-avatar').find('.filename').html($in.val())
picker.on 'change', '[name="option"]', ()->
picker.find('.content').children().addClass('hide')
picker.find('#'+$(this).val()+'-block').removeClass('hide')
if $(this).val() == 'camera'
avatarUploader.initWebCam(picker)
else
avatarUploader.stopCam()
unless avatarUploader.hasGetUserMedia()
picker.find('.header').children().last().hide()
$.fancybox({content: '<%= j render partial: 'form' %>', wrapCSS: 'edit-modal', afterShow: avatarUploader.init, afterClose: avatarUploader.stopCam });
$.fancybox.close();
avatarUploader.stopCam();
$('.description img.avatar').attr('src', '<%= current_user.avatar.big.url %>');
(function(){
$('.info-block.orange').replaceWith('<%= j render partial: 'profile/cv/aside/edit_profile', locals: {profile: current_user.profile} %>')
})();
$('#header-line .dropdown img.avatar').attr('src', '<%= current_user.avatar.small.url %>');
class UserAvatarsController < Profile::ProfileController
respond_to :js, :html
def edit
respond_with
end
def update
if params[:avatar_data].length > 0
params[:user][:avatar] = convert_base64(params[:avatar_data])
end
if current_user.update_attributes(params[:user])
respond_to do |format|
format.js
end
end
end
private
def convert_base64(file)
encoded_image = file.sub('data:image/png;base64,', '')
fname = "#{current_user.username}_camera_avatar.png"
ctype = 'image/png'
decoded = FilelessIO.new(Base64.decode64(encoded_image))
decoded.original_filename = fname
decoded.content_type = ctype
decoded
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment