diff --git a/app/assets/javascripts/gl_crop.js.coffee b/app/assets/javascripts/gl_crop.js.coffee new file mode 100644 index 0000000..5d5b2c4 --- /dev/null +++ b/app/assets/javascripts/gl_crop.js.coffee @@ -0,0 +1,118 @@ +class GitLabCrop + constructor: (el, opts = {}) -> + # Input file + @fileInput = $(el) + + # Set defaults + { + @filename + @form = @fileInput.parents('form') + @modalCrop = '.modal-profile-crop' + + # Button where user clicks to open file dialog + # If not passed as argument let's pick a default one + @pickImageEl = @fileInput.parent().find('.js-choose-user-avatar-button') + @uploadImageBtn = $('.js-upload-user-avatar') + } = opts + + # Ensure @modalCrop is a jQuery Object + @modalCrop = $(@modalCrop) + @modalCropImg = $('.modal-profile-crop-image') + @cropActionsBtn = @modalCrop.find('[data-method]') + + @bindEvents() + + bindEvents: -> + self = @ + @fileInput.on 'change', (e) -> + self.onFileInputChange(e, @) + + @pickImageEl.on 'click', @onPickImageClick + @modalCrop.on 'shown.bs.modal', @onModalShow + @modalCrop.on 'hidden.bs.modal', @onModalHide + @uploadImageBtn.on 'click', @onUploadImageBtnClick + @cropActionsBtn.on 'click', (e) -> + btn = @ + self.onActionBtnClick(btn) + @croppedImageBlob = null + + onPickImageClick: => + @fileInput.trigger('click') + + onModalShow: => + @modalCropImg.cropper( + viewMode: 1 + center: false + aspectRatio: 1 + modal: true + scalable: false + rotatable: false + zoomable: true + dragMode: 'move' + guides: false + zoomOnTouch: false + zoomOnWheel: false + cropBoxMovable: false + cropBoxResizable: false + toggleDragModeOnDblclick: false + built: -> + container = $(@).cropper 'getContainerData' + cropBoxWidth = 200; + cropBoxHeight = 200; + + $(@).cropper('setCropBoxData', + width: cropBoxWidth, + height: cropBoxHeight, + left: (container.width - cropBoxWidth) / 2, + top: (container.height - cropBoxHeight) / 2 + ) + ) + + + onModalHide: => + @modalCropImg + .attr('src', '') # Remove attached image + .cropper('destroy') # Destroy cropper instance + + onUploadImageBtnClick: (e) => + e.preventDefault() + @setBlob() + @modalCrop.modal('hide') + # @form.submit(); + + onActionBtnClick: (btn) -> + data = $(btn).data() + + if @modalCropImg.data('cropper') && data.method + data = $.extend {}, data + result = @modalCropImg.cropper data.method, data.option + + onFileInputChange: (e, input) -> + @readFile(input) + + readFile: (input) -> + self = @ + reader = new FileReader + reader.onload = -> + self.modalCropImg.attr('src', reader.result) + self.modalCrop.modal('show') + + reader.readAsDataURL(input.files[0]) + + dataURLtoBlob: (dataURL) -> + binary = atob(dataURL.split(',')[1]) + array = [] + for v, k in binary + array.push(binary.charCodeAt(k)) + new Blob([new Uint8Array(array)], type: 'image/png') + + setBlob: -> + dataURL = @modalCropImg.cropper('getCroppedCanvas').toDataURL('image/png') + @croppedImageBlob = @dataURLtoBlob(dataURL) + + getBlob: -> + @croppedImageBlob + +$.fn.glCrop = (opts) -> + return @.each -> + $(@).data('glcrop', new GitLabCrop(@, opts))