diff --git a/src/array.ts b/src/array.ts new file mode 100644 index 0000000..3d6a464 --- /dev/null +++ b/src/array.ts @@ -0,0 +1,48 @@ +/** + * 本模块提供数组处理相关方法。 + * @packageDocumentation + */ + +/** + * 创建元组 + * @example + * ```typescript + * const tuple = genTuple(1, 2, '3'); + * console.log(tuple); // [1, 2, '3'],类型:[1, 2, '3'] + * ``` + */ +export const genTuple = (...args: T): T => args; + +/** + * 将数组分组 + * @param arr 数组 + * @param groupLen 每组数量 + * @returns 分组后的数组 + * @example + * ```typescript + * const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + * const groups = groupArray(arr, 3); + * console.log(groups); // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] + * ``` + */ +export function groupArray(arr: T[] = [], groupLen = 3) { + const groups: T[][] = []; + arr.forEach((item, index) => { + let group; + if (groups.length > 0) { + group = groups[groups.length - 1]; + } else { + groups.push([]); + group = groups[0]; + } + if ((index + 1) % groupLen === 0) { + group.push(item); + if (index + 1 < arr.length) { + groups.push([]); + } + } else { + group.push(item); + } + }); + return groups; +} diff --git a/src/color.ts b/src/color.ts new file mode 100644 index 0000000..892b212 --- /dev/null +++ b/src/color.ts @@ -0,0 +1,34 @@ +/** + * 本模块提供颜色处理相关方法。 + * @packageDocumentation + */ + +/** + * 将十六进制的颜色转换成 r、g、b 格式数组 + * @param hex 十六进制的颜色 + * @returns r、g、b 格式数组 + * @example + * ```typescript + * const rgb = hexToRGB('#000000'); + * console.log(rgb); // [0, 0, 0] + * ``` + */ +export function hexToRGB(hex: string): [number, number, number] { + let r = 0; + let g = 0; + let b = 0; + + if (hex.length === 7) { + r = parseInt(hex.slice(1, 3), 16); + g = parseInt(hex.slice(3, 5), 16); + b = parseInt(hex.slice(5, 7), 16); + } + + if (hex.length === 4) { + r = parseInt(hex.slice(1, 2), 16); + g = parseInt(hex.slice(2, 3), 16); + b = parseInt(hex.slice(3, 4), 16); + } + + return [r, g, b]; +} diff --git a/src/file.ts b/src/file.ts index aee9aee..c07b8dc 100644 --- a/src/file.ts +++ b/src/file.ts @@ -93,3 +93,43 @@ export function convertFileSize( return result; } + +/** + * 获取文件扩展名 + * @param fileName 文件名 + * @returns 文件扩展名 + * @example + * ```typescript + * const ext = getFileExtension('test.pdf'); + * console.log(ext); // pdf + * ``` + */ +export function getFileExtension(fileName: string): string { + const ext = fileName.split('.').pop(); + return ext || ''; +} + +export type FileType = 'pdf' | 'word' | 'ppt' | 'excel' | 'image' | 'other'; + +/** + * 根据文件扩展名推断文件类型 + * @param extension 文件扩展名 + * @returns 文件类型 + * @example + * ```typescript + * getFileType('test.pdf'); // pdf + * getFileType('test.docx'); // word + * getFileType('test.pptx'); // ppt + * getFileType('test.jpg'); // image + * getFileType('test.webp'); // image + * getFileType('test.txt'); // other + * ``` + */ +export function getFileType(fileName: string): FileType { + const ext = getFileExtension(fileName); + if (['pdf'].includes(ext)) return 'pdf'; + if (['doc', 'docx'].includes(ext)) return 'word'; + if (['ppt', 'pptx'].includes(ext)) return 'ppt'; + if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(ext)) return 'image'; + return 'other'; +} diff --git a/src/image.ts b/src/image.ts index b0cf169..4fa415c 100644 --- a/src/image.ts +++ b/src/image.ts @@ -313,3 +313,47 @@ export function compressHTMLImgs( }, ); } + +/** + * 获取图片地址的尺寸 + * @param url 图片地址 + * @returns 尺寸与图片实例 + * @example + * ```typescript + * const { width, height, imgTarget } = await getImgSize('https://example.com/image.jpg'); + * console.log(width, height); // 100 100 + * ``` + */ +export function getImgSize( + url: string, +): Promise<{ width: number; height: number; imgTarget: HTMLImageElement }> { + return new Promise<{ width: number; height: number; imgTarget: HTMLImageElement }>( + (resolve, reject) => { + const img = new Image(); + const resolvePromise = () => { + resolve({ + width: img.width, + height: img.height, + imgTarget: img, + }); + }; + img.onload = () => { + resolvePromise(); + }; + img.onerror = ( + event: Event | string, + source?: string, + lineno?: number, + colno?: number, + error?: Error, + ) => { + const reason = error?.message || '未知原因'; + reject(new Error(`获取图片尺寸失败:${reason}`)); + }; + img.src = url; + if (img.complete) { + resolvePromise(); + } + }, + ); +} diff --git a/src/json.ts b/src/json.ts index 965a39a..c2ab1a0 100644 --- a/src/json.ts +++ b/src/json.ts @@ -65,3 +65,38 @@ export function tryParseJSON( } return result; } + +/** + * 转换 JSON 字符串成对象 + * @param params 指定字符串。 + * @return 转换结果。 + * @example + * ```javascript + * parseJson('{"a": 1}'); // { success: true, data: { a: 1 } } + * parseJson('12&&**'); // { success: false, data: '12&&**' } + * ``` + */ +export function parseJson(params: string): + | { + success: true; + data: T; + } + | { + success: false; + data: string; + } { + let result: T | string = params; + + try { + result = JSON.parse(result) as T; + return { + success: true, + data: result, + }; + } catch (error) { + return { + success: false, + data: result as string, + }; + } +} diff --git a/src/timer.ts b/src/timer.ts new file mode 100644 index 0000000..fabe3d9 --- /dev/null +++ b/src/timer.ts @@ -0,0 +1,68 @@ +/** + * 本模块提供定时器相关方法。 + * @packageDocumentation + */ + +/** + * 通过 setTimeout 和递归来模拟 setInterval + * @param fn 回调函数 + * @param intervalTime 间隔时间 + * @param options 选项 + * @returns 清除函数 + */ +export function mockInterval( + fn: (...arg: unknown[]) => unknown, + intervalTime: number | (() => number), + options?: { + maxCount?: number; + immediate?: boolean; + }, +): { clear: () => void } { + const { maxCount = Infinity, immediate = false } = options || {}; + + let timer: number | undefined; + let intervalCount = 0; + + const getIntervalTime = () => { + return typeof intervalTime === 'function' ? intervalTime() : intervalTime; + }; + + const innerInterval = () => { + timer = window.setTimeout(() => { + fn(); + intervalCount++; + + if (intervalCount < maxCount) { + innerInterval(); + } else { + window.clearTimeout(timer); + } + }, getIntervalTime()); + }; + + if (immediate) { + fn(); + } + innerInterval(); + + return { + clear: () => { + // 处理 intervalTime 过少的情况,比如 100ms + window.setTimeout(() => { + window.clearTimeout(timer); + }, 0); + }, + }; +} + +/** + * 等待一段时间 + * @param time 等待时间 + */ +export function waitTime(time = 3000): Promise { + return new Promise(resolve => { + setTimeout(() => { + resolve(); + }, time); + }); +}