1 /** 2 * rem 自动计算 3 * 根据浏览器宽度对比最大宽度,得出百分值,并转化为像素写入 html.style.font-size 4 * @param {number} max = 750 最大宽度 5 * @param {number} min = 320 最小宽度 6 * @return {() => void} 返回计算函数,默认调用一次 7 */ 8 export const autosize = (max = 750, min = 320) => { 9 const htmlstyle: any = document.getElementsByTagName('html')[0].style; 10 const w: number = innerWidth; 11 const resize: () => void = () => { 12 htmlstyle.fontSize = (((w > max && max) || (w < min && min) || w) / max) * 100 + 'px'; 13 }; 14 resize(); 15 return resize; 16 }; 17 18 /** 19 * 异步暂停 20 * @param {number} timeOut 暂停时间 21 */ 22 export const sleep = (timeOut: number) => new Promise(resolve => setTimeout(resolve, timeOut)); 23 24 /** 25 * 获取范围内随机数 26 * @param {number} min 最小值 27 * @param {number} max 最大值 28 */ 29 export const randomInt = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min; 30 31 32 /** 33 * 获取图片对象 34 * @param {string} src 图片地址 35 * @return {Promise} 图片加载后返回图片对象 36 */ 37 export const getImg = (src: string): Promise<HTMLImageElement> => 38 new Promise((resolve, reject) => { 39 const img = new Image(); 40 img.src = src; 41 img.onload = () => resolve(img); 42 img.onerror = reject; 43 }); 44 45 /** 46 * 批量获取图片对象 47 * @param {string[]} srcs 图片地址列表 48 * @return {Promise} 图片加载后返回图片对象列表 49 */ 50 export const getImgBatch = (srcs: string[]) => Promise.all(srcs.map(getImg)); 51 52 /** 53 * 文件组转文件数组 54 * @param {FileList} files 文件流 55 */ 56 export const getFileList = (files: FileList) => { 57 const fileList: File[] = []; 58 for (let i = 0, file; (file = fileList[i++]); ) { 59 fileList.push(file); 60 } 61 return fileList; 62 }; 63 64 /** 65 * 文件转Base64 66 * @param {File} file 待转化文件 67 * @return {Promise} 转化后返回Base64 68 */ 69 export const fileToBase64 = (file: File): Promise<string> => 70 new Promise(resolve => { 71 const reader = new FileReader(); 72 reader.onload = () => resolve(reader.result as string); 73 reader.readAsDataURL(file); 74 }); 75 76 /** 77 * 批量文件转base64 78 * @param {FileList} files 待转化文件列表 79 * @return {Promise} 转化后返回Base64列表 80 */ 81 export const fileToBase64Batch = (files: FileList) => Promise.all(getFileList(files).map(fileToBase64)); 82 83 /** 84 * Base64转文件 85 * @param {string} dataUrl 待转化Base64字符串 86 * @param {[type]} filename = 'file' 转化后文件名 87 * @return {Promise} 转化后返回File对象 88 */ 89 export const base64ToFile = async (dataUrl: string, filename = 'file') => { 90 const data: string[] = dataUrl.split(','); 91 const type: string = data[0].slice(5, -7); 92 const ext: string = type.split('/')[1]; 93 const bstr: string = atob(data[1]); 94 let n = bstr.length; 95 const u8arr = new Uint8Array(n); 96 while (n--) { 97 u8arr[n] = bstr.charCodeAt(n); 98 } 99 return new File([u8arr], `${filename}.${ext}`, { 100 type, 101 }); 102 }; 103 104 /** 105 * 批量Base64转文件 106 * @param {string[]} dataUrls 待转化Base64字符串列表 107 * @param {string[]} filenames 转化后文件名列表 108 * @return {Promise} 转化后返回File对象列表 109 */ 110 export const base64ToFileBatch = (dataUrls: string[], filenames?: string[]) => { 111 return Promise.all( 112 dataUrls.map((dataUrl, index) => { 113 return base64ToFile(dataUrl, filenames ? filenames[index] : undefined); 114 }) 115 ); 116 }; 117 118 type TImg = string | File; 119 interface ICropConfig { 120 quality?: number; // 图片质量 121 x?: number; // 裁剪起点 122 y?: number; // 裁剪起点 123 width?: number; // 裁剪尺寸 124 height?: number; // 裁剪尺寸 125 zoom?: number; // 缩放 126 } 127 128 /** 129 * 图片裁剪 130 * 如配置 quality 图片质量,图片将自动转为 jpg 格式 131 * @param {string | File} image base64 | 文件对象 132 * @param {ICropConfig} config 裁剪配置 133 * @return {Promise} 裁剪后返回base64 134 */ 135 export const crop = async (image: TImg, config: ICropConfig) => { 136 const base64 = image instanceof File ? await fileToBase64(image) : image; 137 const img = await getImg(base64); 138 const { quality, x = 0, y = 0, width = img.width, height = img.height, zoom = 1 } = config; 139 const canvas: HTMLCanvasElement = document.createElement('canvas'); 140 const ctx = canvas.getContext('2d'); 141 ctx!.drawImage(img, x, y, width, height, 0, 0, (canvas.width = width * zoom), (canvas.height = height * zoom)); 142 return canvas.toDataURL(!quality || quality === 1 ? base64.split(',')[0].slice(5, -7) : 'image/jpeg', quality); 143 }; 144 145 /** 146 * 批量图片裁剪 147 * 如配置 quality 图片质量,图片将自动转为 jpg 格式 148 * @param {TImg[]} images base64 | 文件对象 列表 149 * @param {ICropConfig} config 裁剪配置 150 * @return {Promise} 裁剪后返回base64列表 151 */ 152 export const cropBatch = (images: TImg[], config: ICropConfig) => { 153 return Promise.all(images.map(image => crop(image, config))); 154 }; 155 156 157 158 // 清除所有空格 159 export const trim = (str: string) => str.replace(/\s/g, ''); 160 161 // 转json 162 export const toJson = (json = '[]', defaults = []) => { 163 try { 164 return JSON.parse(json); 165 } catch (e) { 166 return defaults; 167 } 168 }; 169 170 // 转json字符串 171 export const toJsonText = (data: object, defaults = '{}') => { 172 try { 173 return JSON.stringify(data, null, 4); 174 } catch (e) { 175 return defaults; 176 } 177 }; 178 179 180 /** 181 * rem 自动计算 182 * 根据浏览器宽度对比最大宽度,得出百分值,并转化为像素写入 html.style.font-size 183 * @param {number} max = 750 最大宽度 184 * @param {number} min = 320 最小宽度 185 * @return {() => void} 返回计算函数,默认调用一次 186 */ 187 export const autosize = (max = 750, min = 320) => { 188 const htmlstyle: any = document.getElementsByTagName('html')[0].style; 189 const w: number = innerWidth; 190 const resize: () => void = () => { 191 htmlstyle.fontSize = (((w > max && max) || (w < min && min) || w) / max) * 100 + 'px'; 192 }; 193 resize(); 194 return resize; 195 }; 196 197 /** 198 * 异步暂停 199 * @param {number} timeOut 暂停时间 200 */ 201 export const sleep = (timeOut: number) => new Promise(resolve => setTimeout(resolve, timeOut)); 202 203 /** 204 * 获取范围内随机数 205 * @param {number} min 最小值 206 * @param {number} max 最大值 207 */ 208 export const randomInt = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min; 209 210 211 /** 212 * 插入标签到页面 213 * @param {HTMLElement} element 待插入元素 214 * @param {HTMLElement} body = document.body 插入的容器 215 * @return {Promise} 标签插入后返回 216 */ 217 export const installElement = (element: HTMLElement, body = document.body) => 218 new Promise(resolve => { 219 body.appendChild(element); 220 if (element instanceof HTMLLinkElement || element instanceof HTMLScriptElement) { 221 element.onload = () => resolve(element); 222 } else { 223 resolve(element); 224 } 225 }); 226 227 /** 228 * 插入脚本 229 * @param {string} src 脚本地址 230 */ 231 export const installScript = (src: string) => { 232 const script = document.createElement('script'); 233 script.src = src; 234 return installElement(script); 235 }; 236 237 /** 238 * 插入样式 239 * @param {string} href 样式地址 240 */ 241 export const installLink = (href: string) => { 242 const link = document.createElement('link'); 243 link.rel = 'stylesheet'; 244 link.href = href; 245 return installElement(link); 246 };