ts 二次封装图片上传前进行压缩
t-jian 时间:2022-01-18
namespace FileUploader { export class Init { constructor(args: any) { return new Uploader(args); } } class Uploader { private lrz: any; private file: any; private formData: FormData = new FormData(); private uploaderDom:any; public option: UploaderOption = new UploaderOption() constructor(arg: any) { var _this=this; this.option = Object.assign(this.option, arg); this.lrz = window.lrz; if(this.lrz==undefined){ this.loadJS('https://cdn.jsdelivr.net/gh/t-jian/static/js/lrz-4.9.41/lrz.all.bundle.js',()=>{ this.lrz=window.lrz; }) } if(this.option.isShowLoading){ this.uploaderDom= document.querySelector(".uploader-box") if(this.uploaderDom==null){ let css='.uploader-box{display:none;width:100%;height:100%;background-color:rgba(100,100,100,0.65);z-index:10;position:fixed;}.uploader-box .loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border:3px solid #f3f3f3;border-top:3px solid #555;border-radius:100%;width:40px;height:40px;display:inline-block;animation:loaderSpin 1.5s linear infinite;}@keyframes loaderSpin{0%{transform:rotate(0deg);}100%{transform:rotate(360deg);}}'; this.createStyleSheet(css); let nodeBox=document.createElement("div"); nodeBox.className="uploader-box"; let node= document.createElement("div"); node.className="loader"; nodeBox.appendChild(node); document.querySelector(this.option.inputFileBox==""?this.option.inputId:this.option.inputFileBox).parentNode.appendChild(nodeBox); this.uploaderDom= document.querySelector(".uploader-box"); } } if(this.option.beforeUpload==null){ this.option.beforeUpload=this.beforeUploadCallback; } if(arg.file==null){ this.changeFileUpload(); }else{ this.compressHandle().then(res => { if (_this.option.autoUpload) { _this.request(); } }) } } private changeFileUpload() { let _this = this; let fileInput = document.querySelector(this.option.inputId); if (fileInput == undefined || fileInput == null) { console.error("no find input "); return; } fileInput.addEventListener('change', function () { let file = this.files[0]; _this.file = file; _this.compressHandle().then(res => { if (_this.option.autoUpload) { _this.request(); } }) }) } private beforeUploadCallback(file:any){ return true; } private compressHandle() { var _this = this; if(!_this.option.beforeUpload(_this.file)) return; return new Promise(function (resolve, reject) { if (_this.option.isCompress) { if(_this.lrz==undefined||_this.lrz==null){ _this.createOriginalFormData(resolve); }else{ _this.compress(_this.file).then((rst: any) => { _this.formData = rst.formData; _this.appendExtendformData(_this.formData); resolve(true); }).catch((err: any) => { console.error(err,"压缩异常"); _this.createOriginalFormData(resolve); }) } } else { _this.createOriginalFormData(resolve); } }) } private showOrHideLoading(b=true){ this.uploaderDom.setAttribute("style",b?"display:block":"display:none"); } private createOriginalFormData(resolve:any) { var _this=this; var formData = new FormData(); this.appendExtendformData(formData); this.fileConvertBase64(this.file).then((res:any)=>{ formData.append(this.option.fieldName, _this.convertBase64UrlToBlob(res),_this.file.name); _this.formData=formData; resolve(true); }); } private appendExtendformData(formData: any) { //追加扩展 if (this.option.requestExtendData != null) { Object.keys(this.option.requestExtendData).forEach(function (key) { formData.append(key, this.option.requestExtendData[key]); }); } } /** * 文件压缩 * @param file 文件 */ private compress(file: any) { var _this = this; var lrzOption: any = { quality: this.option.quality > 1 ? 1 : this.option.quality < 0 ? 0 : this.option.quality, fieldName: this.option.fieldName }; return new Promise(function (resolve, reject) { _this.fileConvertBase64(file).then((res:any)=>{ var img=new Image(); img.src=res; img.onload = function(e){ let tWidth = 0,theight=0; if(_this.option.width==null){ if (_this.option.scale !=0) { tWidth = _this.option.scale * img.width; } else { tWidth = img.width; } }else{ tWidth=_this.option.width; if(img.width<tWidth){ tWidth=img.width; } } lrzOption.width = tWidth; if(_this.option.height==null){ if (_this.option.scale !=0) { theight = _this.option.scale * img.height; } else { theight = img.height; } }else{ theight=_this.option.width; if(img.height<theight){ theight=img.height; } } lrzOption.width = Math.floor(tWidth); lrzOption.height = Math.floor(theight); if(_this.option.maxWidth!=null&&tWidth>_this.option.maxWidth){ lrzOption.width=_this.option.maxWidth; } _this.lrz(file, lrzOption).then(resolve).catch(reject).always(() => {console.log("进入压缩流程")}); } }).catch((err:any)=>{ _this.lrz(file, lrzOption).then(resolve).catch(reject).always(() => {console.log("进入压缩流程")}); }) }); } /** * 上传 * @param formData 数据对象 */ private request() { if(this.option.httpResult!=null){ if (typeof this.option.httpResult == "function") { this.option.httpResult(this.formData,this.file); return; } } var _this = this; _this.showOrHideLoading(); var xhr = new XMLHttpRequest(); xhr.open('POST', _this.option.url); if(this.option.requestHeader!=null){ Object.keys(this.option.requestHeader).forEach(function (key) { xhr.setRequestHeader(key,this.option.requestHeader[key]); }); } xhr.onload = function () { var data = JSON.parse(xhr.response); if (xhr.status === 200) { if (typeof _this.option.success == "function") { _this.option.success(data); } _this.option.progress = 0; } else { if (typeof _this.option.fail == "function") { _this.option.fail(data); } } _this.showOrHideLoading(false); }; xhr.onerror = function (err) { if (typeof _this.option.fail == "function") { _this.option.fail(err); } _this.showOrHideLoading(false); }; if (xhr.upload) { try { xhr.upload.addEventListener('progress', function (e) { if (!e.lengthComputable) return false; if (typeof _this.option.progressCallback == "function") { _this.option.progressCallback(e); } }); } catch (err) { console.error('进度展示出错了,似乎不支持此特性?', err); } } console.log(_this.formData, 999) xhr.send(_this.formData); } /** * 将文件转成base64 * @param file 文件 * @returns */ private fileConvertBase64(file:any){ return new Promise(function (resolve, reject) { if(window.FileReader) { var reads = new FileReader(); reads.readAsDataURL(file); reads.onload = function (e) { resolve(this.result); } reads.onerror=function(e){ reject(e); } } else { console.info("Not supported by your browser!"); reject("Not supported by your browser!") } }) } /** * 将base64 转成 blob * @param urlData base64 * @returns */ private convertBase64UrlToBlob(urlData:string) { var arr = urlData.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); } private loadJS(url:string, callback:any ){ var script = document.createElement('script'); var fn = callback || function(){}; script.type = 'text/javascript'; script.onload = function(){ fn();}; script.src = url; document.getElementsByTagName('head')[0].appendChild(script); } private createStyleSheet(css:string) { var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; style.textContent=css; head.appendChild(style); return style.sheet; } /** * 用于主动上传 * @returns */ public Invoke(){ if(this.file=null){ console.error("file is null"); return; } this.request(); } } class UploaderOption { public inputId: string = "#inputId";//文件域id public inputFileBox:string="";//input 外层盒子 可用于loading区域,空时取文件域的最外层 public isCompress: boolean = true;//默认压缩 public autoUpload: boolean = true;//是否自动上传 public url: string; public quality: number = 0.8;//图片压缩质量,取值 0 - 1,默认为0.8 public scale:number=0.9;//图片大小缩放 public width: number;//图片最大不超过的宽度,默认为原图宽度,高度不设时会适应宽度 public maxWidth:number;//图片最大宽度 public height: number;// 同上 public fieldName: string = "file";//后端接收的字段名,默认:file public progress: number = 0; public isShowLoading:boolean=true;//是否显示loading public beforeUpload:any;//上传文件之前的钩子,参数为上传的文件。 若返回true才触发上传 public success: any;//文件上传成功 public fail: any;//文件上传失败 public progressCallback: any;//进度条回调 public httpResult:any;//允许重写上传但无法触发success、fail、progressCallback 函数 public requestHeader:any;//允许设置请求头 public requestExtendData: any;//允许提交额外的参数 constructor() { return this; } } }
使用
var uploader= FileUploader.Init({ inputId: "#upload-container", quality: 0.85, scale: 0.8, maxWidth:800, autoUpload:true, url: "xxx/file/upload", beforeUpload:file=>{ return true; }, progressCallback:function(e){ console.log(e,5555) }, success: res => { console.log(res, 7777) }, fail: res => { console.log(res, 666) } }); function up(){ uploader.Invoke(); }
特别声明:本站部分内容收集于互联网是出于更直观传递信息的目的。该内容版权归原作者所有,并不代表本站赞同其观点和对其真实性负责。如该内容涉及任何第三方合法权利,请及时与824310991@qq.com联系,我们会及时反馈并处理完毕。