123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- 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);
- };
- };
- // 防抖
- export const frameEebounce = <T extends (...args: any) => any>(fn: T) => {
- let count = 0;
- return function (...args: Parameters<T>) {
- let current = ++count;
- requestAnimationFrame(() => {
- if (current === count) {
- fn.apply(null, args);
- }
- });
- };
- };
- /**
- * 获取数据变化
- * @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;
- };
- export const getResizeCorsur = (level = true, r = 0) => {
- r = rangMod(r, 360);
- if (level) {
- if ((r > 0 && r < 20) || (r > 160 && r <= 200)) {
- return "ew-resize";
- }
- if ((r >= 20 && r <= 70) || (r >= 200 && r <= 250)) {
- return "nwse-resize";
- } else if ((r > 70 && r < 110) || (r > 250 && r < 290)) {
- return "ns-resize";
- } else if ((r >= 110 && r <= 160) || (r >= 290 && r <= 340)) {
- return "nesw-resize";
- } else {
- return "ew-resize";
- }
- } else {
- if ((r > 0 && r < 20) || (r > 160 && r <= 200)) {
- return "ns-resize";
- }
- if ((r >= 20 && r <= 70) || (r >= 200 && r <= 250)) {
- return "nesw-resize";
- } else if ((r > 70 && r < 110) || (r > 250 && r < 290)) {
- return "ew-resize";
- } else if ((r >= 110 && r <= 160) || (r >= 290 && r <= 340)) {
- return "nwse-resize";
- } else {
- return "ns-resize";
- }
- }
- };
- export const diffArrayChange = <T extends Array<any>>(
- newItems: T,
- oldItems: T
- ) => {
- const addedItems = [] as unknown as T;
- const deletedItems = [] as unknown as T;
- for (const item of newItems) {
- if (!oldItems.includes(item)) {
- addedItems.push(item);
- }
- }
- for (const item of oldItems) {
- if (!newItems.includes(item)) {
- deletedItems.push(item);
- }
- }
- return {
- added: addedItems,
- deleted: deletedItems,
- };
- };
- const DMSRG =
- /(\d+(?:\.\d+)?)°(?:(\d+(?:\.\d+)?)['|′])?(?:(\d+(?:\.\d+)?)["|″])?$/;
- export const dmsCheck = (dms: string) => {
- const r = DMSRG.exec(dms);
- return r && Number(r[2] || 0) < 60 && (Number(r[3]) || 0) < 60;
- };
- // 度分秒转经纬度
- export const toDigital = (dms: string) => {
- const r = DMSRG.exec(dms);
- if (r) {
- return round(
- Number(r[1]) + Number(r[2] || 0) / 60 + (Number(r[3]) || 0) / 3600,
- 12
- );
- }
- };
- export const analysisGPS = (temp: string) => {
- const getGPS = (t: any[]) => {
- t = t.map((d) => (dmsCheck(d) ? toDigital(d) : Number(d)));
- if (t.length > 1 && t.every((v) => !Number.isNaN(v))) {
- return {
- x: t[0],
- y: t[1],
- } as Pos;
- }
- };
- function isValidWGS84(lon: number, lat: number) {
- const isValidLon = lon >= -180 && lon <= 180;
- const isValidLat = lat >= -90 && lat <= 90;
- return isValidLon && isValidLat;
- }
- const splitChars = [",", " ", ","];
- for (const splitChar of splitChars) {
- const gps = getGPS(temp.split(splitChar));
- if (gps && isValidWGS84(gps.x, gps.y)) {
- return gps;
- }
- }
- };
- export const tempStrFill = (tempStr: string, fill: Record<string, any>) => {
- const regex = /\{(.*?)\}/g;
- let str = "";
- let ndx = 0;
- let matches;
- while ((matches = regex.exec(tempStr)) !== null) {
- if (!(matches[1] in fill)) continue;
- str += tempStr.substring(ndx, matches.index) + fill[matches[1]];
- ndx = matches.index + matches[0].length;
- }
- str += tempStr.substring(ndx, tempStr.length);
- return str;
- };
- export const genBound = () => {
- let seted = false;
- let minX = Number.MAX_VALUE,
- minY = Number.MAX_VALUE,
- maxX = Number.MIN_VALUE,
- maxY = Number.MIN_VALUE;
- return {
- update(points: Pos | Pos[]) {
- console.log(points)
- points = Array.isArray(points) ? points : [points];
- points.forEach((pos) => {
- seted = true;
- minX = Math.min(pos.x, minX);
- minY = Math.min(pos.y, minY);
- maxX = Math.max(pos.x, maxX);
- maxY = Math.max(pos.y, maxY);
- });
- },
- get() {
- if (!seted) return null;
- return {
- x: minX,
- y: minY,
- width: maxX - minX,
- height: maxY - minY,
- maxX,
- maxY,
- center: {
- x: (minX + maxX) / 2,
- y: (minY + maxY) / 2,
- },
- };
- },
- };
- };
- export const validNum = (num: any) => typeof num === 'number' && !Number.isNaN(num)
|