toosoon-utils 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/dom.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Find the closest parent that matches a selector
3
+ *
4
+ * @param {Element} element Target element
5
+ * @param {(Element|string)} selector Selector or parent to match
6
+ * @returns {Element|null}
7
+ */
8
+ export declare function closest(element: Element, selector: Element | string): Element | null;
9
+ /**
10
+ * Create a canvas and 2d context
11
+ *
12
+ * @param {Number} width Width of the canvas
13
+ * @param {Number} height Height of the canvas
14
+ * @returns {{ canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D }}
15
+ */
16
+ export declare function createCanvas(width: number, height: number): {
17
+ canvas: HTMLCanvasElement;
18
+ ctx: CanvasRenderingContext2D;
19
+ };
20
+ /**
21
+ * Inject CSS styles in `document.head`
22
+ *
23
+ * @param {string} styles CSS styles to inject
24
+ */
25
+ export declare function injectStyles(styles: string): void;
package/lib/dom.js ADDED
@@ -0,0 +1,47 @@
1
+ var DOCUMENT_NODE_TYPE = 9;
2
+ /**
3
+ * Find the closest parent that matches a selector
4
+ *
5
+ * @param {Element} element Target element
6
+ * @param {(Element|string)} selector Selector or parent to match
7
+ * @returns {Element|null}
8
+ */
9
+ export function closest(element, selector) {
10
+ var current = element;
11
+ while (current && current.nodeType !== DOCUMENT_NODE_TYPE) {
12
+ if ((typeof selector === 'string' && current.matches(selector)) || current === selector) {
13
+ return current;
14
+ }
15
+ current = element.parentNode;
16
+ }
17
+ return current;
18
+ }
19
+ /**
20
+ * Create a canvas and 2d context
21
+ *
22
+ * @param {Number} width Width of the canvas
23
+ * @param {Number} height Height of the canvas
24
+ * @returns {{ canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D }}
25
+ */
26
+ export function createCanvas(width, height) {
27
+ var _a;
28
+ var canvas = document.createElement('canvas');
29
+ canvas.width = width;
30
+ canvas.height = height;
31
+ var ctx = (_a = canvas.getContext('2d')) !== null && _a !== void 0 ? _a : new CanvasRenderingContext2D();
32
+ return { canvas: canvas, ctx: ctx };
33
+ }
34
+ /**
35
+ * Inject CSS styles in `document.head`
36
+ *
37
+ * @param {string} styles CSS styles to inject
38
+ */
39
+ export function injectStyles(styles) {
40
+ var $style = document.createElement('style');
41
+ $style.innerHTML = styles;
42
+ var $before = document.querySelector('head link[rel=stylesheet], head style');
43
+ if ($before)
44
+ document.head.insertBefore($style, $before);
45
+ else
46
+ document.head.appendChild($style);
47
+ }
package/lib/files.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Download a Blob object into user files
3
+ *
4
+ * @param {Blob} blob Blob object to download
5
+ * @param {string} filename Downloaded file name
6
+ */
7
+ export declare function download(blob: Blob, filename: string): void;
8
+ /**
9
+ * Upload a file from user files
10
+ *
11
+ * @param {Function} onLoad Callback called once the file is loaded
12
+ * @param {string} [accept=''] MIME type the file input should accept
13
+ */
14
+ export declare function upload(onLoad: (dataUrl: string) => void, accept?: string): void;
package/lib/files.js ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Download a Blob object into user files
3
+ *
4
+ * @param {Blob} blob Blob object to download
5
+ * @param {string} filename Downloaded file name
6
+ */
7
+ export function download(blob, filename) {
8
+ var link = document.createElement('a');
9
+ link.setAttribute('href', URL.createObjectURL(blob));
10
+ link.setAttribute('download', filename);
11
+ document.body.appendChild(link);
12
+ link.click();
13
+ document.body.removeChild(link);
14
+ }
15
+ /**
16
+ * Upload a file from user files
17
+ *
18
+ * @param {Function} onLoad Callback called once the file is loaded
19
+ * @param {string} [accept=''] MIME type the file input should accept
20
+ */
21
+ export function upload(onLoad, accept) {
22
+ if (accept === void 0) { accept = ''; }
23
+ var input = document.createElement('input');
24
+ input.setAttribute('type', 'file');
25
+ input.setAttribute('accept', accept);
26
+ input.addEventListener('change', function (event) {
27
+ var _a, _b;
28
+ var file = (_b = (_a = event.target) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0];
29
+ if (file) {
30
+ var fileReader = new FileReader();
31
+ fileReader.addEventListener('load', function () { return onLoad(URL.createObjectURL(file)); });
32
+ fileReader.readAsDataURL(file);
33
+ }
34
+ });
35
+ document.body.appendChild(input);
36
+ input.click();
37
+ document.body.removeChild(input);
38
+ }
@@ -0,0 +1,22 @@
1
+ import { Deferred } from './types';
2
+ /**
3
+ * No-op function
4
+ */
5
+ export declare const noop: () => void;
6
+ /**
7
+ * Promise wrapped setTimeout
8
+ *
9
+ * @param {number} [timeout=0] Time to wait (in milliseconds)
10
+ * @returns {Promise}
11
+ */
12
+ export declare function wait(timeout?: number): Promise<void>;
13
+ /**
14
+ * Deferred promise implementation
15
+ *
16
+ * @returns {Deferred}
17
+ */
18
+ export declare function defer<T = void>(): Deferred<T>;
19
+ /**
20
+ * Polyfill for `now()` functions
21
+ */
22
+ export declare let now: () => number;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * No-op function
3
+ */
4
+ export var noop = function () { };
5
+ /**
6
+ * Promise wrapped setTimeout
7
+ *
8
+ * @param {number} [timeout=0] Time to wait (in milliseconds)
9
+ * @returns {Promise}
10
+ */
11
+ export function wait(timeout) {
12
+ if (timeout === void 0) { timeout = 0; }
13
+ return new Promise(function (resolve) { return setTimeout(resolve, timeout); });
14
+ }
15
+ /**
16
+ * Deferred promise implementation
17
+ *
18
+ * @returns {Deferred}
19
+ */
20
+ export function defer() {
21
+ var resolve;
22
+ var reject;
23
+ var promise = new Promise(function (_resolve, _reject) {
24
+ resolve = _resolve;
25
+ reject = _reject;
26
+ });
27
+ return { promise: promise, resolve: resolve, reject: reject };
28
+ }
29
+ /**
30
+ * Polyfill for `now()` functions
31
+ */
32
+ export var now;
33
+ // In node.js, use `process.hrtime`
34
+ if (typeof process !== 'undefined' && process.hrtime) {
35
+ now = function () {
36
+ // Convert [seconds, nanoseconds] to milliseconds
37
+ var time = process.hrtime();
38
+ return time[0] * 1000 + time[1] / 1000000;
39
+ };
40
+ }
41
+ // In a browser use `performance` or `Date`
42
+ else if (typeof performance !== 'undefined') {
43
+ // This must be bound, because directly assigning this function leads to an invocation exception in Chrome
44
+ now = performance.now.bind(performance);
45
+ }
46
+ else if (typeof Date.now !== 'undefined') {
47
+ now = Date.now;
48
+ }
49
+ else {
50
+ now = function () {
51
+ return new Date().getTime();
52
+ };
53
+ }
@@ -0,0 +1,89 @@
1
+ import { Vector3 } from './types';
2
+ /**
3
+ * Convert a radians value into degrees
4
+ *
5
+ * @param {number} radians Angle in radians
6
+ * @returns {number} Angle in degrees
7
+ */
8
+ export declare function toDegrees(radians: number): number;
9
+ /**
10
+ * Convert a degrees value into radians
11
+ *
12
+ * @param {number} degrees Angle in degrees
13
+ * @returns {number} Angle in radians
14
+ */
15
+ export declare function toRadians(degrees: number): number;
16
+ /**
17
+ * Calculate the angle from a point to another
18
+ *
19
+ * @param {number} x1 X value of the first point
20
+ * @param {number} y1 Y value of the first point
21
+ * @param {number} x2 X value of the second point
22
+ * @param {number} y2 Y value of the second point
23
+ * @returns {number} Angle
24
+ */
25
+ export declare function angle(x1: number, y1: number, x2: number, y2: number): number;
26
+ /**
27
+ * Find the closest angle between to angles
28
+ *
29
+ * @param {number} source Source angle in radians
30
+ * @param {number} target Target angle in radians
31
+ * @returns {number} Closest angle
32
+ */
33
+ export declare function closestAngle(source: number, target: number): number;
34
+ /**
35
+ * Calculate the distance between two points
36
+ *
37
+ * @param {number} x1 X coord of the first point
38
+ * @param {number} y1 Y coord of the first point
39
+ * @param {number} x2 X coord of the second point
40
+ * @param {number} y2 Y coord of the second point
41
+ * @returns {number} Computed distance
42
+ */
43
+ export declare function distance(x1: number, y1: number, x2: number, y2: number): number;
44
+ /**
45
+ * Calculate the length of the diagonal of a rectangle
46
+ *
47
+ * @param {number} width Width of the rectangle
48
+ * @param {number} height Height of the rectangle
49
+ * @returns {number} Diagonal length
50
+ */
51
+ export declare function diagonal(width: number, height: number): number;
52
+ /**
53
+ * Convert radians to a 3D point on the surface of a unit sphere
54
+ *
55
+ * @param {number} radius Radius of the sphere
56
+ * @param {number} phi Polar angle from the y (up) axis : [0, PI]
57
+ * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
58
+ * @param {Vector3} target Target vector
59
+ * @returns {Vector3}
60
+ */
61
+ export declare function radToSphere(radius: number, phi: number, theta: number, target?: Vector3): Vector3;
62
+ interface FitInput {
63
+ width: number;
64
+ height: number;
65
+ }
66
+ interface FitOutput {
67
+ left: number;
68
+ top: number;
69
+ width: number;
70
+ height: number;
71
+ scale: number;
72
+ }
73
+ /**
74
+ * Make a target fit a container (cover mode)
75
+ *
76
+ * @param {FitInput} target Dimension of the target
77
+ * @param {FitInput} container Dimension of the container
78
+ * @returns {FitOutput}
79
+ */
80
+ export declare function cover(target: FitInput, container: FitInput): FitOutput;
81
+ /**
82
+ * Make a target fit a container (contain mode)
83
+ *
84
+ * @param {FitInput} target Dimension of the target
85
+ * @param {FitInput} container Dimension of the container
86
+ * @returns {FitOutput}
87
+ */
88
+ export declare function contain(target: FitInput, container: FitInput): FitOutput;
89
+ export {};
@@ -0,0 +1,128 @@
1
+ import { PI } from './constants';
2
+ /**
3
+ * Convert a radians value into degrees
4
+ *
5
+ * @param {number} radians Angle in radians
6
+ * @returns {number} Angle in degrees
7
+ */
8
+ export function toDegrees(radians) {
9
+ return (radians * 180) / PI;
10
+ }
11
+ /**
12
+ * Convert a degrees value into radians
13
+ *
14
+ * @param {number} degrees Angle in degrees
15
+ * @returns {number} Angle in radians
16
+ */
17
+ export function toRadians(degrees) {
18
+ return (degrees * PI) / 180;
19
+ }
20
+ /**
21
+ * Calculate the angle from a point to another
22
+ *
23
+ * @param {number} x1 X value of the first point
24
+ * @param {number} y1 Y value of the first point
25
+ * @param {number} x2 X value of the second point
26
+ * @param {number} y2 Y value of the second point
27
+ * @returns {number} Angle
28
+ */
29
+ export function angle(x1, y1, x2, y2) {
30
+ return Math.atan2(y2 - y1, x2 - x1);
31
+ }
32
+ /**
33
+ * Find the closest angle between to angles
34
+ *
35
+ * @param {number} source Source angle in radians
36
+ * @param {number} target Target angle in radians
37
+ * @returns {number} Closest angle
38
+ */
39
+ export function closestAngle(source, target) {
40
+ var delta = target - source;
41
+ return delta > PI ? target - 2 * PI : target < -PI ? delta + 2 * PI : target;
42
+ }
43
+ /**
44
+ * Calculate the distance between two points
45
+ *
46
+ * @param {number} x1 X coord of the first point
47
+ * @param {number} y1 Y coord of the first point
48
+ * @param {number} x2 X coord of the second point
49
+ * @param {number} y2 Y coord of the second point
50
+ * @returns {number} Computed distance
51
+ */
52
+ export function distance(x1, y1, x2, y2) {
53
+ var dx = x1 - x2;
54
+ var dy = y1 - y2;
55
+ return Math.sqrt(dx * dx + dy * dy);
56
+ }
57
+ /**
58
+ * Calculate the length of the diagonal of a rectangle
59
+ *
60
+ * @param {number} width Width of the rectangle
61
+ * @param {number} height Height of the rectangle
62
+ * @returns {number} Diagonal length
63
+ */
64
+ export function diagonal(width, height) {
65
+ return Math.sqrt(width * width + height * height);
66
+ }
67
+ /**
68
+ * Convert radians to a 3D point on the surface of a unit sphere
69
+ *
70
+ * @param {number} radius Radius of the sphere
71
+ * @param {number} phi Polar angle from the y (up) axis : [0, PI]
72
+ * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
73
+ * @param {Vector3} target Target vector
74
+ * @returns {Vector3}
75
+ */
76
+ export function radToSphere(radius, phi, theta, target) {
77
+ if (target === void 0) { target = { x: 0, y: 0, z: 0 }; }
78
+ target.x = radius * Math.sin(phi) * Math.sin(theta);
79
+ target.y = radius * Math.cos(phi);
80
+ target.z = radius * Math.sin(phi) * Math.cos(theta);
81
+ return target;
82
+ }
83
+ /**
84
+ * Make a target fit a container
85
+ *
86
+ * @param {FitInput} target Dimension of the target
87
+ * @param {FitInput} container Dimension of the container
88
+ * @param {string} mode Can be 'contain' | 'cover'
89
+ * @returns {FitOutput}
90
+ */
91
+ function fit(target, container, mode) {
92
+ var ratioWidth = container.width / target.width;
93
+ var ratioHeight = container.height / target.height;
94
+ var scale;
95
+ if (mode === 'contain') {
96
+ scale = ratioWidth < ratioHeight ? ratioWidth : ratioHeight;
97
+ }
98
+ else {
99
+ scale = ratioWidth > ratioHeight ? ratioWidth : ratioHeight;
100
+ }
101
+ return {
102
+ left: (container.width - target.width * scale) >> 1,
103
+ top: (container.height - target.height * scale) >> 1,
104
+ width: target.width * scale,
105
+ height: target.height * scale,
106
+ scale: scale
107
+ };
108
+ }
109
+ /**
110
+ * Make a target fit a container (cover mode)
111
+ *
112
+ * @param {FitInput} target Dimension of the target
113
+ * @param {FitInput} container Dimension of the container
114
+ * @returns {FitOutput}
115
+ */
116
+ export function cover(target, container) {
117
+ return fit(target, container, 'cover');
118
+ }
119
+ /**
120
+ * Make a target fit a container (contain mode)
121
+ *
122
+ * @param {FitInput} target Dimension of the target
123
+ * @param {FitInput} container Dimension of the container
124
+ * @returns {FitOutput}
125
+ */
126
+ export function contain(target, container) {
127
+ return fit(target, container, 'contain');
128
+ }
package/lib/maths.d.ts ADDED
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Check if a number is even
3
+ *
4
+ * @param {number} value Value to check
5
+ * @returns {boolean} True if the given number is even, false otherwise
6
+ */
7
+ export declare function isEven(value: number): boolean;
8
+ /**
9
+ * Check if a number is odd
10
+ *
11
+ * @param {number} value Value to check
12
+ * @returns {boolean} True if the given number is odd, false otherwise
13
+ */
14
+ export declare function isOdd(value: number): boolean;
15
+ /**
16
+ * Check if a number is a power of 2
17
+ *
18
+ * @param {number} value Value to check
19
+ * @returns {boolean} True if the given number is a power of 2, false otherwise
20
+ */
21
+ export declare function isPowerOf2(value: number): boolean;
22
+ /**
23
+ * Find closest power of 2 that fits a number
24
+ *
25
+ * @param {number} value Incoming value
26
+ * @param {string} [mode='ceil'] Can be 'floor' | 'ceil' | 'round'
27
+ * @returns {number} Power of 2
28
+ */
29
+ export declare function toPowerOf2(value: number, mode?: 'floor' | 'ceil' | 'round'): number;
30
+ /**
31
+ * Return the sign (positive or negative) of a number
32
+ *
33
+ * @param {number} value Value to check
34
+ * @returns {number} 1 if the given number is positive, -1 if it is negative, otherwise 0
35
+ */
36
+ export declare function sign(value: number): number;
37
+ /**
38
+ * Clamp a value between two bounds
39
+ *
40
+ * @param {number} value Value to clamp
41
+ * @param {number} [min=0] Minimum boundary
42
+ * @param {number} [max=1] Maximum boundary
43
+ * @returns {number} Clamped value
44
+ */
45
+ export declare function clamp(value: number, min?: number, max?: number): number;
46
+ /**
47
+ * Linear interpolation between two values (lerping)
48
+ *
49
+ * @param {number} value Normalized value to interpolate
50
+ * @param {number} min Minimum value
51
+ * @param {number} max Maximum value
52
+ * @returns {number} Lerped value
53
+ */
54
+ export declare function lerp(value: number, min: number, max: number): number;
55
+ /**
56
+ * Triangular interpolation between two values
57
+ *
58
+ * @param {number} value Normalized value to interpolate
59
+ * @param {number} min Minimum value
60
+ * @param {number} max Maximum value
61
+ * @param {number} target Triangle target value
62
+ * @returns {number} Interpolated value
63
+ */
64
+ export declare function triLerp(value: number, min: number, max: number, target: number): number;
65
+ /**
66
+ * Exponential interpolation between two values
67
+ *
68
+ * @param {number} value Value to interpolate
69
+ * @param {number} currentMin Lower bound of the value's current range
70
+ * @param {number} currentMax Upper bound of the value's current range
71
+ * @param {number} targetMin Lower bound of the value's target range
72
+ * @param {number} targetMax Upper bound of the value's target range
73
+ * @returns {number} Interpolated value
74
+ */
75
+ export declare function expLerp(value: number, currentMin: number, currentMax: number, targetMin: number, targetMax: number): number;
76
+ /**
77
+ * Normalize a value between two bounds
78
+ *
79
+ * @param {number} value Value to normalize
80
+ * @param {number} min Minimum boundary
81
+ * @param {number} max Maximum boundary
82
+ * @returns {number} Normalized value
83
+ */
84
+ export declare function normalize(value: number, min: number, max: number): number;
85
+ /**
86
+ * Re-map a number from one range to another
87
+ *
88
+ * @param {number} value Value to re-map
89
+ * @param {number} currentMin Lower bound of the value's current range
90
+ * @param {number} currentMax Upper bound of the value's current range
91
+ * @param {number} targetMin Lower bound of the value's target range
92
+ * @param {number} targetMax Upper bound of the value's target range
93
+ * @returns {number} Re-mapped value
94
+ */
95
+ export declare function map(value: number, currentMin: number, currentMax: number, targetMin: number, targetMax: number): number;
96
+ /**
97
+ * Round a number up to a nearest multiple
98
+ *
99
+ * @param {number} value Value to round
100
+ * @param {number} [multiple=1] Multiple to round to
101
+ * @returns {number} Closest multiple
102
+ */
103
+ export declare function roundTo(value: number, multiple?: number): number;
104
+ /**
105
+ * Modulo absolute a value based on a length
106
+ *
107
+ * @param {number} value Value to modulate
108
+ * @param {number} length Total length
109
+ * @returns {number} Modulated value
110
+ */
111
+ export declare function modAbs(value: number, length: number): number;
112
+ /**
113
+ * Move back and forth a value between 0 and length, so that it is never larger than length and never smaller than 0
114
+ *
115
+ * @param {number} value Value to modulate
116
+ * @param {number} length Total length
117
+ * @returns {number} PingPonged value
118
+ */
119
+ export declare function pingPong(value: number, length: number): number;
120
+ /**
121
+ * Smooth a value using cubic Hermite interpolation
122
+ *
123
+ * @param {number} value Value to smooth
124
+ * @param {number} [min=0] Minimum boundary
125
+ * @param {number} [max=1] Maximum boundary
126
+ * @returns {number} Normalized smoothed value
127
+ */
128
+ export declare function smoothstep(value: number, min?: number, max?: number): number;
129
+ /**
130
+ * Re-map the [0, 1] interval into [0, 1] parabola, such that corners are remaped to 0 and the center to 1
131
+ * -> parabola(0) = parabola(1) = 0, and parabola(0.5) = 1
132
+ *
133
+ * @param {number} x Normalized coordinate on X axis
134
+ * @param {number} [power=1] Parabola power
135
+ * @returns {number} Normalized re-mapped value
136
+ */
137
+ export declare function parabola(x: number, power?: number): number;
138
+ /**
139
+ * Return the sum of numbers
140
+ *
141
+ * @param {number[]} array Array of numbers
142
+ * @returns {number} Total sum
143
+ */
144
+ export declare function sum(array: number[]): number;
145
+ /**
146
+ * Return the average of numbers
147
+ *
148
+ * @param {number[]} array Array of numbers
149
+ * @returns {number} Total average
150
+ */
151
+ export declare function average(array: number[]): number;
152
+ /**
153
+ * Smoothly interpolate a number toward another
154
+ *
155
+ * @param {number} value Value to interpolate
156
+ * @param {number} target Destination of the interpolation
157
+ * @param {number} damping A higher value will make the movement more sudden, and a lower value will make the movement more gradual
158
+ * @param {number} delta Delta time (in seconds)
159
+ * @returns {number} Interpolated number
160
+ */
161
+ export declare function damp(value: number, target: number, damping: number, delta: number): number;