class GitLabCrop # Matches everything but the file name FILENAMEREGEX = /^.*[\\\/]/ constructor: (input, opts = {}) -> @fileInput = $(input) # We should rename to avoid spec to fail # Form will submit the proper input filed with a file using FormData @fileInput .attr('name', "#{@fileInput.attr('name')}-trigger") .attr('id', "#{@fileInput.attr('id')}-trigger") # Set defaults { @exportWidth = 200 @exportHeight = 200 @cropBoxWidth = 200 @cropBoxHeight = 200 @form = @fileInput.parents('form') # Required params @filename @previewImage @modalCrop @pickImageEl @uploadImageBtn @modalCropImg } = opts # Ensure needed elements are jquery objects # If selector is provided we will convert them to a jQuery Object @filename = @getElement(@filename) @previewImage = @getElement(@previewImage) @pickImageEl = @getElement(@pickImageEl) # Modal elements usually are outside the @form element @modalCrop = if _.isString(@modalCrop) then $(@modalCrop) else @modalCrop @uploadImageBtn = if _.isString(@uploadImageBtn) then $(@uploadImageBtn) else @uploadImageBtn @modalCropImg = if _.isString(@modalCropImg) then $(@modalCropImg) else @modalCropImg @cropActionsBtn = @modalCrop.find('[data-method]') @bindEvents() getElement: (selector) -> $(selector, @form) bindEvents: -> _this = @ @fileInput.on 'change', (e) -> _this.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 = @ _this.onActionBtnClick(btn) @croppedImageBlob = null onPickImageClick: => @fileInput.trigger('click') onModalShow: => _this = @ @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: -> $image = $(@) container = $image.cropper 'getContainerData' cropBoxWidth = _this.cropBoxWidth; cropBoxHeight = _this.cropBoxHeight; $image.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() @setPreview() @modalCrop.modal('hide') @fileInput.val('') onActionBtnClick: (btn) -> data = $(btn).data() if @modalCropImg.data('cropper') && data.method result = @modalCropImg.cropper data.method, data.option onFileInputChange: (e, input) -> @readFile(input) readFile: (input) -> _this = @ reader = new FileReader reader.onload = -> _this.modalCropImg.attr('src', reader.result) _this.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') setPreview: -> @previewImage.attr('src', @dataURL) filename = @fileInput.val().replace(FILENAMEREGEX, '') @filename.text(filename) setBlob: -> @dataURL = @modalCropImg.cropper('getCroppedCanvas', width: 200 height: 200 ).toDataURL('image/png') @croppedImageBlob = @dataURLtoBlob(@dataURL) getBlob: -> @croppedImageBlob $.fn.glCrop = (opts) -> return @.each -> $(@).data('glcrop', new GitLabCrop(@, opts))