aboutsummaryrefslogtreecommitdiff
path: root/src/util.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.ts')
-rw-r--r--src/util.ts16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/util.ts b/src/util.ts
index a686b70..180c7c2 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -2,8 +2,12 @@
* General utility functions
*/
+// ========== For device detection ==========
+
// For detecting screen size
+
export type Breakpoint = 'sm' | 'md' | 'lg';
+
export function getBreakpoint(): Breakpoint {
const w = window.innerWidth;
if (w < 768){
@@ -14,6 +18,7 @@ export function getBreakpoint(): Breakpoint {
return 'lg';
}
}
+
// For getting scroll-bar width // From stackoverflow.com/questions/13382516/getting-scroll-bar-width-using-javascript
export function getScrollBarWidth(){
// Create hidden outer div
@@ -31,19 +36,24 @@ export function getScrollBarWidth(){
//
return scrollBarWidth;
}
+
// Detects a touch device
export function onTouchDevice(){
return window.matchMedia('(pointer: coarse)').matches;
}
+// ========== Other ==========
+
// Returns [0 ... len]
export function range(len: number): number[] {
return [...Array(len).keys()];
}
+
// Returns sum of array values
export function arraySum(array: number[]): number {
return array.reduce((x,y) => x+y);
}
+
// Returns an array of increasing evenly-spaced numbers from 'start' to 'end', with size 'size'
export function linspace(start: number, end: number, size: number): number[] {
const step = (end - start) / (size - 1);
@@ -53,6 +63,7 @@ export function linspace(start: number, end: number, size: number): number[] {
}
return ar;
}
+
// Returns array copy with vals clipped to within [min,max], redistributing to compensate
// Returns null on failure
export function limitVals(arr: number[], min: number, max: number): number[] | null {
@@ -78,6 +89,7 @@ export function limitVals(arr: number[], min: number, max: number): number[] | n
if (Math.abs(owedChg) < Number.EPSILON){
return vals;
}
+
// Compensate for changes made
const indicesToUpdate = (owedChg > 0) ?
range(vals.length).filter(idx => vals[idx] < max) :
@@ -91,6 +103,7 @@ export function limitVals(arr: number[], min: number, max: number): number[] | n
owedChg = 0;
}
}
+
// Usable to iterate through possible int arrays with ascending values in the range 0 to N, where N < maxLen
// For example, with maxLen 3, passing [0] will update it to [0,1], then [0,2], then [0,1,2]
// Returns false when there is no next array
@@ -114,6 +127,7 @@ export function updateAscSeq(seq: number[], maxLen: number): boolean {
}
}
}
+
// Given a non-empty array of non-negative weights, returns an array index chosen with weighted pseudorandomness
// Returns null if array contains all zeros
export function randWeightedChoice(weights: number[]): number | null {
@@ -131,6 +145,7 @@ export function randWeightedChoice(weights: number[]): number | null {
}
return null;
}
+
// Returns a string with words first-letter capitalised
export function capitalizeWords(str: string){
str = str.replace(/\b\w/g, x => x.toUpperCase()); // '\b' matches word boundary, '\w' is like [a-zA-Z0-9_]
@@ -138,6 +153,7 @@ export function capitalizeWords(str: string){
str = str.replace(/ And\b/, ' and'); // Avoid cases like "frogs and toads" -> "Frogs And Toads"
return str;
}
+
// Used to async-await for until after a timeout
export async function timeout(ms: number){
return new Promise(resolve => setTimeout(resolve, ms))