@hognevevle/vue-avatar-cropper
Version:
A simple and elegant component to crop and upload avatars
2 lines (1 loc) • 5.95 kB
JavaScript
(function(s,p){typeof exports=="object"&&typeof module!="undefined"?module.exports=p(require("cropperjs/dist/cropper.css"),require("cropperjs"),require("mime/lite"),require("vue")):typeof define=="function"&&define.amd?define(["cropperjs/dist/cropper.css","cropperjs","mime/lite","vue"],p):(s=typeof globalThis!="undefined"?globalThis:s||self,s["vue-avatar-cropper"]=p(null,s.Cropper,s.mime,s.Vue))})(this,function(s,p,f,r){"use strict";function u(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var h=u(p),g=u(f),V="",y=(e,t)=>{const i=e.__vccOpts||e;for(const[n,l]of t)i[n]=l;return i};const F={name:"AvatarCropper",model:{prop:"trigger",event:"triggered"},props:{trigger:{type:Boolean,default:!1},file:{type:File},uploadHandler:{type:Function},uploadUrl:{type:String},requestOptions:{type:Object,default(){return{method:"POST"}}},uploadFileField:{type:String,default:"file"},uploadFileName:{type:[String,Function]},uploadFormData:{type:FormData,default(){return new FormData}},cropperOptions:{type:Object,default(){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(){return{submit:"Ok",cancel:"Cancel"}}},inline:{type:Boolean,default:!1}},data(){return{cropper:void 0,dataUrl:void 0,fileName:void 0,mimeType:void 0}},computed:{cleanedMimes(){if(!this.mimes)throw new Error("vue-avatar-cropper: mimes prop cannot be empty");return this.mimes.trim().toLowerCase()}},watch:{trigger(e){!e||(this.file?this.onFileChange(this.file):this.pickImage(),this.$emit("triggered",!1))}},mounted(){this.$emit("triggered",!1)},methods:{destroy(){this.cropper&&this.cropper.destroy(),this.$refs.input&&(this.$refs.input.value=""),this.dataUrl=void 0},submit(){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(){this.$emit("cancel"),this.destroy()},onImgElementError(){this.$emit("error",{type:"load",message:"File loading failed"}),this.destroy()},pickImage(){this.$refs.input&&this.$refs.input.click()},onFileChange(e){if(this.cleanedMimes==="image/*"){if(e.type.split("/")[0]!=="image"){this.$emit("error",{type:"user",message:"File type not correct"});return}}else if(this.cleanedMimes&&!this.cleanedMimes.split(", ").find(n=>n===e.type)){this.$emit("error",{type:"user",message:"File type not correct"});return}const t=new FileReader;t.onload=i=>{this.dataUrl=i.target.result},t.readAsDataURL(e),this.fileName=e.name||"unknown",this.mimeType=e.type,this.$emit("changed",{file:e,reader:t})},onFileInputChange(e){!e.target.files||!e.target.files[0]||this.onFileChange(e.target.files[0])},createCropper(){this.cropper=new h.default(this.$refs.img,this.cropperOptions)},getFilename(e){const t=g.default.getExtension(e.type);if(!this.uploadFileName){let i=this.fileName;const n=this.fileName.split(".");return n.length>1&&(i=n.slice(0,-1).join(".")),`${i}.${t}`}return typeof this.uploadFileName=="string"?this.uploadFileName:typeof this.uploadFileName=="function"?this.uploadFileName({filename:this.fileName,mime:e.type,extension:t}):`unknown.${t}`},uploadImage(){this.cropper.getCroppedCanvas(this.outputOptions).toBlob(async e=>{const t=new FormData;for(const[o,j]in this.uploadFormData.entries())t.append(o,j);t.append(this.uploadFileField,e,this.getFilename(e));const i=Object.assign({body:t},this.requestOptions),n=new Request(this.uploadUrl,i),l=fetch(n);this.$emit("uploading",{form:t,request:n,response:l});const a=await l;this.$emit("completed",{form:t,request:n,response:a}),a.ok?this.$emit("uploaded",{form:t,request:n,response:a}):this.$emit("error",{type:"upload",message:"Image upload fail",context:{request:n,response:a}})},this.outputMime||this.mimeType,this.outputQuality)}}},_={class:"avatar-cropper"},C={key:0,class:"avatar-cropper-mark"},b=["title"],k={class:"avatar-cropper-container"},v={class:"avatar-cropper-image-container"},N=["src"],w={class:"avatar-cropper-footer"},E=["accept","capture"];function O(e,t,i,n,l,a){return r.openBlock(),r.createElementBlock("div",_,[l.dataUrl?(r.openBlock(),r.createElementBlock("div",{key:0,class:r.normalizeClass(["avatar-cropper-overlay",{"avatar-cropper-overlay-inline":i.inline}])},[i.inline?r.createCommentVNode("",!0):(r.openBlock(),r.createElementBlock("div",C,[r.createElementVNode("a",{onClick:t[0]||(t[0]=(...o)=>a.cancel&&a.cancel(...o)),class:"avatar-cropper-close",title:i.labels.cancel,href:"javascript:;"},"\xD7",8,b)])),r.createElementVNode("div",k,[r.createElementVNode("div",v,[r.createElementVNode("img",{ref:"img",src:l.dataUrl,alt:"",onLoad:t[1]||(t[1]=r.withModifiers((...o)=>a.createCropper&&a.createCropper(...o),["stop"])),onError:t[2]||(t[2]=(...o)=>a.onImgElementError&&a.onImgElementError(...o))},null,40,N)]),r.createElementVNode("div",w,[r.createElementVNode("button",{onClick:t[3]||(t[3]=r.withModifiers((...o)=>a.cancel&&a.cancel(...o),["stop","prevent"])),class:"avatar-cropper-btn"},r.toDisplayString(i.labels.cancel),1),r.createElementVNode("button",{onClick:t[4]||(t[4]=r.withModifiers((...o)=>a.submit&&a.submit(...o),["stop","prevent"])),class:"avatar-cropper-btn"},r.toDisplayString(i.labels.submit),1)])])],2)):r.createCommentVNode("",!0),i.file?r.createCommentVNode("",!0):(r.openBlock(),r.createElementBlock("input",{key:1,accept:a.cleanedMimes,capture:i.capture,class:"avatar-cropper-img-input",ref:"input",type:"file",onChange:t[5]||(t[5]=(...o)=>a.onFileInputChange&&a.onFileInputChange(...o))},null,40,E))])}var d=y(F,[["render",O]]);const m=e=>{m.installed||(m.installed=!0,e.component(d.name,d))};let c=null;return typeof window!="undefined"?c=window.Vue:typeof global!="undefined"&&(c=global.Vue),c&&c.use({install:m}),d});