js-draw 0.1.12 → 0.2.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.
Files changed (122) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.firebaserc +5 -0
  3. package/.github/workflows/firebase-hosting-merge.yml +25 -0
  4. package/.github/workflows/firebase-hosting-pull-request.yml +22 -0
  5. package/.github/workflows/github-pages.yml +52 -0
  6. package/CHANGELOG.md +6 -0
  7. package/README.md +11 -6
  8. package/dist/bundle.js +1 -1
  9. package/dist/src/Color4.d.ts +19 -0
  10. package/dist/src/Color4.js +24 -3
  11. package/dist/src/Editor.d.ts +129 -2
  12. package/dist/src/Editor.js +94 -17
  13. package/dist/src/EditorImage.d.ts +7 -2
  14. package/dist/src/EditorImage.js +41 -25
  15. package/dist/src/EventDispatcher.d.ts +18 -0
  16. package/dist/src/EventDispatcher.js +19 -4
  17. package/dist/src/Pointer.js +3 -2
  18. package/dist/src/UndoRedoHistory.js +15 -2
  19. package/dist/src/Viewport.js +4 -1
  20. package/dist/src/bundle/bundled.d.ts +1 -2
  21. package/dist/src/bundle/bundled.js +1 -2
  22. package/dist/src/commands/Duplicate.d.ts +1 -1
  23. package/dist/src/commands/Duplicate.js +3 -4
  24. package/dist/src/commands/Erase.d.ts +1 -1
  25. package/dist/src/commands/Erase.js +6 -5
  26. package/dist/src/commands/SerializableCommand.d.ts +4 -5
  27. package/dist/src/commands/SerializableCommand.js +12 -4
  28. package/dist/src/commands/invertCommand.d.ts +4 -0
  29. package/dist/src/commands/invertCommand.js +44 -0
  30. package/dist/src/commands/lib.d.ts +6 -0
  31. package/dist/src/commands/lib.js +6 -0
  32. package/dist/src/commands/localization.d.ts +1 -0
  33. package/dist/src/commands/localization.js +1 -0
  34. package/dist/src/components/AbstractComponent.d.ts +13 -8
  35. package/dist/src/components/AbstractComponent.js +26 -15
  36. package/dist/src/components/SVGGlobalAttributesObject.d.ts +1 -1
  37. package/dist/src/components/SVGGlobalAttributesObject.js +7 -1
  38. package/dist/src/components/Stroke.d.ts +12 -2
  39. package/dist/src/components/Stroke.js +10 -7
  40. package/dist/src/components/Text.d.ts +2 -2
  41. package/dist/src/components/Text.js +6 -6
  42. package/dist/src/components/UnknownSVGObject.d.ts +1 -1
  43. package/dist/src/components/UnknownSVGObject.js +6 -1
  44. package/dist/src/components/lib.d.ts +4 -0
  45. package/dist/src/components/lib.js +4 -0
  46. package/dist/src/lib.d.ts +25 -0
  47. package/dist/src/lib.js +25 -0
  48. package/dist/src/math/Mat33.d.ts +47 -1
  49. package/dist/src/math/Mat33.js +48 -20
  50. package/dist/src/math/Path.js +3 -3
  51. package/dist/src/math/Rect2.d.ts +2 -2
  52. package/dist/src/math/Vec3.d.ts +62 -0
  53. package/dist/src/math/Vec3.js +62 -14
  54. package/dist/src/math/lib.d.ts +7 -0
  55. package/dist/src/math/lib.js +7 -0
  56. package/dist/src/math/rounding.js +1 -0
  57. package/dist/src/rendering/Display.d.ts +44 -0
  58. package/dist/src/rendering/Display.js +45 -6
  59. package/dist/src/rendering/caching/CacheRecord.d.ts +1 -0
  60. package/dist/src/rendering/caching/CacheRecord.js +3 -0
  61. package/dist/src/rendering/caching/CacheRecordManager.d.ts +4 -3
  62. package/dist/src/rendering/caching/CacheRecordManager.js +16 -4
  63. package/dist/src/rendering/caching/RenderingCache.d.ts +2 -3
  64. package/dist/src/rendering/caching/RenderingCache.js +9 -10
  65. package/dist/src/rendering/caching/types.d.ts +1 -3
  66. package/dist/src/rendering/renderers/CanvasRenderer.js +1 -1
  67. package/dist/src/toolbar/HTMLToolbar.js +1 -0
  68. package/dist/src/toolbar/makeColorInput.js +1 -1
  69. package/dist/src/toolbar/widgets/PenWidget.js +1 -0
  70. package/dist/src/tools/Pen.d.ts +1 -2
  71. package/dist/src/tools/Pen.js +8 -1
  72. package/dist/src/tools/PipetteTool.js +1 -0
  73. package/dist/src/tools/SelectionTool.js +45 -22
  74. package/dist/src/types.d.ts +17 -6
  75. package/dist/src/types.js +7 -5
  76. package/firebase.json +16 -0
  77. package/package.json +118 -101
  78. package/src/Color4.ts +23 -2
  79. package/src/Editor.ts +147 -25
  80. package/src/EditorImage.ts +45 -27
  81. package/src/EventDispatcher.ts +21 -6
  82. package/src/Pointer.ts +3 -2
  83. package/src/UndoRedoHistory.ts +18 -2
  84. package/src/Viewport.ts +5 -2
  85. package/src/bundle/bundled.ts +1 -2
  86. package/src/commands/Duplicate.ts +3 -4
  87. package/src/commands/Erase.ts +6 -5
  88. package/src/commands/SerializableCommand.ts +17 -9
  89. package/src/commands/invertCommand.ts +51 -0
  90. package/src/commands/lib.ts +14 -0
  91. package/src/commands/localization.ts +2 -0
  92. package/src/components/AbstractComponent.ts +31 -20
  93. package/src/components/SVGGlobalAttributesObject.ts +8 -1
  94. package/src/components/Stroke.test.ts +1 -1
  95. package/src/components/Stroke.ts +11 -7
  96. package/src/components/Text.ts +6 -7
  97. package/src/components/UnknownSVGObject.ts +7 -1
  98. package/src/components/lib.ts +9 -0
  99. package/src/lib.ts +28 -0
  100. package/src/math/Mat33.ts +48 -20
  101. package/src/math/Path.ts +3 -3
  102. package/src/math/Rect2.ts +2 -2
  103. package/src/math/Vec3.ts +62 -14
  104. package/src/math/lib.ts +15 -0
  105. package/src/math/rounding.ts +2 -0
  106. package/src/rendering/Display.ts +46 -6
  107. package/src/rendering/caching/CacheRecord.test.ts +1 -1
  108. package/src/rendering/caching/CacheRecord.ts +4 -0
  109. package/src/rendering/caching/CacheRecordManager.ts +33 -7
  110. package/src/rendering/caching/RenderingCache.ts +10 -15
  111. package/src/rendering/caching/types.ts +1 -6
  112. package/src/rendering/renderers/CanvasRenderer.ts +1 -1
  113. package/src/toolbar/HTMLToolbar.ts +1 -0
  114. package/src/toolbar/makeColorInput.ts +1 -1
  115. package/src/toolbar/widgets/PenWidget.ts +2 -0
  116. package/src/tools/PanZoom.ts +0 -1
  117. package/src/tools/Pen.ts +11 -2
  118. package/src/tools/PipetteTool.ts +2 -0
  119. package/src/tools/SelectionTool.ts +46 -18
  120. package/src/types.ts +19 -3
  121. package/tsconfig.json +4 -1
  122. package/typedoc.json +20 -0
@@ -0,0 +1,4 @@
1
+ import AbstractComponent from './AbstractComponent';
2
+ import Stroke from './Stroke';
3
+ import Text from './Text';
4
+ export { AbstractComponent, Stroke, Text, };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The main entrypoint for the NPM package. Everything exported by this file
3
+ * is available through the `js-draw` package.
4
+ *
5
+ * @example
6
+ * ```
7
+ * import { Editor, Vec3, Mat33 } from 'js-draw';
8
+ * ```
9
+ *
10
+ * @see
11
+ * {@link Editor!}
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ import Editor from './Editor';
16
+ export { EditorEventType } from './types';
17
+ export { default as getLocalizationTable } from './localizations/getLocalizationTable';
18
+ export * from './localization';
19
+ export { default as Color4 } from './Color4';
20
+ export * from './math/lib';
21
+ export * from './components/lib';
22
+ export * from './commands/lib';
23
+ export { default as HTMLToolbar } from './toolbar/HTMLToolbar';
24
+ export { Editor };
25
+ export default Editor;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The main entrypoint for the NPM package. Everything exported by this file
3
+ * is available through the `js-draw` package.
4
+ *
5
+ * @example
6
+ * ```
7
+ * import { Editor, Vec3, Mat33 } from 'js-draw';
8
+ * ```
9
+ *
10
+ * @see
11
+ * {@link Editor!}
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ import Editor from './Editor';
16
+ export { EditorEventType } from './types';
17
+ export { default as getLocalizationTable } from './localizations/getLocalizationTable';
18
+ export * from './localization';
19
+ export { default as Color4 } from './Color4';
20
+ export * from './math/lib';
21
+ export * from './components/lib';
22
+ export * from './commands/lib';
23
+ export { default as HTMLToolbar } from './toolbar/HTMLToolbar';
24
+ export { Editor };
25
+ export default Editor;
@@ -1,5 +1,10 @@
1
1
  import { Point2, Vec2 } from './Vec2';
2
2
  import Vec3 from './Vec3';
3
+ /**
4
+ * Represents a three dimensional linear transformation or
5
+ * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
6
+ * **and** translates while a linear transformation just scales/rotates/shears).
7
+ */
3
8
  export default class Mat33 {
4
9
  readonly a1: number;
5
10
  readonly a2: number;
@@ -11,22 +16,63 @@ export default class Mat33 {
11
16
  readonly c2: number;
12
17
  readonly c3: number;
13
18
  private readonly rows;
19
+ /**
20
+ * Creates a matrix from inputs in the form,
21
+ * ```
22
+ * ⎡ a1 a2 a3 ⎤
23
+ * ⎢ b1 b2 b3 ⎥
24
+ * ⎣ c1 c2 c3 ⎦
25
+ * ```
26
+ */
14
27
  constructor(a1: number, a2: number, a3: number, b1: number, b2: number, b3: number, c1: number, c2: number, c3: number);
28
+ /**
29
+ * Creates a matrix from the given rows:
30
+ * ```
31
+ * ⎡ r1.x r1.y r1.z ⎤
32
+ * ⎢ r2.x r2.y r2.z ⎥
33
+ * ⎣ r3.x r3.y r3.z ⎦
34
+ * ```
35
+ */
15
36
  static ofRows(r1: Vec3, r2: Vec3, r3: Vec3): Mat33;
16
37
  static identity: Mat33;
38
+ /**
39
+ * Either returns the inverse of this, or, if this matrix is singular/uninvertable,
40
+ * returns Mat33.identity.
41
+ *
42
+ * This may cache the computed inverse and return the cached version instead of recomputing
43
+ * it.
44
+ */
17
45
  inverse(): Mat33;
18
46
  invertable(): boolean;
19
47
  private cachedInverse;
20
48
  private computeInverse;
21
49
  transposed(): Mat33;
22
50
  rightMul(other: Mat33): Mat33;
23
- transformVec2(other: Vec3): Vec2;
51
+ /**
52
+ * Applies this as an affine transformation to the given vector.
53
+ * Returns a transformed version of `other`.
54
+ */
55
+ transformVec2(other: Vec2): Vec2;
56
+ /**
57
+ * Applies this as a linear transformation to the given vector (doesn't translate).
58
+ * This is the standard way of transforming vectors in ℝ³.
59
+ */
24
60
  transformVec3(other: Vec3): Vec3;
61
+ /** Returns true iff this = other ± fuzz */
25
62
  eq(other: Mat33, fuzz?: number): boolean;
26
63
  toString(): string;
64
+ /**
65
+ * ```
66
+ * result[0] = top left element
67
+ * result[1] = element at row zero, column 1
68
+ * ...
69
+ * ```
70
+ */
27
71
  toArray(): number[];
72
+ /** Constructs a 3x3 translation matrix (for translating `Vec2`s) */
28
73
  static translation(amount: Vec2): Mat33;
29
74
  static zRotation(radians: number, center?: Point2): Mat33;
30
75
  static scaling2D(amount: number | Vec2, center?: Point2): Mat33;
76
+ /** Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33. */
31
77
  static fromCSSMatrix(cssString: string): Mat33;
32
78
  }
@@ -1,12 +1,19 @@
1
1
  import { Vec2 } from './Vec2';
2
2
  import Vec3 from './Vec3';
3
- // Represents a three dimensional linear transformation or
4
- // a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
5
- // **and** translates while a linear transformation just scales/rotates/shears).
3
+ /**
4
+ * Represents a three dimensional linear transformation or
5
+ * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
6
+ * **and** translates while a linear transformation just scales/rotates/shears).
7
+ */
6
8
  export default class Mat33 {
7
- // ⎡ a1 a2 a3 ⎤
8
- // b1 b2 b3
9
- // ⎣ c1 c2 c3 ⎦
9
+ /**
10
+ * Creates a matrix from inputs in the form,
11
+ * ```
12
+ * ⎡ a1 a2 a3 ⎤
13
+ * ⎢ b1 b2 b3 ⎥
14
+ * ⎣ c1 c2 c3 ⎦
15
+ * ```
16
+ */
10
17
  constructor(a1, a2, a3, b1, b2, b3, c1, c2, c3) {
11
18
  this.a1 = a1;
12
19
  this.a2 = a2;
@@ -24,11 +31,24 @@ export default class Mat33 {
24
31
  Vec3.of(c1, c2, c3),
25
32
  ];
26
33
  }
34
+ /**
35
+ * Creates a matrix from the given rows:
36
+ * ```
37
+ * ⎡ r1.x r1.y r1.z ⎤
38
+ * ⎢ r2.x r2.y r2.z ⎥
39
+ * ⎣ r3.x r3.y r3.z ⎦
40
+ * ```
41
+ */
27
42
  static ofRows(r1, r2, r3) {
28
43
  return new Mat33(r1.x, r1.y, r1.z, r2.x, r2.y, r2.z, r3.x, r3.y, r3.z);
29
44
  }
30
- // Either returns the inverse of this, or, if this matrix is singular/uninvertable,
31
- // returns Mat33.identity.
45
+ /**
46
+ * Either returns the inverse of this, or, if this matrix is singular/uninvertable,
47
+ * returns Mat33.identity.
48
+ *
49
+ * This may cache the computed inverse and return the cached version instead of recomputing
50
+ * it.
51
+ */
32
52
  inverse() {
33
53
  var _a;
34
54
  return (_a = this.computeInverse()) !== null && _a !== void 0 ? _a : Mat33.identity;
@@ -109,8 +129,10 @@ export default class Mat33 {
109
129
  };
110
130
  return new Mat33(at(0, 0), at(0, 1), at(0, 2), at(1, 0), at(1, 1), at(1, 2), at(2, 0), at(2, 1), at(2, 2));
111
131
  }
112
- // Applies this as an affine transformation to the given vector.
113
- // Returns a transformed version of [other].
132
+ /**
133
+ * Applies this as an affine transformation to the given vector.
134
+ * Returns a transformed version of `other`.
135
+ */
114
136
  transformVec2(other) {
115
137
  // When transforming a Vec2, we want to use the z transformation
116
138
  // components of this for translation:
@@ -124,12 +146,14 @@ export default class Mat33 {
124
146
  // Drop the z=1 to allow magnitude to work as expected
125
147
  return Vec2.of(intermediate.x, intermediate.y);
126
148
  }
127
- // Applies this as a linear transformation to the given vector (doesn't translate).
128
- // This is the standard way of transforming vectors in ℝ³.
149
+ /**
150
+ * Applies this as a linear transformation to the given vector (doesn't translate).
151
+ * This is the standard way of transforming vectors in ℝ³.
152
+ */
129
153
  transformVec3(other) {
130
154
  return Vec3.of(this.rows[0].dot(other), this.rows[1].dot(other), this.rows[2].dot(other));
131
155
  }
132
- // Returns true iff this = other ± fuzz
156
+ /** Returns true iff this = other ± fuzz */
133
157
  eq(other, fuzz = 0) {
134
158
  for (let i = 0; i < 3; i++) {
135
159
  if (!this.rows[i].eq(other.rows[i], fuzz)) {
@@ -143,11 +167,15 @@ export default class Mat33 {
143
167
  ⎡ ${this.a1},\t ${this.a2},\t ${this.a3}\t ⎤
144
168
  ⎢ ${this.b1},\t ${this.b2},\t ${this.b3}\t ⎥
145
169
  ⎣ ${this.c1},\t ${this.c2},\t ${this.c3}\t ⎦
146
- `.trimRight();
147
- }
148
- // result[0] = top left element
149
- // result[1] = element at row zero, column 1
150
- // ...
170
+ `.trimEnd().trimStart();
171
+ }
172
+ /**
173
+ * ```
174
+ * result[0] = top left element
175
+ * result[1] = element at row zero, column 1
176
+ * ...
177
+ * ```
178
+ */
151
179
  toArray() {
152
180
  return [
153
181
  this.a1, this.a2, this.a3,
@@ -155,7 +183,7 @@ export default class Mat33 {
155
183
  this.c1, this.c2, this.c3,
156
184
  ];
157
185
  }
158
- // Constructs a 3x3 translation matrix (for translating Vec2s)
186
+ /** Constructs a 3x3 translation matrix (for translating `Vec2`s) */
159
187
  static translation(amount) {
160
188
  // When transforming Vec2s by a 3x3 matrix, we give the input
161
189
  // Vec2s z = 1. As such,
@@ -186,7 +214,7 @@ export default class Mat33 {
186
214
  // Translate such that [center] goes to (0, 0)
187
215
  return result.rightMul(Mat33.translation(center.times(-1)));
188
216
  }
189
- // Converts a CSS-form matrix(a, b, c, d, e, f) to a Mat33.
217
+ /** Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33. */
190
218
  static fromCSSMatrix(cssString) {
191
219
  if (cssString === '' || cssString === 'none') {
192
220
  return Mat33.identity;
@@ -215,8 +215,8 @@ export default class Path {
215
215
  serialize() {
216
216
  return this.toString();
217
217
  }
218
- // [onlyAbsCommands]: True if we should avoid converting absolute coordinates to relative offsets -- such
219
- // conversions can lead to smaller output strings, but also take time.
218
+ // @param onlyAbsCommands - True if we should avoid converting absolute coordinates to relative offsets -- such
219
+ // conversions can lead to smaller output strings, but also take time.
220
220
  static toString(startPoint, parts, onlyAbsCommands = true) {
221
221
  const result = [];
222
222
  let prevPoint;
@@ -286,7 +286,7 @@ export default class Path {
286
286
  }
287
287
  // Create a Path from a SVG path specification.
288
288
  // TODO: Support a larger subset of SVG paths.
289
- // TODO: Support s,t shorthands.
289
+ // TODO: Support `s`,`t` commands shorthands.
290
290
  static fromString(pathString) {
291
291
  // See the MDN reference:
292
292
  // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
@@ -1,7 +1,8 @@
1
1
  import LineSegment2 from './LineSegment2';
2
2
  import Mat33 from './Mat33';
3
3
  import { Point2, Vec2 } from './Vec2';
4
- interface RectTemplate {
4
+ /** An object that can be converted to a Rect2. */
5
+ export interface RectTemplate {
5
6
  x: number;
6
7
  y: number;
7
8
  w?: number;
@@ -48,4 +49,3 @@ export default class Rect2 {
48
49
  static empty: Rect2;
49
50
  static unitSquare: Rect2;
50
51
  }
51
- export {};
@@ -1,30 +1,92 @@
1
+ /**
2
+ * A vector with three components. Can also be used to represent a two-component vector.
3
+ *
4
+ * A `Vec3` is immutable.
5
+ */
1
6
  export default class Vec3 {
2
7
  readonly x: number;
3
8
  readonly y: number;
4
9
  readonly z: number;
5
10
  private constructor();
11
+ /** Returns the x, y components of this. */
6
12
  get xy(): {
7
13
  x: number;
8
14
  y: number;
9
15
  };
10
16
  static of(x: number, y: number, z: number): Vec3;
17
+ /** Returns this' `idx`th component. For example, `Vec3.of(1, 2, 3).at(1) → 2`. */
11
18
  at(idx: number): number;
19
+ /** Alias for this.magnitude. */
12
20
  length(): number;
13
21
  magnitude(): number;
14
22
  magnitudeSquared(): number;
23
+ /**
24
+ * Return this' angle in the XY plane (treats this as a Vec2).
25
+ *
26
+ * This is equivalent to `Math.atan2(vec.y, vec.x)`.
27
+ */
15
28
  angle(): number;
29
+ /**
30
+ * Returns a unit vector in the same direction as this.
31
+ *
32
+ * If `this` has zero length, the resultant vector has `NaN` components.
33
+ */
16
34
  normalized(): Vec3;
35
+ /** @returns A copy of `this` multiplied by a scalar. */
17
36
  times(c: number): Vec3;
18
37
  plus(v: Vec3): Vec3;
19
38
  minus(v: Vec3): Vec3;
20
39
  dot(other: Vec3): number;
21
40
  cross(other: Vec3): Vec3;
41
+ /**
42
+ * Returns a vector orthogonal to this. If this is a Vec2, returns `this` rotated
43
+ * 90 degrees counter-clockwise.
44
+ */
22
45
  orthog(): Vec3;
46
+ /** Returns this plus a vector of length `distance` in `direction`. */
23
47
  extend(distance: number, direction: Vec3): Vec3;
48
+ /** Returns a vector `fractionTo` of the way to target from this. */
24
49
  lerp(target: Vec3, fractionTo: number): Vec3;
50
+ /**
51
+ * `zip` Maps a component of this and a corresponding component of
52
+ * `other` to a component of the output vector.
53
+ *
54
+ * @example
55
+ * ```
56
+ * const a = Vec3.of(1, 2, 3);
57
+ * const b = Vec3.of(0.5, 2.1, 2.9);
58
+ *
59
+ * const zipped = a.zip(b, (aComponent, bComponent) => {
60
+ * return Math.min(aComponent, bComponent);
61
+ * });
62
+ *
63
+ * console.log(zipped.toString()); // → Vec(0.5, 2, 2.9)
64
+ * ```
65
+ */
25
66
  zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
67
+ /**
68
+ * Returns a vector with each component acted on by `fn`.
69
+ *
70
+ * @example
71
+ * ```
72
+ * console.log(Vec3.of(1, 2, 3).map(val => val + 1)); // → Vec(2, 3, 4)
73
+ * ```
74
+ */
26
75
  map(fn: (component: number, index: number) => number): Vec3;
27
76
  asArray(): number[];
77
+ /**
78
+ * [fuzz] The maximum difference between two components for this and [other]
79
+ * to be considered equal.
80
+ *
81
+ * @example
82
+ * ```
83
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 100); // → true
84
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 0.1); // → false
85
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3); // → true
86
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3.01); // → true
87
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 2.99); // → false
88
+ * ```
89
+ */
28
90
  eq(other: Vec3, fuzz: number): boolean;
29
91
  toString(): string;
30
92
  static unitX: Vec3;
@@ -1,11 +1,15 @@
1
- // A vector with three components. Can also be used to represent a two-component vector
1
+ /**
2
+ * A vector with three components. Can also be used to represent a two-component vector.
3
+ *
4
+ * A `Vec3` is immutable.
5
+ */
2
6
  export default class Vec3 {
3
7
  constructor(x, y, z) {
4
8
  this.x = x;
5
9
  this.y = y;
6
10
  this.z = z;
7
11
  }
8
- // Returns the x, y components of this
12
+ /** Returns the x, y components of this. */
9
13
  get xy() {
10
14
  // Useful for APIs that behave differently if .z is present.
11
15
  return {
@@ -16,7 +20,7 @@ export default class Vec3 {
16
20
  static of(x, y, z) {
17
21
  return new Vec3(x, y, z);
18
22
  }
19
- // Returns this' [idx]th component
23
+ /** Returns this' `idx`th component. For example, `Vec3.of(1, 2, 3).at(1) → 2`. */
20
24
  at(idx) {
21
25
  if (idx === 0)
22
26
  return this.x;
@@ -26,7 +30,7 @@ export default class Vec3 {
26
30
  return this.z;
27
31
  throw new Error(`${idx} out of bounds!`);
28
32
  }
29
- // Alias for this.magnitude
33
+ /** Alias for this.magnitude. */
30
34
  length() {
31
35
  return this.magnitude();
32
36
  }
@@ -36,14 +40,24 @@ export default class Vec3 {
36
40
  magnitudeSquared() {
37
41
  return this.dot(this);
38
42
  }
39
- // Return this' angle in the XY plane (treats this as a Vec2)
43
+ /**
44
+ * Return this' angle in the XY plane (treats this as a Vec2).
45
+ *
46
+ * This is equivalent to `Math.atan2(vec.y, vec.x)`.
47
+ */
40
48
  angle() {
41
49
  return Math.atan2(this.y, this.x);
42
50
  }
51
+ /**
52
+ * Returns a unit vector in the same direction as this.
53
+ *
54
+ * If `this` has zero length, the resultant vector has `NaN` components.
55
+ */
43
56
  normalized() {
44
57
  const norm = this.magnitude();
45
58
  return Vec3.of(this.x / norm, this.y / norm, this.z / norm);
46
59
  }
60
+ /** @returns A copy of `this` multiplied by a scalar. */
47
61
  times(c) {
48
62
  return Vec3.of(this.x * c, this.y * c, this.z * c);
49
63
  }
@@ -62,8 +76,10 @@ export default class Vec3 {
62
76
  // | x2 y2 z2|
63
77
  return Vec3.of(this.y * other.z - other.y * this.z, other.x * this.z - this.x * other.z, this.x * other.y - other.x * this.y);
64
78
  }
65
- // Returns a vector orthogonal to this. If this is a Vec2, returns [this] rotated
66
- // 90 degrees counter-clockwise.
79
+ /**
80
+ * Returns a vector orthogonal to this. If this is a Vec2, returns `this` rotated
81
+ * 90 degrees counter-clockwise.
82
+ */
67
83
  orthog() {
68
84
  // If parallel to the z-axis
69
85
  if (this.dot(Vec3.unitX) === 0 && this.dot(Vec3.unitY) === 0) {
@@ -71,28 +87,60 @@ export default class Vec3 {
71
87
  }
72
88
  return this.cross(Vec3.unitZ.times(-1)).normalized();
73
89
  }
74
- // Returns this plus a vector of length [distance] in [direction]
90
+ /** Returns this plus a vector of length `distance` in `direction`. */
75
91
  extend(distance, direction) {
76
92
  return this.plus(direction.normalized().times(distance));
77
93
  }
78
- // Returns a vector [fractionTo] of the way to target from this.
94
+ /** Returns a vector `fractionTo` of the way to target from this. */
79
95
  lerp(target, fractionTo) {
80
96
  return this.times(1 - fractionTo).plus(target.times(fractionTo));
81
97
  }
82
- // [zip] Maps a component of this and a corresponding component of
83
- // [other] to a component of the output vector.
98
+ /**
99
+ * `zip` Maps a component of this and a corresponding component of
100
+ * `other` to a component of the output vector.
101
+ *
102
+ * @example
103
+ * ```
104
+ * const a = Vec3.of(1, 2, 3);
105
+ * const b = Vec3.of(0.5, 2.1, 2.9);
106
+ *
107
+ * const zipped = a.zip(b, (aComponent, bComponent) => {
108
+ * return Math.min(aComponent, bComponent);
109
+ * });
110
+ *
111
+ * console.log(zipped.toString()); // → Vec(0.5, 2, 2.9)
112
+ * ```
113
+ */
84
114
  zip(other, zip) {
85
115
  return Vec3.of(zip(other.x, this.x), zip(other.y, this.y), zip(other.z, this.z));
86
116
  }
87
- // Returns a vector with each component acted on by [fn]
117
+ /**
118
+ * Returns a vector with each component acted on by `fn`.
119
+ *
120
+ * @example
121
+ * ```
122
+ * console.log(Vec3.of(1, 2, 3).map(val => val + 1)); // → Vec(2, 3, 4)
123
+ * ```
124
+ */
88
125
  map(fn) {
89
126
  return Vec3.of(fn(this.x, 0), fn(this.y, 1), fn(this.z, 2));
90
127
  }
91
128
  asArray() {
92
129
  return [this.x, this.y, this.z];
93
130
  }
94
- // [fuzz] The maximum difference between two components for this and [other]
95
- // to be considered equal.
131
+ /**
132
+ * [fuzz] The maximum difference between two components for this and [other]
133
+ * to be considered equal.
134
+ *
135
+ * @example
136
+ * ```
137
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 100); // → true
138
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 0.1); // → false
139
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3); // → true
140
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3.01); // → true
141
+ * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 2.99); // → false
142
+ * ```
143
+ */
96
144
  eq(other, fuzz) {
97
145
  for (let i = 0; i < 3; i++) {
98
146
  if (Math.abs(other.at(i) - this.at(i)) > fuzz) {
@@ -0,0 +1,7 @@
1
+ import LineSegment2 from './LineSegment2';
2
+ import Mat33 from './Mat33';
3
+ import Path from './Path';
4
+ import Rect2 from './Rect2';
5
+ import { Vec2 } from './Vec2';
6
+ import Vec3 from './Vec3';
7
+ export { LineSegment2, Mat33, Path, Rect2, Vec3, Vec2, };
@@ -0,0 +1,7 @@
1
+ import LineSegment2 from './LineSegment2';
2
+ import Mat33 from './Mat33';
3
+ import Path from './Path';
4
+ import Rect2 from './Rect2';
5
+ import { Vec2 } from './Vec2';
6
+ import Vec3 from './Vec3';
7
+ export { LineSegment2, Mat33, Path, Rect2, Vec3, Vec2, };
@@ -1,3 +1,4 @@
1
+ // @packageDocumentation @internal
1
2
  // Clean up stringified numbers
2
3
  const cleanUpNumber = (text) => {
3
4
  // Regular expression substitions can be somewhat expensive. Only do them
@@ -1,3 +1,17 @@
1
+ /**
2
+ * Handles `HTMLCanvasElement`s (or other drawing surfaces if being used) used to display the editor's contents.
3
+ *
4
+ * @example
5
+ * ```
6
+ * const editor = new Editor(document.body);
7
+ * const w = editor.display.width;
8
+ * const h = editor.display.height;
9
+ * const center = Vec2.of(w / 2, h / 2);
10
+ * const colorAtCenter = editor.display.getColorAt(center);
11
+ * ```
12
+ *
13
+ * @packageDocumentation
14
+ */
1
15
  import AbstractRenderer from './renderers/AbstractRenderer';
2
16
  import { Editor } from '../Editor';
3
17
  import { Point2 } from '../math/Vec2';
@@ -17,17 +31,47 @@ export default class Display {
17
31
  private cache;
18
32
  private resizeSurfacesCallback?;
19
33
  private flattenCallback?;
34
+ /** @internal */
20
35
  constructor(editor: Editor, mode: RenderingMode, parent: HTMLElement | null);
36
+ /**
37
+ * @returns the visible width of the display (e.g. how much
38
+ * space the display's element takes up in the x direction
39
+ * in the DOM).
40
+ */
21
41
  get width(): number;
22
42
  get height(): number;
43
+ /** @internal */
23
44
  getCache(): RenderingCache;
45
+ /**
46
+ * @returns the color at the given point on the dry ink renderer, or `null` if `screenPos`
47
+ * is not on the display.
48
+ */
24
49
  getColorAt: (_screenPos: Point2) => Color4 | null;
25
50
  private initializeCanvasRendering;
26
51
  private initializeTextRendering;
52
+ /**
53
+ * Rerenders the text-based display.
54
+ * The text-based display is intended for screen readers and can be navigated to by pressing `tab`.
55
+ */
27
56
  rerenderAsText(): void;
57
+ /**
58
+ * Clears the drawing surfaces and otherwise prepares for a rerender.
59
+ *
60
+ * @returns the dry ink renderer.
61
+ */
28
62
  startRerender(): AbstractRenderer;
63
+ /**
64
+ * If `draftMode`, the dry ink renderer is configured to render
65
+ * low-quality output.
66
+ */
29
67
  setDraftMode(draftMode: boolean): void;
68
+ /** @internal */
30
69
  getDryInkRenderer(): AbstractRenderer;
70
+ /**
71
+ * @returns The renderer used for showing action previews (e.g. an unfinished stroke).
72
+ * The `wetInkRenderer`'s surface is stacked above the `dryInkRenderer`'s.
73
+ */
31
74
  getWetInkRenderer(): AbstractRenderer;
75
+ /** Re-renders the contents of the wetInkRenderer onto the dryInkRenderer. */
32
76
  flatten(): void;
33
77
  }