@js-draw/math 1.22.0 → 1.24.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/dist/cjs/Color4.d.ts +24 -1
  2. package/dist/cjs/Color4.js +33 -1
  3. package/dist/cjs/Mat33.d.ts +20 -0
  4. package/dist/cjs/Mat33.js +23 -1
  5. package/dist/cjs/Vec3.d.ts +14 -5
  6. package/dist/cjs/Vec3.js +11 -2
  7. package/dist/cjs/lib.d.ts +3 -0
  8. package/dist/cjs/lib.js +3 -0
  9. package/dist/cjs/rounding/cleanUpNumber.js +1 -1
  10. package/dist/cjs/shapes/BezierJSWrapper.d.ts +9 -1
  11. package/dist/cjs/shapes/BezierJSWrapper.js +2 -0
  12. package/dist/cjs/shapes/Path.d.ts +1 -0
  13. package/dist/cjs/shapes/Path.js +1 -0
  14. package/dist/cjs/shapes/QuadraticBezier.d.ts +19 -2
  15. package/dist/cjs/shapes/QuadraticBezier.js +26 -3
  16. package/dist/cjs/shapes/Rect2.d.ts +13 -0
  17. package/dist/cjs/shapes/Rect2.js +22 -1
  18. package/dist/mjs/Color4.d.ts +24 -1
  19. package/dist/mjs/Color4.mjs +33 -1
  20. package/dist/mjs/Mat33.d.ts +20 -0
  21. package/dist/mjs/Mat33.mjs +23 -1
  22. package/dist/mjs/Vec3.d.ts +14 -5
  23. package/dist/mjs/Vec3.mjs +11 -2
  24. package/dist/mjs/lib.d.ts +3 -0
  25. package/dist/mjs/lib.mjs +3 -0
  26. package/dist/mjs/rounding/cleanUpNumber.mjs +1 -1
  27. package/dist/mjs/shapes/BezierJSWrapper.d.ts +9 -1
  28. package/dist/mjs/shapes/BezierJSWrapper.mjs +2 -0
  29. package/dist/mjs/shapes/Path.d.ts +1 -0
  30. package/dist/mjs/shapes/Path.mjs +1 -0
  31. package/dist/mjs/shapes/QuadraticBezier.d.ts +19 -2
  32. package/dist/mjs/shapes/QuadraticBezier.mjs +26 -3
  33. package/dist/mjs/shapes/Rect2.d.ts +13 -0
  34. package/dist/mjs/shapes/Rect2.mjs +22 -1
  35. package/dist-test/test_imports/test-require.cjs +1 -0
  36. package/package.json +3 -3
  37. package/src/Color4.test.ts +5 -0
  38. package/src/Color4.ts +39 -1
  39. package/src/Mat33.fromCSSMatrix.test.ts +4 -1
  40. package/src/Mat33.test.ts +6 -6
  41. package/src/Mat33.ts +23 -1
  42. package/src/Vec3.ts +14 -5
  43. package/src/lib.ts +3 -0
  44. package/src/rounding/cleanUpNumber.test.ts +2 -0
  45. package/src/rounding/cleanUpNumber.ts +1 -1
  46. package/src/shapes/BezierJSWrapper.ts +11 -4
  47. package/src/shapes/Path.ts +1 -0
  48. package/src/shapes/QuadraticBezier.ts +22 -2
  49. package/src/shapes/Rect2.ts +17 -0
@@ -28,9 +28,32 @@ export declare class Color4 {
28
28
  * Each component should be in the range [0, 1].
29
29
  */
30
30
  static ofRGB(red: number, green: number, blue: number): Color4;
31
+ /**
32
+ * Creates a color from red, green, blue, and transparency components. Each component should
33
+ * be in the range $[0, 1]$.
34
+ */
31
35
  static ofRGBA(red: number, green: number, blue: number, alpha: number): Color4;
36
+ /**
37
+ * Creates a color from an RGB (or RGBA) array.
38
+ *
39
+ * This is similar to {@link ofRGB} and {@link ofRGBA}, but, by default, takes values
40
+ * that range from 0 to 255.
41
+ *
42
+ * If the array values instead range from 0-1, pass `maxValue` as `1`.
43
+ */
44
+ static fromRGBArray(array: Uint8Array | Uint8ClampedArray | number[], maxValue?: number): Color4;
45
+ /**
46
+ * Creates a `Color4` from a three or four-component hexadecimal
47
+ * [color string](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet).
48
+ *
49
+ * Example:
50
+ * ```ts,runnable,console
51
+ * import { Color4 } from '@js-draw/math';
52
+ * console.log(Color4.fromHex('#ff0'));
53
+ * ```
54
+ */
32
55
  static fromHex(hexString: string): Color4;
33
- /** Like fromHex, but can handle additional colors if an `HTMLCanvasElement` is available. */
56
+ /** Like {@link fromHex}, but can handle additional colors if an `HTMLCanvasElement` is available. */
34
57
  static fromString(text: string): Color4;
35
58
  /** @returns true if `this` and `other` are approximately equal. */
36
59
  eq(other: Color4 | null | undefined): boolean;
@@ -42,6 +42,10 @@ class Color4 {
42
42
  static ofRGB(red, green, blue) {
43
43
  return Color4.ofRGBA(red, green, blue, 1.0);
44
44
  }
45
+ /**
46
+ * Creates a color from red, green, blue, and transparency components. Each component should
47
+ * be in the range $[0, 1]$.
48
+ */
45
49
  static ofRGBA(red, green, blue, alpha) {
46
50
  red = Math.max(0, Math.min(red, 1));
47
51
  green = Math.max(0, Math.min(green, 1));
@@ -49,6 +53,34 @@ class Color4 {
49
53
  alpha = Math.max(0, Math.min(alpha, 1));
50
54
  return new Color4(red, green, blue, alpha);
51
55
  }
56
+ /**
57
+ * Creates a color from an RGB (or RGBA) array.
58
+ *
59
+ * This is similar to {@link ofRGB} and {@link ofRGBA}, but, by default, takes values
60
+ * that range from 0 to 255.
61
+ *
62
+ * If the array values instead range from 0-1, pass `maxValue` as `1`.
63
+ */
64
+ static fromRGBArray(array, maxValue = 255) {
65
+ const red = array[0];
66
+ const green = array[1] ?? red;
67
+ const blue = array[2] ?? red;
68
+ let alpha = 255;
69
+ if (3 < array.length) {
70
+ alpha = array[3];
71
+ }
72
+ return Color4.ofRGBA(red / maxValue, green / maxValue, blue / maxValue, alpha / maxValue);
73
+ }
74
+ /**
75
+ * Creates a `Color4` from a three or four-component hexadecimal
76
+ * [color string](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet).
77
+ *
78
+ * Example:
79
+ * ```ts,runnable,console
80
+ * import { Color4 } from '@js-draw/math';
81
+ * console.log(Color4.fromHex('#ff0'));
82
+ * ```
83
+ */
52
84
  static fromHex(hexString) {
53
85
  // Remove starting '#' (if present)
54
86
  hexString = (hexString.match(/^[#]?(.*)$/) ?? [])[1];
@@ -77,7 +109,7 @@ class Color4 {
77
109
  }
78
110
  return Color4.ofRGBA(components[0], components[1], components[2], components[3]);
79
111
  }
80
- /** Like fromHex, but can handle additional colors if an `HTMLCanvasElement` is available. */
112
+ /** Like {@link fromHex}, but can handle additional colors if an `HTMLCanvasElement` is available. */
81
113
  static fromString(text) {
82
114
  if (text.startsWith('#')) {
83
115
  return Color4.fromHex(text);
@@ -206,6 +206,26 @@ export declare class Mat33 {
206
206
  * $$
207
207
  */
208
208
  static translation(amount: Vec2): Mat33;
209
+ /**
210
+ * Creates a matrix for rotating `Vec2`s about `center` by some number of `radians`.
211
+ *
212
+ * For this function, {@link Vec2}s are considered to be points in 2D space.
213
+ *
214
+ * For example,
215
+ * ```ts,runnable,console
216
+ * import { Mat33, Vec2 } from '@js-draw/math';
217
+ *
218
+ * const halfCircle = Math.PI; // PI radians = 180 degrees = 1/2 circle
219
+ * const center = Vec2.of(1, 1); // The point (1,1)
220
+ * const rotationMatrix = Mat33.zRotation(halfCircle, center);
221
+ *
222
+ * console.log(
223
+ * 'Rotating (0,0) 180deg about', center, 'results in',
224
+ * // Rotates (0,0)
225
+ * rotationMatrix.transformVec2(Vec2.zero),
226
+ * );
227
+ * ```
228
+ */
209
229
  static zRotation(radians: number, center?: Point2): Mat33;
210
230
  static scaling2D(amount: number | Vec2, center?: Point2): Mat33;
211
231
  /**
package/dist/cjs/Mat33.js CHANGED
@@ -362,6 +362,26 @@ class Mat33 {
362
362
  // ...
363
363
  return new Mat33(1, 0, amount.x, 0, 1, amount.y, 0, 0, 1);
364
364
  }
365
+ /**
366
+ * Creates a matrix for rotating `Vec2`s about `center` by some number of `radians`.
367
+ *
368
+ * For this function, {@link Vec2}s are considered to be points in 2D space.
369
+ *
370
+ * For example,
371
+ * ```ts,runnable,console
372
+ * import { Mat33, Vec2 } from '@js-draw/math';
373
+ *
374
+ * const halfCircle = Math.PI; // PI radians = 180 degrees = 1/2 circle
375
+ * const center = Vec2.of(1, 1); // The point (1,1)
376
+ * const rotationMatrix = Mat33.zRotation(halfCircle, center);
377
+ *
378
+ * console.log(
379
+ * 'Rotating (0,0) 180deg about', center, 'results in',
380
+ * // Rotates (0,0)
381
+ * rotationMatrix.transformVec2(Vec2.zero),
382
+ * );
383
+ * ```
384
+ */
365
385
  static zRotation(radians, center = Vec2_1.Vec2.zero) {
366
386
  if (radians === 0) {
367
387
  return Mat33.identity;
@@ -410,6 +430,8 @@ class Mat33 {
410
430
  if (cssString === '' || cssString === 'none') {
411
431
  return Mat33.identity;
412
432
  }
433
+ // Normalize spacing
434
+ cssString = cssString.trim().replace(/\s+/g, ' ');
413
435
  const parseArguments = (argumentString) => {
414
436
  const parsed = argumentString.split(/[, \t\n]+/g).map((argString) => {
415
437
  // Handle trailing spaces/commands
@@ -486,7 +508,7 @@ class Mat33 {
486
508
  };
487
509
  // A command (\w+)
488
510
  // followed by a set of arguments ([ \t\n0-9eE.,\-%]+)
489
- const partRegex = /\s*(\w+)\s*\(([^)]*)\)/gi;
511
+ const partRegex = /(\w+)\s?\(([^)]*)\)/gi;
490
512
  let match;
491
513
  let matrix = null;
492
514
  while ((match = partRegex.exec(cssString)) !== null) {
@@ -68,8 +68,8 @@ export interface Vec3 {
68
68
  *
69
69
  * This is equivalent to `Math.atan2(vec.y, vec.x)`.
70
70
  *
71
- * As such, observing that `Math.atan2(-0, -1)` $\approx -\pi$ and `Math.atan2(0, -1)`$\approx \pi$
72
- * the resultant angle is in the range $[-\pi, pi]$.
71
+ * As such, observing that `Math.atan2(-0, -1)` $\approx -\pi$ and `Math.atan2(0, -1)` $\approx \pi$
72
+ * the resultant angle is in the range $[-\pi, \pi]$.
73
73
  *
74
74
  * **Example**:
75
75
  * ```ts,runnable,console
@@ -150,7 +150,7 @@ export interface Vec3 {
150
150
  map(fn: (component: number, index: number) => number): Vec3;
151
151
  asArray(): [number, number, number];
152
152
  /**
153
- * [fuzz] The maximum difference between two components for this and [other]
153
+ * @param tolerance The maximum difference between two components for this and [other]
154
154
  * to be considered equal.
155
155
  *
156
156
  * @example
@@ -200,12 +200,16 @@ declare class Vec2Impl implements Vec3 {
200
200
  toString(): string;
201
201
  }
202
202
  /**
203
- * A `Vec2` is a `Vec3` optimized for working in a plane. As such, they have an
203
+ * A `Vec2` is a {@link Vec3} optimized for working in a plane. `Vec2`s have an
204
204
  * always-zero `z` component.
205
205
  *
206
206
  * ```ts,runnable,console
207
207
  * import { Vec2 } from '@js-draw/math';
208
- * console.log(Vec2.of(1, 2));
208
+ *
209
+ * const v = Vec2.of(1, 2);
210
+ * console.log('a Vec2:', v);
211
+ * console.log('x component:', v.x);
212
+ * console.log('z component:', v.z);
209
213
  * ```
210
214
  */
211
215
  export declare namespace Vec2 {
@@ -240,6 +244,7 @@ export declare namespace Vec2 {
240
244
  /** The zero vector: A vector with x=0, y=0. */
241
245
  const zero: Vec2Impl;
242
246
  }
247
+ /** Contains static methods for constructing a {@link Vec3}. */
243
248
  export declare namespace Vec3 {
244
249
  /**
245
250
  * Construct a vector from three components.
@@ -248,11 +253,15 @@ export declare namespace Vec3 {
248
253
  * ```ts,runnable,console
249
254
  * import { Vec3 } from '@js-draw/math';
250
255
  * const v1 = Vec3.of(1, 2, 3);
256
+ * console.log(v1.plus(Vec3.of(0, 100, 0)));
251
257
  * ```
252
258
  */
253
259
  const of: (x: number, y: number, z: number) => Vec3;
260
+ /** A unit vector in the x direction (`[1, 0, 0]`). */
254
261
  const unitX: Vec2Impl;
262
+ /** A unit vector in the y direction (`[0, 1, 0]`). */
255
263
  const unitY: Vec2Impl;
264
+ /** The zero vector (`[0, 0, 0]`). */
256
265
  const zero: Vec2Impl;
257
266
  /** A vector of length 1 in the z direction. */
258
267
  const unitZ: Vec3;
package/dist/cjs/Vec3.js CHANGED
@@ -227,12 +227,16 @@ class Vec2Impl {
227
227
  }
228
228
  }
229
229
  /**
230
- * A `Vec2` is a `Vec3` optimized for working in a plane. As such, they have an
230
+ * A `Vec2` is a {@link Vec3} optimized for working in a plane. `Vec2`s have an
231
231
  * always-zero `z` component.
232
232
  *
233
233
  * ```ts,runnable,console
234
234
  * import { Vec2 } from '@js-draw/math';
235
- * console.log(Vec2.of(1, 2));
235
+ *
236
+ * const v = Vec2.of(1, 2);
237
+ * console.log('a Vec2:', v);
238
+ * console.log('x component:', v.x);
239
+ * console.log('z component:', v.z);
236
240
  * ```
237
241
  */
238
242
  var Vec2;
@@ -269,6 +273,7 @@ var Vec2;
269
273
  /** The zero vector: A vector with x=0, y=0. */
270
274
  Vec2.zero = Vec2.of(0, 0);
271
275
  })(Vec2 || (exports.Vec2 = Vec2 = {}));
276
+ /** Contains static methods for constructing a {@link Vec3}. */
272
277
  var Vec3;
273
278
  (function (Vec3) {
274
279
  /**
@@ -278,6 +283,7 @@ var Vec3;
278
283
  * ```ts,runnable,console
279
284
  * import { Vec3 } from '@js-draw/math';
280
285
  * const v1 = Vec3.of(1, 2, 3);
286
+ * console.log(v1.plus(Vec3.of(0, 100, 0)));
281
287
  * ```
282
288
  */
283
289
  Vec3.of = (x, y, z) => {
@@ -288,8 +294,11 @@ var Vec3;
288
294
  return new Vec3Impl(x, y, z);
289
295
  }
290
296
  };
297
+ /** A unit vector in the x direction (`[1, 0, 0]`). */
291
298
  Vec3.unitX = Vec2.unitX;
299
+ /** A unit vector in the y direction (`[0, 1, 0]`). */
292
300
  Vec3.unitY = Vec2.unitY;
301
+ /** The zero vector (`[0, 0, 0]`). */
293
302
  Vec3.zero = Vec2.zero;
294
303
  /** A vector of length 1 in the z direction. */
295
304
  Vec3.unitZ = Vec3.of(0, 0, 1);
package/dist/cjs/lib.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * This package contains general math utilities used by `js-draw`.
3
+ * These include 2D and 3D vectors, 2D paths, and 3x3 matrices.
4
+ *
2
5
  * ```ts,runnable,console
3
6
  * import { Vec2, Mat33, Rect2 } from '@js-draw/math';
4
7
  *
package/dist/cjs/lib.js CHANGED
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
+ * This package contains general math utilities used by `js-draw`.
4
+ * These include 2D and 3D vectors, 2D paths, and 3x3 matrices.
5
+ *
3
6
  * ```ts,runnable,console
4
7
  * import { Vec2, Mat33, Rect2 } from '@js-draw/math';
5
8
  *
@@ -14,7 +14,7 @@ const cleanUpNumber = (text) => {
14
14
  const lastChar = text.charAt(text.length - 1);
15
15
  if (lastChar === '0' || lastChar === '.') {
16
16
  // Remove trailing zeroes
17
- text = text.replace(/([.]\d*[^0]+)0+$/, '$1');
17
+ text = text.replace(/([.]\d*[^0])0+$/, '$1');
18
18
  text = text.replace(/[.]0+$/, '.');
19
19
  // Remove trailing period
20
20
  text = text.replace(/[.]$/, '');
@@ -3,6 +3,12 @@ import { Point2, Vec2 } from '../Vec2';
3
3
  import LineSegment2 from './LineSegment2';
4
4
  import Rect2 from './Rect2';
5
5
  import Parameterized2DShape from './Parameterized2DShape';
6
+ interface CorrectedBezierType extends Bezier {
7
+ dderivative(t: number): {
8
+ x: number;
9
+ y: number;
10
+ };
11
+ }
6
12
  /**
7
13
  * A lazy-initializing wrapper around Bezier-js.
8
14
  *
@@ -17,7 +23,7 @@ export declare abstract class BezierJSWrapper extends Parameterized2DShape {
17
23
  protected constructor(bezierJsBezier?: Bezier);
18
24
  /** Returns the start, control points, and end point of this Bézier. */
19
25
  abstract getPoints(): readonly Point2[];
20
- protected getBezier(): Bezier;
26
+ protected getBezier(): CorrectedBezierType;
21
27
  signedDistance(point: Point2): number;
22
28
  /**
23
29
  * @returns the (more) exact distance from `point` to this.
@@ -29,8 +35,10 @@ export declare abstract class BezierJSWrapper extends Parameterized2DShape {
29
35
  * @returns the curve evaluated at `t`.
30
36
  */
31
37
  at(t: number): Point2;
38
+ /** @returns the curve's directional derivative at `t`. */
32
39
  derivativeAt(t: number): Point2;
33
40
  secondDerivativeAt(t: number): Point2;
41
+ /** @returns the [normal vector](https://en.wikipedia.org/wiki/Normal_(geometry)) to this curve at `t`. */
34
42
  normal(t: number): Vec2;
35
43
  normalAt(t: number): Vec2;
36
44
  tangentAt(t: number): Vec2;
@@ -63,12 +63,14 @@ class BezierJSWrapper extends Parameterized2DShape_1.default {
63
63
  at(t) {
64
64
  return Vec2_1.Vec2.ofXY(this.getBezier().get(t));
65
65
  }
66
+ /** @returns the curve's directional derivative at `t`. */
66
67
  derivativeAt(t) {
67
68
  return Vec2_1.Vec2.ofXY(this.getBezier().derivative(t));
68
69
  }
69
70
  secondDerivativeAt(t) {
70
71
  return Vec2_1.Vec2.ofXY(this.getBezier().dderivative(t));
71
72
  }
73
+ /** @returns the [normal vector](https://en.wikipedia.org/wiki/Normal_(geometry)) to this curve at `t`. */
72
74
  normal(t) {
73
75
  return Vec2_1.Vec2.ofXY(this.getBezier().normal(t));
74
76
  }
@@ -3,6 +3,7 @@ import Mat33 from '../Mat33';
3
3
  import Rect2 from './Rect2';
4
4
  import { Point2 } from '../Vec2';
5
5
  import Parameterized2DShape from './Parameterized2DShape';
6
+ /** Identifiers for different path commands. These commands can make up a {@link Path}. */
6
7
  export declare enum PathCommandType {
7
8
  LineTo = 0,
8
9
  MoveTo = 1,
@@ -13,6 +13,7 @@ const PointShape2D_1 = __importDefault(require("./PointShape2D"));
13
13
  const toRoundedString_1 = __importDefault(require("../rounding/toRoundedString"));
14
14
  const toStringOfSamePrecision_1 = __importDefault(require("../rounding/toStringOfSamePrecision"));
15
15
  const convexHull2Of_1 = __importDefault(require("../utils/convexHull2Of"));
16
+ /** Identifiers for different path commands. These commands can make up a {@link Path}. */
16
17
  var PathCommandType;
17
18
  (function (PathCommandType) {
18
19
  PathCommandType[PathCommandType["LineTo"] = 0] = "LineTo";
@@ -2,9 +2,26 @@ import { Point2, Vec2 } from '../Vec2';
2
2
  import BezierJSWrapper from './BezierJSWrapper';
3
3
  import Rect2 from './Rect2';
4
4
  /**
5
- * Represents a 2D Bézier curve.
5
+ * Represents a 2D [Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve).
6
6
  *
7
- * **Note**: Many Bézier operations use `bezier-js`'s.
7
+ * Example:
8
+ * ```ts,runnable,console
9
+ * import { QuadraticBezier, Vec2 } from '@js-draw/math';
10
+ *
11
+ * const startPoint = Vec2.of(4, 3);
12
+ * const controlPoint = Vec2.of(1, 1);
13
+ * const endPoint = Vec2.of(1, 3);
14
+ *
15
+ * const curve = new QuadraticBezier(
16
+ * startPoint,
17
+ * controlPoint,
18
+ * endPoint,
19
+ * );
20
+ *
21
+ * console.log('Curve:', curve);
22
+ * ```
23
+ *
24
+ * **Note**: Some Bézier operations internally use the `bezier-js` library.
8
25
  */
9
26
  export declare class QuadraticBezier extends BezierJSWrapper {
10
27
  readonly p0: Point2;
@@ -9,12 +9,35 @@ const solveQuadratic_1 = __importDefault(require("../polynomial/solveQuadratic")
9
9
  const BezierJSWrapper_1 = __importDefault(require("./BezierJSWrapper"));
10
10
  const Rect2_1 = __importDefault(require("./Rect2"));
11
11
  /**
12
- * Represents a 2D Bézier curve.
12
+ * Represents a 2D [Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve).
13
13
  *
14
- * **Note**: Many Bézier operations use `bezier-js`'s.
14
+ * Example:
15
+ * ```ts,runnable,console
16
+ * import { QuadraticBezier, Vec2 } from '@js-draw/math';
17
+ *
18
+ * const startPoint = Vec2.of(4, 3);
19
+ * const controlPoint = Vec2.of(1, 1);
20
+ * const endPoint = Vec2.of(1, 3);
21
+ *
22
+ * const curve = new QuadraticBezier(
23
+ * startPoint,
24
+ * controlPoint,
25
+ * endPoint,
26
+ * );
27
+ *
28
+ * console.log('Curve:', curve);
29
+ * ```
30
+ *
31
+ * **Note**: Some Bézier operations internally use the `bezier-js` library.
15
32
  */
16
33
  class QuadraticBezier extends BezierJSWrapper_1.default {
17
- constructor(p0, p1, p2) {
34
+ constructor(
35
+ // Start point
36
+ p0,
37
+ // Control point
38
+ p1,
39
+ // End point
40
+ p2) {
18
41
  super();
19
42
  this.p0 = p0;
20
43
  this.p1 = p1;
@@ -15,6 +15,18 @@ export interface RectTemplate {
15
15
  /**
16
16
  * Represents a rectangle in 2D space, parallel to the XY axes.
17
17
  *
18
+ * **Example**:
19
+ * ```ts,runnable,console
20
+ * import { Rect2, Vec2 } from '@js-draw/math';
21
+ *
22
+ * const rect = Rect2.fromCorners(
23
+ * Vec2.of(0, 0),
24
+ * Vec2.of(10, 10),
25
+ * );
26
+ * console.log('area', rect.area);
27
+ * console.log('topLeft', rect.topLeft);
28
+ * ```
29
+ *
18
30
  * `invariant: w ≥ 0, h ≥ 0, immutable`
19
31
  */
20
32
  export declare class Rect2 extends Abstract2DShape {
@@ -29,6 +41,7 @@ export declare class Rect2 extends Abstract2DShape {
29
41
  translatedBy(vec: Vec2): Rect2;
30
42
  resizedTo(size: Vec2): Rect2;
31
43
  containsPoint(other: Point2): boolean;
44
+ /** @returns true iff `other` is completely within this `Rect2`. */
32
45
  containsRect(other: Rect2): boolean;
33
46
  /**
34
47
  * @returns true iff this and `other` overlap
@@ -10,10 +10,30 @@ const Abstract2DShape_1 = __importDefault(require("./Abstract2DShape"));
10
10
  /**
11
11
  * Represents a rectangle in 2D space, parallel to the XY axes.
12
12
  *
13
+ * **Example**:
14
+ * ```ts,runnable,console
15
+ * import { Rect2, Vec2 } from '@js-draw/math';
16
+ *
17
+ * const rect = Rect2.fromCorners(
18
+ * Vec2.of(0, 0),
19
+ * Vec2.of(10, 10),
20
+ * );
21
+ * console.log('area', rect.area);
22
+ * console.log('topLeft', rect.topLeft);
23
+ * ```
24
+ *
13
25
  * `invariant: w ≥ 0, h ≥ 0, immutable`
14
26
  */
15
27
  class Rect2 extends Abstract2DShape_1.default {
16
- constructor(x, y, w, h) {
28
+ constructor(
29
+ // Top left x coordinate
30
+ x,
31
+ // Top left y coordinate
32
+ y,
33
+ // Width
34
+ w,
35
+ // Height
36
+ h) {
17
37
  super();
18
38
  this.x = x;
19
39
  this.y = y;
@@ -45,6 +65,7 @@ class Rect2 extends Abstract2DShape_1.default {
45
65
  this.x + this.w >= other.x &&
46
66
  this.y + this.h >= other.y);
47
67
  }
68
+ /** @returns true iff `other` is completely within this `Rect2`. */
48
69
  containsRect(other) {
49
70
  return (this.x <= other.x &&
50
71
  this.y <= other.y &&
@@ -28,9 +28,32 @@ export declare class Color4 {
28
28
  * Each component should be in the range [0, 1].
29
29
  */
30
30
  static ofRGB(red: number, green: number, blue: number): Color4;
31
+ /**
32
+ * Creates a color from red, green, blue, and transparency components. Each component should
33
+ * be in the range $[0, 1]$.
34
+ */
31
35
  static ofRGBA(red: number, green: number, blue: number, alpha: number): Color4;
36
+ /**
37
+ * Creates a color from an RGB (or RGBA) array.
38
+ *
39
+ * This is similar to {@link ofRGB} and {@link ofRGBA}, but, by default, takes values
40
+ * that range from 0 to 255.
41
+ *
42
+ * If the array values instead range from 0-1, pass `maxValue` as `1`.
43
+ */
44
+ static fromRGBArray(array: Uint8Array | Uint8ClampedArray | number[], maxValue?: number): Color4;
45
+ /**
46
+ * Creates a `Color4` from a three or four-component hexadecimal
47
+ * [color string](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet).
48
+ *
49
+ * Example:
50
+ * ```ts,runnable,console
51
+ * import { Color4 } from '@js-draw/math';
52
+ * console.log(Color4.fromHex('#ff0'));
53
+ * ```
54
+ */
32
55
  static fromHex(hexString: string): Color4;
33
- /** Like fromHex, but can handle additional colors if an `HTMLCanvasElement` is available. */
56
+ /** Like {@link fromHex}, but can handle additional colors if an `HTMLCanvasElement` is available. */
34
57
  static fromString(text: string): Color4;
35
58
  /** @returns true if `this` and `other` are approximately equal. */
36
59
  eq(other: Color4 | null | undefined): boolean;
@@ -36,6 +36,10 @@ export class Color4 {
36
36
  static ofRGB(red, green, blue) {
37
37
  return Color4.ofRGBA(red, green, blue, 1.0);
38
38
  }
39
+ /**
40
+ * Creates a color from red, green, blue, and transparency components. Each component should
41
+ * be in the range $[0, 1]$.
42
+ */
39
43
  static ofRGBA(red, green, blue, alpha) {
40
44
  red = Math.max(0, Math.min(red, 1));
41
45
  green = Math.max(0, Math.min(green, 1));
@@ -43,6 +47,34 @@ export class Color4 {
43
47
  alpha = Math.max(0, Math.min(alpha, 1));
44
48
  return new Color4(red, green, blue, alpha);
45
49
  }
50
+ /**
51
+ * Creates a color from an RGB (or RGBA) array.
52
+ *
53
+ * This is similar to {@link ofRGB} and {@link ofRGBA}, but, by default, takes values
54
+ * that range from 0 to 255.
55
+ *
56
+ * If the array values instead range from 0-1, pass `maxValue` as `1`.
57
+ */
58
+ static fromRGBArray(array, maxValue = 255) {
59
+ const red = array[0];
60
+ const green = array[1] ?? red;
61
+ const blue = array[2] ?? red;
62
+ let alpha = 255;
63
+ if (3 < array.length) {
64
+ alpha = array[3];
65
+ }
66
+ return Color4.ofRGBA(red / maxValue, green / maxValue, blue / maxValue, alpha / maxValue);
67
+ }
68
+ /**
69
+ * Creates a `Color4` from a three or four-component hexadecimal
70
+ * [color string](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet).
71
+ *
72
+ * Example:
73
+ * ```ts,runnable,console
74
+ * import { Color4 } from '@js-draw/math';
75
+ * console.log(Color4.fromHex('#ff0'));
76
+ * ```
77
+ */
46
78
  static fromHex(hexString) {
47
79
  // Remove starting '#' (if present)
48
80
  hexString = (hexString.match(/^[#]?(.*)$/) ?? [])[1];
@@ -71,7 +103,7 @@ export class Color4 {
71
103
  }
72
104
  return Color4.ofRGBA(components[0], components[1], components[2], components[3]);
73
105
  }
74
- /** Like fromHex, but can handle additional colors if an `HTMLCanvasElement` is available. */
106
+ /** Like {@link fromHex}, but can handle additional colors if an `HTMLCanvasElement` is available. */
75
107
  static fromString(text) {
76
108
  if (text.startsWith('#')) {
77
109
  return Color4.fromHex(text);
@@ -206,6 +206,26 @@ export declare class Mat33 {
206
206
  * $$
207
207
  */
208
208
  static translation(amount: Vec2): Mat33;
209
+ /**
210
+ * Creates a matrix for rotating `Vec2`s about `center` by some number of `radians`.
211
+ *
212
+ * For this function, {@link Vec2}s are considered to be points in 2D space.
213
+ *
214
+ * For example,
215
+ * ```ts,runnable,console
216
+ * import { Mat33, Vec2 } from '@js-draw/math';
217
+ *
218
+ * const halfCircle = Math.PI; // PI radians = 180 degrees = 1/2 circle
219
+ * const center = Vec2.of(1, 1); // The point (1,1)
220
+ * const rotationMatrix = Mat33.zRotation(halfCircle, center);
221
+ *
222
+ * console.log(
223
+ * 'Rotating (0,0) 180deg about', center, 'results in',
224
+ * // Rotates (0,0)
225
+ * rotationMatrix.transformVec2(Vec2.zero),
226
+ * );
227
+ * ```
228
+ */
209
229
  static zRotation(radians: number, center?: Point2): Mat33;
210
230
  static scaling2D(amount: number | Vec2, center?: Point2): Mat33;
211
231
  /**
@@ -356,6 +356,26 @@ export class Mat33 {
356
356
  // ...
357
357
  return new Mat33(1, 0, amount.x, 0, 1, amount.y, 0, 0, 1);
358
358
  }
359
+ /**
360
+ * Creates a matrix for rotating `Vec2`s about `center` by some number of `radians`.
361
+ *
362
+ * For this function, {@link Vec2}s are considered to be points in 2D space.
363
+ *
364
+ * For example,
365
+ * ```ts,runnable,console
366
+ * import { Mat33, Vec2 } from '@js-draw/math';
367
+ *
368
+ * const halfCircle = Math.PI; // PI radians = 180 degrees = 1/2 circle
369
+ * const center = Vec2.of(1, 1); // The point (1,1)
370
+ * const rotationMatrix = Mat33.zRotation(halfCircle, center);
371
+ *
372
+ * console.log(
373
+ * 'Rotating (0,0) 180deg about', center, 'results in',
374
+ * // Rotates (0,0)
375
+ * rotationMatrix.transformVec2(Vec2.zero),
376
+ * );
377
+ * ```
378
+ */
359
379
  static zRotation(radians, center = Vec2.zero) {
360
380
  if (radians === 0) {
361
381
  return Mat33.identity;
@@ -404,6 +424,8 @@ export class Mat33 {
404
424
  if (cssString === '' || cssString === 'none') {
405
425
  return Mat33.identity;
406
426
  }
427
+ // Normalize spacing
428
+ cssString = cssString.trim().replace(/\s+/g, ' ');
407
429
  const parseArguments = (argumentString) => {
408
430
  const parsed = argumentString.split(/[, \t\n]+/g).map((argString) => {
409
431
  // Handle trailing spaces/commands
@@ -480,7 +502,7 @@ export class Mat33 {
480
502
  };
481
503
  // A command (\w+)
482
504
  // followed by a set of arguments ([ \t\n0-9eE.,\-%]+)
483
- const partRegex = /\s*(\w+)\s*\(([^)]*)\)/gi;
505
+ const partRegex = /(\w+)\s?\(([^)]*)\)/gi;
484
506
  let match;
485
507
  let matrix = null;
486
508
  while ((match = partRegex.exec(cssString)) !== null) {