aboutsummaryrefslogtreecommitdiff
path: root/src/Utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/Utils.ts')
-rw-r--r--src/Utils.ts142
1 files changed, 104 insertions, 38 deletions
diff --git a/src/Utils.ts b/src/Utils.ts
index 2dd4eace4..8ab6207a9 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -2,10 +2,8 @@ import v4 = require('uuid/v4');
import v5 = require("uuid/v5");
import { Socket, Room } from 'socket.io';
import { Message } from './server/Message';
-import { RouteStore } from './server/RouteStore';
export namespace Utils {
-
export const DRAG_THRESHOLD = 4;
export function GenerateGuid(): string {
@@ -46,11 +44,16 @@ export namespace Utils {
}
export function CorsProxy(url: string): string {
- return prepend(RouteStore.corsProxy + "/") + encodeURIComponent(url);
+ return prepend("/corsProxy/") + encodeURIComponent(url);
+ }
+
+ export async function getApiKey(target: string): Promise<string> {
+ const response = await fetch(prepend(`environment/${target.toUpperCase()}`));
+ return response.text();
}
export function CopyText(text: string) {
- var textArea = document.createElement("textarea");
+ const textArea = document.createElement("textarea");
textArea.value = text;
document.body.appendChild(textArea);
textArea.focus();
@@ -62,14 +65,14 @@ export namespace Utils {
}
export function fromRGBAstr(rgba: string) {
- let rm = rgba.match(/rgb[a]?\(([ 0-9]+)/);
- let r = rm ? Number(rm[1]) : 0;
- let gm = rgba.match(/rgb[a]?\([ 0-9]+,([ 0-9]+)/);
- let g = gm ? Number(gm[1]) : 0;
- let bm = rgba.match(/rgb[a]?\([ 0-9]+,[ 0-9]+,([ 0-9]+)/);
- let b = bm ? Number(bm[1]) : 0;
- let am = rgba.match(/rgba?\([ 0-9]+,[ 0-9]+,[ 0-9]+,([ .0-9]+)/);
- let a = am ? Number(am[1]) : 1;
+ const rm = rgba.match(/rgb[a]?\(([ 0-9]+)/);
+ const r = rm ? Number(rm[1]) : 0;
+ const gm = rgba.match(/rgb[a]?\([ 0-9]+,([ 0-9]+)/);
+ const g = gm ? Number(gm[1]) : 0;
+ const bm = rgba.match(/rgb[a]?\([ 0-9]+,[ 0-9]+,([ 0-9]+)/);
+ const b = bm ? Number(bm[1]) : 0;
+ const am = rgba.match(/rgba?\([ 0-9]+,[ 0-9]+,[ 0-9]+,([ .0-9]+)/);
+ const a = am ? Number(am[1]) : 1;
return { r: r, g: g, b: b, a: a };
}
@@ -82,10 +85,10 @@ export namespace Utils {
// s /= 100;
// l /= 100;
- let c = (1 - Math.abs(2 * l - 1)) * s,
+ const c = (1 - Math.abs(2 * l - 1)) * s,
x = c * (1 - Math.abs((h / 60) % 2 - 1)),
- m = l - c / 2,
- r = 0,
+ m = l - c / 2;
+ let r = 0,
g = 0,
b = 0;
if (0 <= h && h < 60) {
@@ -114,10 +117,10 @@ export namespace Utils {
b /= 255;
// Find greatest and smallest channel values
- let cmin = Math.min(r, g, b),
+ const cmin = Math.min(r, g, b),
cmax = Math.max(r, g, b),
- delta = cmax - cmin,
- h = 0,
+ delta = cmax - cmin;
+ let h = 0,
s = 0,
l = 0;
// Calculate hue
@@ -153,19 +156,76 @@ export namespace Utils {
return Math.max(lower, Math.min(upper, n));
}
+ export function distanceBetweenHorizontalLines(xs: number, xe: number, y: number, xs2: number, xe2: number, y2: number): [number, number[]] {
+ if ((xs2 < xs && xe2 > xs) || (xs2 < xe && xe2 > xe) || (xs2 > xs && xe2 < xe)) return [Math.abs(y - y2), [Math.max(xs, xs2), y, Math.min(xe, xe2), y]];
+ if (xe2 < xs) return [Math.sqrt((xe2 - xs) * (xe2 - xs) + (y2 - y) * (y2 - y)), [xs, y, xs, y]];
+ //if (xs2 > xe)
+ return [Math.sqrt((xs2 - xe) * (xs2 - xe) + (y2 - y) * (y2 - y)), [xe, y, xe, y]];
+ }
+ export function distanceBetweenVerticalLines(x: number, ys: number, ye: number, x2: number, ys2: number, ye2: number): [number, number[]] {
+ if ((ys2 < ys && ye2 > ys) || (ys2 < ye && ye2 > ye) || (ys2 > ys && ye2 < ye)) return [Math.abs(x - x2), [x, Math.max(ys, ys2), x, Math.min(ye, ye2)]];
+ if (ye2 < ys) return [Math.sqrt((ye2 - ys) * (ye2 - ys) + (x2 - x) * (x2 - x)), [x, ys, x, ys]];
+ //if (ys2 > ye)
+ return [Math.sqrt((ys2 - ye) * (ys2 - ye) + (x2 - x) * (x2 - x)), [x, ye, x, ye]];
+ }
+
+ function project(px: number, py: number, ax: number, ay: number, bx: number, by: number) {
+
+ if (ax === bx && ay === by) return { point: { x: ax, y: ay }, left: false, dot: 0, t: 0 };
+ const atob = { x: bx - ax, y: by - ay };
+ const atop = { x: px - ax, y: py - ay };
+ const len = atob.x * atob.x + atob.y * atob.y;
+ var dot = atop.x * atob.x + atop.y * atob.y;
+ const t = Math.min(1, Math.max(0, dot / len));
+
+ dot = (bx - ax) * (py - ay) - (by - ay) * (px - ax);
+
+ return {
+ point: {
+ x: ax + atob.x * t,
+ y: ay + atob.y * t
+ },
+ left: dot < 1,
+ dot: dot,
+ t: t
+ };
+ }
+
+ export function closestPtBetweenRectangles(l: number, t: number, w: number, h: number,
+ l1: number, t1: number, w1: number, h1: number,
+ x: number, y: number) {
+ const r = l + w,
+ b = t + h;
+ const r1 = l1 + w1,
+ b1 = t1 + h1;
+ const hsegs = [[l, r, t, l1, r1, t1], [l, r, b, l1, r1, t1], [l, r, t, l1, r1, b1], [l, r, b, l1, r1, b1]];
+ const vsegs = [[l, t, b, l1, t1, b1], [r, t, b, l1, t1, b1], [l, t, b, r1, t1, b1], [r, t, b, r1, t1, b1]];
+ const res = hsegs.reduce((closest, seg) => {
+ const res = distanceBetweenHorizontalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
+ return (res[0] < closest[0]) ? res : closest;
+ }, [Number.MAX_VALUE, []] as [number, number[]]);
+ const fres = vsegs.reduce((closest, seg) => {
+ const res = distanceBetweenVerticalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
+ return (res[0] < closest[0]) ? res : closest;
+ }, res);
+
+ const near = project(x, y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
+ return project(near.point.x, near.point.y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
+ }
+
export function getNearestPointInPerimeter(l: number, t: number, w: number, h: number, x: number, y: number) {
- var r = l + w,
+ const r = l + w,
b = t + h;
- var x = clamp(x, l, r),
+ x = clamp(x, l, r),
y = clamp(y, t, b);
- var dl = Math.abs(x - l),
+ const dl = Math.abs(x - l),
dr = Math.abs(x - r),
dt = Math.abs(y - t),
db = Math.abs(y - b);
- var m = Math.min(dl, dr, dt, db);
+ const m = Math.min(dl, dr, dt, db);
return (m === dt) ? [x, t] :
(m === db) ? [x, b] :
@@ -173,7 +233,7 @@ export namespace Utils {
}
export function GetClipboardText(): string {
- var textArea = document.createElement("textarea");
+ const textArea = document.createElement("textarea");
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
@@ -196,9 +256,9 @@ export namespace Utils {
if (logFilter !== undefined && logFilter !== message.type) {
return;
}
- let idString = (message.id || "").padStart(36, ' ');
+ const idString = (message.id || "").padStart(36, ' ');
prefix = prefix.padEnd(16, ' ');
- console.log(`${prefix}: ${idString}, ${receiving ? 'receiving' : 'sending'} ${messageName} with data ${JSON.stringify(message)}`);
+ console.log(`${prefix}: ${idString}, ${receiving ? 'receiving' : 'sending'} ${messageName} with data ${JSON.stringify(message)} `);
}
function loggingCallback(prefix: string, func: (args: any) => any, messageName: string) {
@@ -254,18 +314,18 @@ export function OmitKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => vo
}
export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
- var dup: any = {};
+ const dup: any = {};
keys.forEach(key => dup[key] = obj[key]);
addKeyFunc && addKeyFunc(dup);
return dup;
}
export function timenow() {
- var now = new Date();
+ const now = new Date();
let ampm = 'am';
let h = now.getHours();
let m: any = now.getMinutes();
- let s: any = now.getSeconds();
+ const s: any = now.getSeconds();
if (h >= 12) {
if (h > 12) h -= 12;
ampm = 'pm';
@@ -274,15 +334,16 @@ export function timenow() {
return now.toLocaleDateString() + ' ' + h + ':' + m + ' ' + ampm;
}
-export function aggregateBounds(boundsList: { x: number, y: number, width: number, height: number }[]) {
- return boundsList.reduce((bounds, b) => {
- var [sptX, sptY] = [b.x, b.y];
- let [bptX, bptY] = [sptX + b.width, sptY + b.height];
+export function aggregateBounds(boundsList: { x: number, y: number, width: number, height: number }[], xpad: number, ypad: number) {
+ const bounds = boundsList.reduce((bounds, b) => {
+ const [sptX, sptY] = [b.x, b.y];
+ const [bptX, bptY] = [sptX + b.width, sptY + b.height];
return {
x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
};
}, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE });
+ return { x: bounds.x !== Number.MAX_VALUE ? bounds.x - xpad : bounds.x, y: bounds.y !== Number.MAX_VALUE ? bounds.y - ypad : bounds.y, r: bounds.r !== -Number.MAX_VALUE ? bounds.r + xpad : bounds.r, b: bounds.b !== -Number.MAX_VALUE ? bounds.b + ypad : bounds.b };
}
export function intersectRect(r1: { left: number, top: number, width: number, height: number },
r2: { left: number, top: number, width: number, height: number }) {
@@ -307,17 +368,22 @@ export function returnZero() { return 0; }
export function returnEmptyString() { return ""; }
+export let emptyPath = [];
+
export function emptyFunction() { }
+export function unimplementedFunction() { throw new Error("This function is not implemented, but should be."); }
+
export type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export type Predicate<K, V> = (entry: [K, V]) => boolean;
export function DeepCopy<K, V>(source: Map<K, V>, predicate?: Predicate<K, V>) {
- let deepCopy = new Map<K, V>();
- let entries = source.entries(), next = entries.next();
+ const deepCopy = new Map<K, V>();
+ const entries = source.entries();
+ let next = entries.next();
while (!next.done) {
- let entry = next.value;
+ const entry = next.value;
if (!predicate || predicate(entry)) {
deepCopy.set(entry[0], entry[1]);
}
@@ -370,13 +436,13 @@ export function smoothScroll(duration: number, element: HTMLElement, to: number)
animateScroll();
}
export function addStyleSheet(styleType: string = "text/css") {
- let style = document.createElement("style");
+ const style = document.createElement("style");
style.type = styleType;
- var sheets = document.head.appendChild(style);
+ const sheets = document.head.appendChild(style);
return (sheets as any).sheet;
}
export function addStyleSheetRule(sheet: any, selector: any, css: any) {
- var propText = typeof css === "string" ? css : Object.keys(css).map(p => p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p])).join(";");
+ const propText = typeof css === "string" ? css : Object.keys(css).map(p => p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p])).join(";");
return sheet.insertRule("." + selector + "{" + propText + "}", sheet.cssRules.length);
}
export function removeStyleSheetRule(sheet: any, rule: number) {