123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- import { Pos } from "@/utils/math.ts";
- import { v4 as uuid } from "uuid";
- /**
- * 四舍五入
- * @param num
- * @param b 保留位数
- * @returns
- */
- export const round = (num: number, b: number = 2) => {
- const scale = Math.pow(10, b);
- return Math.round(num * scale) / scale;
- };
- /**
- * 范围取余
- * @param num
- * @param mod
- */
- export const rangMod = (num: number, mod: number) => ((num % mod) + mod) % mod;
- /**
- * 有偏差的indexOf
- * @param arr
- * @param warp
- * @param val
- * @returns
- */
- export const warpIndexOf = (arr: number[], warp: number, val: number) =>
- arr.findIndex((num) => val >= num - warp && val <= num + warp);
- /**
- * 多个函数合并成一个函数
- * @param fns
- * @returns
- */
- export const mergeFuns = (...fns: (() => void)[] | (() => void)[][]) => {
- return () => {
- fns.forEach((fn) => {
- if (Array.isArray(fn)) {
- fn.forEach((f) => f());
- } else {
- fn();
- }
- });
- };
- };
- export const copy = <T>(data: T): T => JSON.parse(JSON.stringify(data));
- /**
- * 获取数据类型
- * @param value
- * @returns
- */
- export const toRawType = (value: unknown): string =>
- Object.prototype.toString.call(value).slice(8, -1);
- // 是否修改
- const _inRevise = (raw1: any, raw2: any, readly: Set<[any, any]>): boolean => {
- if (raw1 === raw2) return false;
- const rawType1 = toRawType(raw1);
- const rawType2 = toRawType(raw2);
- if (rawType1 !== rawType2) {
- return true;
- } else if (
- rawType1 === "String" ||
- rawType1 === "Number" ||
- rawType1 === "Boolean"
- ) {
- if (rawType1 === "Number" && isNaN(raw1) && isNaN(raw2)) {
- return false;
- } else {
- return raw1 !== raw2;
- }
- }
- const rawsArray = Array.from(readly.values());
- for (const raws of rawsArray) {
- if (raws.includes(raw1) && raws.includes(raw2)) {
- return false;
- }
- }
- readly.add([raw1, raw2]);
- if (rawType1 === "Array") {
- return (
- raw1.length !== raw2.length ||
- raw1.some((item1: any, i: number) => _inRevise(item1, raw2[i], readly))
- );
- } else if (rawType1 === "Object") {
- const rawKeys1 = Object.keys(raw1).sort();
- const rawKeys2 = Object.keys(raw2).sort();
- return (
- _inRevise(rawKeys1, rawKeys2, readly) ||
- rawKeys1.some((key) => _inRevise(raw1[key], raw2[key], readly))
- );
- } else if (rawType1 === "Map") {
- const rawKeys1 = Array.from(raw1.keys()).sort();
- const rawKeys2 = Array.from(raw2.keys()).sort();
- return (
- _inRevise(rawKeys1, rawKeys2, readly) ||
- rawKeys1.some((key) => _inRevise(raw1.get(key), raw2.get(key), readly))
- );
- } else if (rawType1 === "Set") {
- return inRevise(Array.from(raw1.values()), Array.from(raw2.values()));
- } else {
- return raw1 !== raw2;
- }
- };
- /**
- * 查看数据是否被修改
- * @param raw1
- * @param raw2
- * @returns
- */
- export const inRevise = (raw1: any, raw2: any) =>
- _inRevise(raw1, raw2, new Set());
- // 防抖
- export const debounce = <T extends (...args: any) => any>(
- fn: T,
- delay: number = 160
- ) => {
- let timeout: any;
- return function (...args: Parameters<T>) {
- clearTimeout(timeout);
- timeout = setTimeout(() => {
- fn.apply(null, args);
- }, delay);
- };
- };
- /**
- * 获取数据变化
- * @param newIds
- * @param oldIds
- * @returns
- */
- export const getChangePart = <T>(newIds: T[], oldIds: T[] = []) => {
- const addPort = newIds.filter((newId) => !oldIds.includes(newId));
- const delPort = oldIds.filter((oldId) => !newIds.includes(oldId));
- const holdPort = oldIds.filter((oldId) => newIds.includes(oldId));
- return { addPort, delPort, holdPort };
- };
- export const flatPositions = (positions: Pos[]) =>
- positions.flatMap((p) => [p.x, p.y]);
- export const flatToPositions = (coords: number[]) => {
- const positions: Pos[] = [];
- for (let i = 0; i < coords.length; i += 2) {
- positions.push({
- x: coords[i],
- y: coords[i + 1],
- });
- }
- return positions;
- };
- export const onlyId = () => uuid();
- export const startAnimation = (update: () => void, dur = -1) => {
- let isStop = false;
- const animation = () => {
- requestAnimationFrame(() => {
- if (!isStop) {
- update();
- animation();
- }
- });
- };
- animation();
- let timeout: any;
- if (dur >= 0) {
- setTimeout(() => (isStop = true), dur);
- }
- return () => {
- clearTimeout(timeout);
- isStop = true;
- };
- };
- export const arrayInsert = <T>(
- array: T[],
- item: T,
- canInsert: (eItem: T, insertItem: T) => boolean
- ) => {
- let i = 0;
- for (i = 0; i < array.length; i++) {
- if (canInsert(array[i], item)) {
- break;
- }
- }
- array.splice(i, 0, item);
- return array;
- };
- export const asyncTimeout = (time: number) => {
- let timeout: any;
- let reject: any
- const promise = new Promise<void>((resolve, r) => {
- timeout = setTimeout(resolve, time);
- reject = r
- }) as Promise<void> & { stop: () => void };
- promise.stop = () => {
- clearTimeout(timeout);
- reject('取消')
- };
- return promise;
- };
|