vue-avatar-cropper
Version:
A simple and elegant component to crop and upload avatars
2 lines (1 loc) • 7.92 kB
JavaScript
import e from"@babel/runtime/helpers/slicedToArray";import t from"@babel/runtime/helpers/asyncToGenerator";import r from"@babel/runtime/regenerator";import"cropperjs/dist/cropper.css";import a from"cropperjs";import n from"mime/lite";import{defineComponent as i,openBlock as o,createElementBlock as p,normalizeClass as l,createElementVNode as c,createCommentVNode as s,withModifiers as u,toDisplayString as m}from"vue";var d=i({name:"AvatarCropper",emits:["update:modelValue","submit","error","cancel","changed","uploading","completed","uploaded"],props:{modelValue:{type:Boolean,default:!1},file:{type:File},uploadHandler:{type:Function},uploadUrl:{type:String},requestOptions:{type:Object,default:function(){return{method:"POST"}}},uploadFileField:{type:String,default:"file"},uploadFileName:{type:[String,Function]},uploadFormData:{type:FormData,default:function(){return new FormData}},cropperOptions:{type:Object,default:function(){return{aspectRatio:1,autoCropArea:1,viewMode:1,movable:!1,zoomable:!1}}},outputOptions:{type:Object},outputMime:{type:String,default:null},outputQuality:{type:Number,default:.9},mimes:{type:String,default:"image/png, image/gif, image/jpeg, image/bmp, image/x-icon"},capture:{type:String},labels:{type:Object,default:function(){return{submit:"Ok",cancel:"Cancel"}}},inline:{type:Boolean,default:!1}},data:function(){return{cropper:void 0,dataUrl:void 0,fileName:void 0,mimeType:void 0}},computed:{cleanedMimes:function(){if(!this.mimes)throw new Error("vue-avatar-cropper: mimes prop cannot be empty");return this.mimes.trim().toLowerCase()}},watch:{modelValue:function(e){e&&(this.file?this.onFileChange(this.file):this.pickImage(),this.$emit("update:modelValue",!1))}},mounted:function(){this.$emit("update:modelValue",!1)},methods:{destroy:function(){this.cropper&&this.cropper.destroy(),this.$refs.input&&(this.$refs.input.value=""),this.dataUrl=void 0},submit:function(){this.$emit("submit"),this.uploadUrl?this.uploadImage():this.uploadHandler?this.uploadHandler(this.cropper):this.$emit("error",{type:"user",message:"No upload handler found"}),this.destroy()},cancel:function(){this.$emit("cancel"),this.destroy()},onImgElementError:function(){this.$emit("error",{type:"load",message:"File loading failed"}),this.destroy()},pickImage:function(){this.$refs.input&&this.$refs.input.click()},onFileChange:function(e){var t=this;if("image/*"===this.cleanedMimes){if("image"!==e.type.split("/")[0])return void this.$emit("error",{type:"user",message:"File type not correct"})}else if(this.cleanedMimes){var r=this.cleanedMimes.split(", ").find((function(t){return t===e.type}));if(!r)return void this.$emit("error",{type:"user",message:"File type not correct"})}var a=new FileReader;a.onload=function(e){t.dataUrl=e.target.result},a.readAsDataURL(e),this.fileName=e.name||"unknown",this.mimeType=e.type,this.$emit("changed",{file:e,reader:a})},onFileInputChange:function(e){e.target.files&&e.target.files[0]&&this.onFileChange(e.target.files[0])},createCropper:function(){this.cropper=new a(this.$refs.img,this.cropperOptions)},getFilename:function(e){var t=n.getExtension(e.type);if(!this.uploadFileName){var r=this.fileName,a=this.fileName.split(".");return a.length>1&&(r=a.slice(0,-1).join(".")),"".concat(r,".").concat(t)}return"string"==typeof this.uploadFileName?this.uploadFileName:"function"==typeof this.uploadFileName?this.uploadFileName({filename:this.fileName,mime:e.type,extension:t}):"unknown.".concat(t)},uploadImage:function(){var a=this;this.cropper.getCroppedCanvas(this.outputOptions).toBlob(function(){var n=t(r.mark((function t(n){var i,o,p,l,c,s,u,m,d;return r.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:for(o in i=new FormData,a.uploadFormData.entries())p=e(o,2),l=p[0],c=p[1],i.append(l,c);return i.append(a.uploadFileField,n,a.getFilename(n)),s=Object.assign({body:i},a.requestOptions),u=new Request(a.uploadUrl,s),m=fetch(u),a.$emit("uploading",{form:i,request:u,response:m}),t.next=9,m;case 9:d=t.sent,a.$emit("completed",{form:i,request:u,response:d}),d.ok?a.$emit("uploaded",{form:i,request:u,response:d}):a.$emit("error",{type:"upload",message:"Image upload fail",context:{request:u,response:d}});case 12:case"end":return t.stop()}}),t)})));return function(e){return n.apply(this,arguments)}}(),this.outputMime||this.mimeType,this.outputQuality)}}}),f={class:"avatar-cropper"},h={key:0,class:"avatar-cropper-mark"},v=["title"],g={class:"avatar-cropper-container"},y={class:"avatar-cropper-image-container"},b=["src"],x={class:"avatar-cropper-footer"},F=["accept","capture"];!function(e,t){void 0===t&&(t={});var r=t.insertAt;if(e&&"undefined"!=typeof document){var a=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css","top"===r&&a.firstChild?a.insertBefore(n,a.firstChild):a.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}}(".avatar-cropper .avatar-cropper-overlay {\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 99999; }\n\n.avatar-cropper .avatar-cropper-overlay-inline {\n position: initial; }\n\n.avatar-cropper .avatar-cropper-img-input {\n display: none; }\n\n.avatar-cropper .avatar-cropper-close {\n float: right;\n padding: 20px;\n font-size: 3rem;\n color: #fff;\n font-weight: 100;\n text-shadow: 0px 1px rgba(40, 40, 40, 0.3); }\n\n.avatar-cropper .avatar-cropper-mark {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.1); }\n\n.avatar-cropper .avatar-cropper-container {\n background: #fff;\n z-index: 999;\n box-shadow: 1px 1px 5px rgba(100, 100, 100, 0.14); }\n .avatar-cropper .avatar-cropper-container .avatar-cropper-image-container {\n position: relative;\n max-width: 400px;\n height: 300px; }\n .avatar-cropper .avatar-cropper-container img {\n max-width: 100%;\n height: 100%; }\n .avatar-cropper .avatar-cropper-container .avatar-cropper-footer {\n display: flex;\n align-items: stretch;\n align-content: stretch;\n justify-content: space-between; }\n .avatar-cropper .avatar-cropper-container .avatar-cropper-footer .avatar-cropper-btn {\n width: 50%;\n padding: 15px 0;\n cursor: pointer;\n border: none;\n background: transparent;\n outline: none; }\n .avatar-cropper .avatar-cropper-container .avatar-cropper-footer .avatar-cropper-btn:hover {\n background-color: #2aabd2;\n color: #fff; }\n"),d.render=function(e,t,r,a,n,i){return o(),p("div",f,[e.dataUrl?(o(),p("div",{key:0,class:l(["avatar-cropper-overlay",{"avatar-cropper-overlay-inline":e.inline}])},[e.inline?s("",!0):(o(),p("div",h,[c("a",{onClick:t[0]||(t[0]=function(){return e.cancel&&e.cancel.apply(e,arguments)}),class:"avatar-cropper-close",title:e.labels.cancel,href:"javascript:;"}," × ",8,v)])),c("div",g,[c("div",y,[c("img",{ref:"img",src:e.dataUrl,alt:"",onLoad:t[1]||(t[1]=u((function(){return e.createCropper&&e.createCropper.apply(e,arguments)}),["stop"])),onError:t[2]||(t[2]=function(){return e.onImgElementError&&e.onImgElementError.apply(e,arguments)})},null,40,b)]),c("div",x,[c("button",{onClick:t[3]||(t[3]=u((function(){return e.cancel&&e.cancel.apply(e,arguments)}),["stop","prevent"])),class:"avatar-cropper-btn"},m(e.labels.cancel),1),c("button",{onClick:t[4]||(t[4]=u((function(){return e.submit&&e.submit.apply(e,arguments)}),["stop","prevent"])),class:"avatar-cropper-btn"},m(e.labels.submit),1)])])],2)):s("",!0),e.file?s("",!0):(o(),p("input",{key:1,accept:e.cleanedMimes,capture:e.capture,class:"avatar-cropper-img-input",ref:"input",type:"file",onChange:t[5]||(t[5]=function(){return e.onFileInputChange&&e.onFileInputChange.apply(e,arguments)})},null,40,F))])},d.install=function(e){e.component("avatar-cropper",d)};export{d as default};