@teachinglab/omd 0.1.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 (144) hide show
  1. package/README.md +138 -0
  2. package/canvas/core/canvasConfig.js +203 -0
  3. package/canvas/core/omdCanvas.js +475 -0
  4. package/canvas/drawing/segment.js +168 -0
  5. package/canvas/drawing/stroke.js +386 -0
  6. package/canvas/events/eventManager.js +435 -0
  7. package/canvas/events/pointerEventHandler.js +263 -0
  8. package/canvas/features/focusFrameManager.js +287 -0
  9. package/canvas/index.js +49 -0
  10. package/canvas/tools/eraserTool.js +322 -0
  11. package/canvas/tools/pencilTool.js +319 -0
  12. package/canvas/tools/selectTool.js +457 -0
  13. package/canvas/tools/tool.js +223 -0
  14. package/canvas/tools/toolManager.js +394 -0
  15. package/canvas/ui/cursor.js +438 -0
  16. package/canvas/ui/toolbar.js +304 -0
  17. package/canvas/utils/boundingBox.js +378 -0
  18. package/canvas/utils/mathUtils.js +259 -0
  19. package/docs/api/configuration-options.md +104 -0
  20. package/docs/api/eventManager.md +68 -0
  21. package/docs/api/focusFrameManager.md +150 -0
  22. package/docs/api/index.md +91 -0
  23. package/docs/api/main.md +58 -0
  24. package/docs/api/omdBinaryExpressionNode.md +227 -0
  25. package/docs/api/omdCanvas.md +142 -0
  26. package/docs/api/omdConfigManager.md +192 -0
  27. package/docs/api/omdConstantNode.md +117 -0
  28. package/docs/api/omdDisplay.md +121 -0
  29. package/docs/api/omdEquationNode.md +161 -0
  30. package/docs/api/omdEquationSequenceNode.md +301 -0
  31. package/docs/api/omdEquationStack.md +139 -0
  32. package/docs/api/omdFunctionNode.md +141 -0
  33. package/docs/api/omdGroupNode.md +182 -0
  34. package/docs/api/omdHelpers.md +96 -0
  35. package/docs/api/omdLeafNode.md +163 -0
  36. package/docs/api/omdNode.md +101 -0
  37. package/docs/api/omdOperationDisplayNode.md +139 -0
  38. package/docs/api/omdOperatorNode.md +127 -0
  39. package/docs/api/omdParenthesisNode.md +122 -0
  40. package/docs/api/omdPopup.md +117 -0
  41. package/docs/api/omdPowerNode.md +127 -0
  42. package/docs/api/omdRationalNode.md +128 -0
  43. package/docs/api/omdSequenceNode.md +128 -0
  44. package/docs/api/omdSimplification.md +110 -0
  45. package/docs/api/omdSqrtNode.md +79 -0
  46. package/docs/api/omdStepVisualizer.md +115 -0
  47. package/docs/api/omdStepVisualizerHighlighting.md +61 -0
  48. package/docs/api/omdStepVisualizerInteractiveSteps.md +129 -0
  49. package/docs/api/omdStepVisualizerLayout.md +60 -0
  50. package/docs/api/omdStepVisualizerNodeUtils.md +140 -0
  51. package/docs/api/omdStepVisualizerTextBoxes.md +68 -0
  52. package/docs/api/omdToolbar.md +102 -0
  53. package/docs/api/omdTranscriptionService.md +76 -0
  54. package/docs/api/omdTreeDiff.md +134 -0
  55. package/docs/api/omdUnaryExpressionNode.md +174 -0
  56. package/docs/api/omdUtilities.md +70 -0
  57. package/docs/api/omdVariableNode.md +148 -0
  58. package/docs/api/selectTool.md +74 -0
  59. package/docs/api/simplificationEngine.md +98 -0
  60. package/docs/api/simplificationRules.md +77 -0
  61. package/docs/api/simplificationUtils.md +64 -0
  62. package/docs/api/transcribe.md +43 -0
  63. package/docs/api-reference.md +85 -0
  64. package/docs/index.html +454 -0
  65. package/docs/user-guide.md +9 -0
  66. package/index.js +67 -0
  67. package/omd/config/omdConfigManager.js +267 -0
  68. package/omd/core/index.js +150 -0
  69. package/omd/core/omdEquationStack.js +347 -0
  70. package/omd/core/omdUtilities.js +115 -0
  71. package/omd/display/omdDisplay.js +443 -0
  72. package/omd/display/omdToolbar.js +502 -0
  73. package/omd/nodes/omdBinaryExpressionNode.js +460 -0
  74. package/omd/nodes/omdConstantNode.js +142 -0
  75. package/omd/nodes/omdEquationNode.js +1223 -0
  76. package/omd/nodes/omdEquationSequenceNode.js +1273 -0
  77. package/omd/nodes/omdFunctionNode.js +352 -0
  78. package/omd/nodes/omdGroupNode.js +68 -0
  79. package/omd/nodes/omdLeafNode.js +77 -0
  80. package/omd/nodes/omdNode.js +557 -0
  81. package/omd/nodes/omdOperationDisplayNode.js +322 -0
  82. package/omd/nodes/omdOperatorNode.js +109 -0
  83. package/omd/nodes/omdParenthesisNode.js +293 -0
  84. package/omd/nodes/omdPowerNode.js +236 -0
  85. package/omd/nodes/omdRationalNode.js +295 -0
  86. package/omd/nodes/omdSqrtNode.js +308 -0
  87. package/omd/nodes/omdUnaryExpressionNode.js +178 -0
  88. package/omd/nodes/omdVariableNode.js +123 -0
  89. package/omd/simplification/omdSimplification.js +171 -0
  90. package/omd/simplification/omdSimplificationEngine.js +886 -0
  91. package/omd/simplification/package.json +6 -0
  92. package/omd/simplification/rules/binaryRules.js +1037 -0
  93. package/omd/simplification/rules/functionRules.js +111 -0
  94. package/omd/simplification/rules/index.js +48 -0
  95. package/omd/simplification/rules/parenthesisRules.js +19 -0
  96. package/omd/simplification/rules/powerRules.js +143 -0
  97. package/omd/simplification/rules/rationalRules.js +475 -0
  98. package/omd/simplification/rules/sqrtRules.js +48 -0
  99. package/omd/simplification/rules/unaryRules.js +37 -0
  100. package/omd/simplification/simplificationRules.js +32 -0
  101. package/omd/simplification/simplificationUtils.js +1056 -0
  102. package/omd/step-visualizer/omdStepVisualizer.js +597 -0
  103. package/omd/step-visualizer/omdStepVisualizerHighlighting.js +206 -0
  104. package/omd/step-visualizer/omdStepVisualizerLayout.js +245 -0
  105. package/omd/step-visualizer/omdStepVisualizerTextBoxes.js +163 -0
  106. package/omd/utils/omdNodeOverlay.js +638 -0
  107. package/omd/utils/omdPopup.js +1084 -0
  108. package/omd/utils/omdStepVisualizerInteractiveSteps.js +491 -0
  109. package/omd/utils/omdStepVisualizerNodeUtils.js +268 -0
  110. package/omd/utils/omdTranscriptionService.js +125 -0
  111. package/omd/utils/omdTreeDiff.js +734 -0
  112. package/package.json +46 -0
  113. package/src/index.js +62 -0
  114. package/src/json-schemas.md +109 -0
  115. package/src/omd-json-samples.js +115 -0
  116. package/src/omd.js +109 -0
  117. package/src/omdApp.js +391 -0
  118. package/src/omdAppCanvas.js +336 -0
  119. package/src/omdBalanceHanger.js +172 -0
  120. package/src/omdColor.js +13 -0
  121. package/src/omdCoordinatePlane.js +467 -0
  122. package/src/omdEquation.js +125 -0
  123. package/src/omdExpression.js +104 -0
  124. package/src/omdFunction.js +113 -0
  125. package/src/omdMetaExpression.js +287 -0
  126. package/src/omdNaturalExpression.js +564 -0
  127. package/src/omdNode.js +384 -0
  128. package/src/omdNumber.js +53 -0
  129. package/src/omdNumberLine.js +107 -0
  130. package/src/omdNumberTile.js +119 -0
  131. package/src/omdOperator.js +73 -0
  132. package/src/omdPowerExpression.js +92 -0
  133. package/src/omdProblem.js +55 -0
  134. package/src/omdRatioChart.js +232 -0
  135. package/src/omdRationalExpression.js +115 -0
  136. package/src/omdSampleData.js +215 -0
  137. package/src/omdShapes.js +476 -0
  138. package/src/omdSpinner.js +148 -0
  139. package/src/omdString.js +39 -0
  140. package/src/omdTable.js +369 -0
  141. package/src/omdTapeDiagram.js +245 -0
  142. package/src/omdTerm.js +92 -0
  143. package/src/omdTileEquation.js +349 -0
  144. package/src/omdVariable.js +51 -0
@@ -0,0 +1,259 @@
1
+ export class mathUtils {
2
+ /**
3
+ * Calculate distance between two points
4
+ * @param {Object} p1 - First point {x, y}
5
+ * @param {Object} p2 - Second point {x, y}
6
+ * @returns {number} Distance
7
+ */
8
+ static distance(p1, p2) {
9
+ const dx = p2.x - p1.x;
10
+ const dy = p2.y - p1.y;
11
+ return Math.sqrt(dx * dx + dy * dy);
12
+ }
13
+
14
+ /**
15
+ * Calculate squared distance (faster than distance when just comparing)
16
+ * @param {Object} p1 - First point {x, y}
17
+ * @param {Object} p2 - Second point {x, y}
18
+ * @returns {number} Squared distance
19
+ */
20
+ static distanceSquared(p1, p2) {
21
+ const dx = p2.x - p1.x;
22
+ const dy = p2.y - p1.y;
23
+ return dx * dx + dy * dy;
24
+ }
25
+
26
+ /**
27
+ * Calculate angle between two points
28
+ * @param {Object} p1 - First point {x, y}
29
+ * @param {Object} p2 - Second point {x, y}
30
+ * @returns {number} Angle in radians
31
+ */
32
+ static angle(p1, p2) {
33
+ return Math.atan2(p2.y - p1.y, p2.x - p1.x);
34
+ }
35
+
36
+ /**
37
+ * Calculate angle in degrees
38
+ * @param {Object} p1 - First point {x, y}
39
+ * @param {Object} p2 - Second point {x, y}
40
+ * @returns {number} Angle in degrees
41
+ */
42
+ static angleDegrees(p1, p2) {
43
+ return this.angle(p1, p2) * 180 / Math.PI;
44
+ }
45
+
46
+ /**
47
+ * Linear interpolation between two values
48
+ * @param {number} a - Start value
49
+ * @param {number} b - End value
50
+ * @param {number} t - Interpolation factor (0-1)
51
+ * @returns {number} Interpolated value
52
+ */
53
+ static lerp(a, b, t) {
54
+ return a + (b - a) * t;
55
+ }
56
+
57
+ /**
58
+ * Linear interpolation between two points
59
+ * @param {Object} p1 - Start point {x, y}
60
+ * @param {Object} p2 - End point {x, y}
61
+ * @param {number} t - Interpolation factor (0-1)
62
+ * @returns {Object} Interpolated point {x, y}
63
+ */
64
+ static lerpPoint(p1, p2, t) {
65
+ return {
66
+ x: this.lerp(p1.x, p2.x, t),
67
+ y: this.lerp(p1.y, p2.y, t)
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Clamp value between min and max
73
+ * @param {number} value - Value to clamp
74
+ * @param {number} min - Minimum value
75
+ * @param {number} max - Maximum value
76
+ * @returns {number} Clamped value
77
+ */
78
+ static clamp(value, min, max) {
79
+ return Math.min(Math.max(value, min), max);
80
+ }
81
+
82
+ /**
83
+ * Normalize value from one range to another
84
+ * @param {number} value - Input value
85
+ * @param {number} inMin - Input range minimum
86
+ * @param {number} inMax - Input range maximum
87
+ * @param {number} outMin - Output range minimum
88
+ * @param {number} outMax - Output range maximum
89
+ * @returns {number} Normalized value
90
+ */
91
+ static map(value, inMin, inMax, outMin, outMax) {
92
+ return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
93
+ }
94
+
95
+ /**
96
+ * Calculate distance from point to line segment
97
+ * @param {Object} point - Point {x, y}
98
+ * @param {Object} lineStart - Line start {x, y}
99
+ * @param {Object} lineEnd - Line end {x, y}
100
+ * @returns {number} Distance
101
+ */
102
+ static distanceToLineSegment(point, lineStart, lineEnd) {
103
+ const dx = lineEnd.x - lineStart.x;
104
+ const dy = lineEnd.y - lineStart.y;
105
+ const length = Math.sqrt(dx * dx + dy * dy);
106
+
107
+ if (length === 0) {
108
+ return this.distance(point, lineStart);
109
+ }
110
+
111
+ const t = Math.max(0, Math.min(1, ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (length * length)));
112
+ const projection = {
113
+ x: lineStart.x + t * dx,
114
+ y: lineStart.y + t * dy
115
+ };
116
+
117
+ return this.distance(point, projection);
118
+ }
119
+
120
+ /**
121
+ * Check if point is inside circle
122
+ * @param {Object} point - Point {x, y}
123
+ * @param {Object} center - Circle center {x, y}
124
+ * @param {number} radius - Circle radius
125
+ * @returns {boolean} True if point is inside circle
126
+ */
127
+ static pointInCircle(point, center, radius) {
128
+ return this.distanceSquared(point, center) <= radius * radius;
129
+ }
130
+
131
+ /**
132
+ * Check if point is inside rectangle
133
+ * @param {Object} point - Point {x, y}
134
+ * @param {Object} rect - Rectangle {x, y, width, height}
135
+ * @returns {boolean} True if point is inside rectangle
136
+ */
137
+ static pointInRect(point, rect) {
138
+ return point.x >= rect.x &&
139
+ point.x <= rect.x + rect.width &&
140
+ point.y >= rect.y &&
141
+ point.y <= rect.y + rect.height;
142
+ }
143
+
144
+ /**
145
+ * Smooth an array of points using averaging
146
+ * @param {Array} points - Array of points
147
+ * @param {number} factor - Smoothing factor (0-1)
148
+ * @returns {Array} Smoothed points
149
+ */
150
+ static smoothPoints(points, factor = 0.5) {
151
+ if (points.length < 3) return points;
152
+
153
+ const smoothed = [points[0]]; // Keep first point
154
+
155
+ for (let i = 1; i < points.length - 1; i++) {
156
+ const prev = points[i - 1];
157
+ const curr = points[i];
158
+ const next = points[i + 1];
159
+
160
+ const avgX = (prev.x + curr.x + next.x) / 3;
161
+ const avgY = (prev.y + curr.y + next.y) / 3;
162
+
163
+ smoothed.push({
164
+ x: this.lerp(curr.x, avgX, factor),
165
+ y: this.lerp(curr.y, avgY, factor),
166
+ ...curr // Preserve other properties
167
+ });
168
+ }
169
+
170
+ smoothed.push(points[points.length - 1]); // Keep last point
171
+ return smoothed;
172
+ }
173
+
174
+ /**
175
+ * Generate bezier curve points
176
+ * @param {Object} p0 - Control point 0
177
+ * @param {Object} p1 - Control point 1
178
+ * @param {Object} p2 - Control point 2
179
+ * @param {Object} p3 - Control point 3
180
+ * @param {number} steps - Number of steps
181
+ * @returns {Array} Curve points
182
+ */
183
+ static bezierCurve(p0, p1, p2, p3, steps = 20) {
184
+ const points = [];
185
+
186
+ for (let i = 0; i <= steps; i++) {
187
+ const t = i / steps;
188
+ const u = 1 - t;
189
+ const tt = t * t;
190
+ const uu = u * u;
191
+ const uuu = uu * u;
192
+ const ttt = tt * t;
193
+
194
+ const x = uuu * p0.x + 3 * uu * t * p1.x + 3 * u * tt * p2.x + ttt * p3.x;
195
+ const y = uuu * p0.y + 3 * uu * t * p1.y + 3 * u * tt * p2.y + ttt * p3.y;
196
+
197
+ points.push({ x, y });
198
+ }
199
+
200
+ return points;
201
+ }
202
+
203
+ /**
204
+ * Convert degrees to radians
205
+ * @param {number} degrees - Angle in degrees
206
+ * @returns {number} Angle in radians
207
+ */
208
+ static degreesToRadians(degrees) {
209
+ return degrees * Math.PI / 180;
210
+ }
211
+
212
+ /**
213
+ * Convert radians to degrees
214
+ * @param {number} radians - Angle in radians
215
+ * @returns {number} Angle in degrees
216
+ */
217
+ static radiansToDegrees(radians) {
218
+ return radians * 180 / Math.PI;
219
+ }
220
+
221
+ /**
222
+ * Rotate point around center
223
+ * @param {Object} point - Point to rotate {x, y}
224
+ * @param {Object} center - Center of rotation {x, y}
225
+ * @param {number} angle - Rotation angle in radians
226
+ * @returns {Object} Rotated point {x, y}
227
+ */
228
+ static rotatePoint(point, center, angle) {
229
+ const cos = Math.cos(angle);
230
+ const sin = Math.sin(angle);
231
+ const dx = point.x - center.x;
232
+ const dy = point.y - center.y;
233
+
234
+ return {
235
+ x: center.x + dx * cos - dy * sin,
236
+ y: center.y + dx * sin + dy * cos
237
+ };
238
+ }
239
+
240
+ /**
241
+ * Generate random number between min and max
242
+ * @param {number} min - Minimum value
243
+ * @param {number} max - Maximum value
244
+ * @returns {number} Random number
245
+ */
246
+ static random(min, max) {
247
+ return Math.random() * (max - min) + min;
248
+ }
249
+
250
+ /**
251
+ * Generate random integer between min and max
252
+ * @param {number} min - Minimum value (inclusive)
253
+ * @param {number} max - Maximum value (inclusive)
254
+ * @returns {number} Random integer
255
+ */
256
+ static randomInt(min, max) {
257
+ return Math.floor(Math.random() * (max - min + 1)) + min;
258
+ }
259
+ }
@@ -0,0 +1,104 @@
1
+ # Configuration Options
2
+
3
+ This document details all available configuration options for the OMD library, managed by the `omdConfigManager` module. These options allow you to customize various aspects of the library's behavior, appearance, and mathematical preferences.
4
+
5
+ ## Overview
6
+
7
+ The OMD configuration is a single JavaScript object that can be loaded from a JSON file or set programmatically. It is organized into logical categories.
8
+
9
+ ## Default Configuration Structure
10
+
11
+ If no custom configuration is provided, the library uses the following default structure:
12
+
13
+ ```json
14
+ {
15
+ "multiplication": {
16
+ "symbol": "·",
17
+ "forceImplicit": false,
18
+ "implicitCombinations": {
19
+ "constantVariable": true,
20
+ "variableConstant": false,
21
+ "parenthesisAfterVariable": true,
22
+ "parenthesisAfterConstant": true,
23
+ "variableParenthesis": true,
24
+ "parenthesisParenthesis": true,
25
+ "parenthesisVariable": true,
26
+ "parenthesisConstant": true,
27
+ "variableVariable": true
28
+ }
29
+ },
30
+ "stepVisualizer": {
31
+ "dotSizes": {
32
+ "level0": 8,
33
+ "level1": 6,
34
+ "level2": 4
35
+ },
36
+ "fontWeights": {
37
+ "level0": 400,
38
+ "level1": 300,
39
+ "level2": 200
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Configuration Categories and Options
46
+
47
+ ### `multiplication`
48
+
49
+ Settings related to how multiplication is displayed and handled.
50
+
51
+ - **`symbol`** {string}
52
+ - The character used to represent multiplication. Default: `"·"` (middle dot).
53
+ - Example: `"*"` or `"×"`.
54
+
55
+ - **`forceImplicit`** {boolean}
56
+ - If `true`, implicit multiplication (e.g., `2x` instead of `2 * x`) is always used where mathematically valid, overriding `implicitCombinations`.
57
+ - Default: `false`.
58
+
59
+ - **`implicitCombinations`** {Object}
60
+ - An object defining specific scenarios where implicit multiplication should be used. Each property is a boolean.
61
+ - **`constantVariable`** {boolean}: `2x` (Default: `true`)
62
+ - **`variableConstant`** {boolean}: `x2` (Default: `false`)
63
+ - **`parenthesisAfterVariable`** {boolean}: `x(y+z)` (Default: `true`)
64
+ - **`parenthesisAfterConstant`** {boolean}: `2(x+y)` (Default: `true`)
65
+ - **`variableParenthesis`** {boolean}: `(x+y)z` (Default: `true`)
66
+ - **`parenthesisParenthesis`** {boolean}: `(x+y)(a+b)` (Default: `true`)
67
+ - **`parenthesisVariable`** {boolean}: `(x+y)z` (Default: `true`)
68
+ - **`parenthesisConstant`** {boolean}: `(x+y)2` (Default: `true`)
69
+ - **`variableVariable`** {boolean}: `xy` (Default: `true`)
70
+
71
+ ### `stepVisualizer`
72
+
73
+ Settings specific to the `omdStepVisualizer` component, controlling the appearance of step dots and text.
74
+
75
+ - **`dotSizes`** {Object}
76
+ - Defines the radius of the step dots based on their importance level.
77
+ - **`level0`** {number}: Radius for major steps. Default: `8`.
78
+ - **`level1`** {number}: Radius for minor steps. Default: `6`.
79
+ - **`level2`** {number}: Radius for detailed steps. Default: `4`.
80
+
81
+ - **`fontWeights`** {Object}
82
+ - Defines the font weight for the equations based on their importance level.
83
+ - **`level0`** {number}: Font weight for major steps. Default: `400`.
84
+ - **`level1`** {number}: Font weight for minor steps. Default: `300`.
85
+ - **`level2`** {number}: Font weight for detailed steps. Default: `200`.
86
+
87
+ ## Usage
88
+
89
+ Configuration options can be set during initialization or updated at runtime using the `omdConfigManager` functions. For detailed usage, refer to the [`omdConfigManager`](./omdConfigManager.md) documentation.
90
+
91
+ ```javascript
92
+ import { initializeConfig, setConfigValue, getConfigValue } from 'omd-library';
93
+
94
+ // Initialize with a custom config file
95
+ await initializeConfig('./my-custom-omd-config.json');
96
+
97
+ // Or set options programmatically
98
+ setConfigValue('multiplication.symbol', '*');
99
+ setConfigValue('stepVisualizer.dotSizes.level0', 10);
100
+
101
+ // Retrieve a config value
102
+ const currentSymbol = getConfigValue('multiplication.symbol');
103
+ console.log(currentSymbol); // Output: *
104
+ ```
@@ -0,0 +1,68 @@
1
+ # EventManager
2
+
3
+ The `EventManager` class is responsible for handling all user interactions with the canvas, including pointer events (mouse, touch, pen), keyboard events, and wheel events. It normals these events and delegates them to the appropriate handlers, such as the active tool or the `pointerEventHandler`.
4
+
5
+ ## Class Definition
6
+
7
+ ```javascript
8
+ export class EventManager {
9
+ // ...
10
+ }
11
+ ```
12
+
13
+ ## Constructor
14
+
15
+ ### `new EventManager(canvas)`
16
+
17
+ Creates a new `EventManager` instance.
18
+
19
+ * **canvas** (`OMDCanvas`): The canvas instance.
20
+
21
+ ## Public Methods
22
+
23
+ ### `initialize()`
24
+
25
+ Initializes the event manager and attaches all necessary event listeners to the canvas and document.
26
+
27
+ ### `getPointerInfo()`
28
+
29
+ Gets information about the current state of the pointers.
30
+
31
+ * **Returns**: `object` - An object containing pointer information, including the number of active pointers and whether the user is currently drawing.
32
+
33
+ ### `destroy()`
34
+
35
+ Destroys the event manager and removes all event listeners.
36
+
37
+ ## Event Handling
38
+
39
+ The `EventManager` listens for the following events:
40
+
41
+ * **Pointer Events**: `pointerdown`, `pointermove`, `pointerup`, `pointercancel`, `pointerenter`, `pointerleave`
42
+ * **Keyboard Events**: `keydown`, `keyup`
43
+ * **Wheel Events**: `wheel`
44
+ * **Context Menu**: `contextmenu`
45
+
46
+ When an event occurs, the `EventManager` normalizes it and then delegates it to the appropriate handler. For example, pointer events are passed to the `pointerEventHandler` and the active tool, while keyboard events are used to trigger global shortcuts or are passed to the active tool.
47
+
48
+ ## State Management
49
+
50
+ The `EventManager` tracks the following state:
51
+
52
+ * **`activePointers`**: A map of all currently active pointers on the canvas.
53
+ * **`isDrawing`**: A boolean indicating whether a drawing operation is currently in progress.
54
+ * **`lastEventTime`**: The timestamp of the last processed event, used for throttling.
55
+
56
+ ## Event Emitters
57
+
58
+ The `EventManager` also emits the following events on the canvas instance:
59
+
60
+ * `pointerDown`
61
+ * `pointerMove`
62
+ * `pointerUp`
63
+ * `pointerCancel`
64
+ * `pointerEnter`
65
+ * `pointerLeave`
66
+ * `keyDown`
67
+ * `keyUp`
68
+ * `wheel`
@@ -0,0 +1,150 @@
1
+ # FocusFrameManager
2
+
3
+ The `FocusFrameManager` class is responsible for creating, managing, and capturing content from focus frames on the canvas.
4
+
5
+ ## Class Definition
6
+
7
+ ```javascript
8
+ export class FocusFrameManager {
9
+ // ...
10
+ }
11
+ ```
12
+
13
+ ## Constructor
14
+
15
+ ### `new FocusFrameManager(canvas)`
16
+
17
+ Creates a new `FocusFrameManager` instance.
18
+
19
+ * **canvas** (`OMDCanvas`): The canvas instance.
20
+
21
+ ## Public Methods
22
+
23
+ ### `createFrame([options])`
24
+
25
+ Creates a new focus frame.
26
+
27
+ * **[options]** (`object`, optional): Configuration options for the frame.
28
+ * **x** (`number`, optional): The x-coordinate of the frame. Defaults to `0`.
29
+ * **y** (`number`, optional): The y-coordinate of the frame. Defaults to `0`.
30
+ * **width** (`number`, optional): The width of the frame. Defaults to `200`.
31
+ * **height** (`number`, optional): The height of the frame. Defaults to `150`.
32
+ * **showOutline** (`boolean`, optional): Whether to show the frame outline. Defaults to `true`.
33
+ * **outlineColor** (`string`, optional): The color of the frame outline. Defaults to `'#007bff'`.
34
+ * **outlineWidth** (`number`, optional): The width of the frame outline. Defaults to `2`.
35
+ * **outlineDashed** (`boolean`, optional): Whether the frame outline is dashed. Defaults to `false`.
36
+ * **Returns**: `object` - An object containing the `id` and `frame` of the created frame.
37
+
38
+ ### `removeFrame(frameId)`
39
+
40
+ Removes a focus frame.
41
+
42
+ * **frameId** (`string`): The ID of the frame to remove.
43
+ * **Returns**: `boolean` - `true` if the frame was removed, `false` otherwise.
44
+
45
+ ### `getFrame(frameId)`
46
+
47
+ Gets a focus frame by its ID.
48
+
49
+ * **frameId** (`string`): The ID of the frame to get.
50
+ * **Returns**: `FocusFrame` or `undefined` - The frame instance, or `undefined` if not found.
51
+
52
+ ### `setActiveFrame(frameId)`
53
+
54
+ Sets the active focus frame.
55
+
56
+ * **frameId** (`string`): The ID of the frame to set as active.
57
+ * **Returns**: `boolean` - `true` if the frame was set as active, `false` otherwise.
58
+
59
+ ### `getActiveFrame()`
60
+
61
+ Gets the currently active focus frame.
62
+
63
+ * **Returns**: `FocusFrame` or `null` - The active frame, or `null` if no frame is active.
64
+
65
+ ### `captureActiveFrame()`
66
+
67
+ Captures the content of the active focus frame as an SVG string.
68
+
69
+ * **Returns**: `string` or `null` - The SVG content of the active frame, or `null` if no frame is active.
70
+
71
+ ### `captureAllFrames()`
72
+
73
+ Captures the content of all focus frames.
74
+
75
+ * **Returns**: `Map<string, string>` - A map of frame IDs to their SVG content.
76
+
77
+ ### `clearAllFrames()`
78
+
79
+ Removes all focus frames from the canvas.
80
+
81
+ ### `getFrameIds()`
82
+
83
+ Gets the IDs of all focus frames.
84
+
85
+ * **Returns**: `Array<string>` - An array of frame IDs.
86
+
87
+ ### `destroy()`
88
+
89
+ Destroys the focus frame manager and all associated frames.
90
+
91
+ # FocusFrame
92
+
93
+ The `FocusFrame` class represents an individual focus frame on the canvas.
94
+
95
+ ## Class Definition
96
+
97
+ ```javascript
98
+ class FocusFrame {
99
+ // ...
100
+ }
101
+ ```
102
+
103
+ ## Public Methods
104
+
105
+ ### `setActive(active)`
106
+
107
+ Sets the frame as active or inactive.
108
+
109
+ * **active** (`boolean`): Whether the frame should be active.
110
+
111
+ ### `capture()`
112
+
113
+ Captures the content of the frame as an SVG string.
114
+
115
+ * **Returns**: `string` - The SVG content of the frame.
116
+
117
+ ### `toBitmap([format], [quality])`
118
+
119
+ Converts the frame content to a bitmap.
120
+
121
+ * **[format]** (`string`, optional): The image format. Defaults to `'png'`.
122
+ * **[quality]** (`number`, optional): The image quality. Defaults to `1`.
123
+ * **Returns**: `Promise<Blob>` - A promise that resolves with the bitmap as a `Blob`.
124
+
125
+ ### `downloadAsBitmap([filename], [format])`
126
+
127
+ Downloads the frame content as a bitmap image.
128
+
129
+ * **[filename]** (`string`, optional): The filename for the downloaded image. Defaults to `focus-frame-{id}.png`.
130
+ * **[format]** (`string`, optional): The image format. Defaults to `'png'`.
131
+
132
+ ### `updateBounds(bounds)`
133
+
134
+ Updates the bounds of the frame.
135
+
136
+ * **bounds** (`object`): An object containing the new bounds.
137
+ * **x** (`number`, optional): The new x-coordinate.
138
+ * **y** (`number`, optional): The new y-coordinate.
139
+ * **width** (`number`, optional): The new width.
140
+ * **height** (`number`, optional): The new height.
141
+
142
+ ### `getBounds()`
143
+
144
+ Gets the bounds of the frame.
145
+
146
+ * **Returns**: `object` - An object containing the bounds of the frame.
147
+
148
+ ### `destroy()`
149
+
150
+ Destroys the frame and removes it from the canvas.
@@ -0,0 +1,91 @@
1
+ # OMD Library Entry Point
2
+
3
+ This module (`omd/index.js`) serves as the main entry point for the OMD (Open Math Display) library. It re-exports all core classes, visualization components, and utility functions, making them easily accessible from a single import.
4
+
5
+ ## Overview
6
+
7
+ When you import from `omd-library` (or directly from `omd/index.js`), you gain access to a comprehensive set of tools for building and manipulating mathematical expressions and their visual representations.
8
+
9
+ ## Exports
10
+
11
+ ### Core Node Classes
12
+
13
+ All classes extending `omdNode` are re-exported, allowing you to construct and work with various types of mathematical expressions:
14
+
15
+ - [`omdNode`](./omdNode.md)
16
+ - [`omdBinaryExpressionNode`](./omdBinaryExpressionNode.md)
17
+ - [`omdConstantNode`](./omdConstantNode.md)
18
+ - [`omdEquationNode`](./omdEquationNode.md)
19
+ - [`omdFunctionNode`](./omdFunctionNode.md)
20
+ - [`omdGroupNode`](./omdGroupNode.md)
21
+ - [`omdLeafNode`](./omdLeafNode.md)
22
+ - [`omdOperationDisplayNode`](./omdOperationDisplayNode.md)
23
+ - [`omdOperatorNode`](./omdOperatorNode.md)
24
+ - [`omdParenthesisNode`](./omdParenthesisNode.md)
25
+ - [`omdPowerNode`](./omdPowerNode.md)
26
+ - [`omdRationalNode`](./omdRationalNode.md)
27
+ - [`omdEquationSequenceNode`](./omdEquationSequenceNode.md)
28
+ - [`omdSqrtNode`](./omdSqrtNode.md)
29
+ - [`omdUnaryExpressionNode`](./omdUnaryExpressionNode.md)
30
+ - [`omdVariableNode`](./omdVariableNode.md)
31
+
32
+ ### Visualization Components
33
+
34
+ These classes provide high-level components for rendering and interacting with mathematical expressions:
35
+
36
+ - [`omdStepVisualizer`](./omdStepVisualizer.md)
37
+ - [`omdDisplay`](./omdDisplay.md)
38
+ - [`omdCanvas`](./omdCanvas.md)
39
+ - [`omdToolbar`](./omdToolbar.md)
40
+
41
+ ### Utilities
42
+
43
+ Essential utility functions for parsing, simplification, and configuration management:
44
+
45
+ - `getNodeForAST`: A factory function to get the correct `omdNode` class for a given math.js AST.
46
+ - `simplifyStep`: Applies a single simplification step to an expression.
47
+ - `initializeConfig`: Initializes the OMD configuration.
48
+ - `setConfig`: Sets the OMD configuration.
49
+ - `getDefaultConfig`: Retrieves the default OMD configuration.
50
+ - `omdExpression`: (From `../src/omdExpression.js`) A base class for expressions.
51
+
52
+ ### `omdHelpers`
53
+
54
+ A collection of convenience functions for common operations:
55
+
56
+ #### `createNodeFromExpression(expression, mathjs)`
57
+ - Creates an `omdNode` instance from a string expression using a provided math.js instance.
58
+
59
+ #### `createEquation(equationString)`
60
+ - Creates an `omdEquationNode` from a string representation of an equation.
61
+
62
+ #### `createStepVisualizer(equationStrings)`
63
+ - Creates an `omdStepVisualizer` instance from an array of equation strings.
64
+
65
+ ## Default Export
66
+
67
+ The module also provides a default export, which is an object containing all the re-exported classes and functions, organized into logical groups (`nodes`, `helpers`, etc.). This allows for a more structured import if preferred.
68
+
69
+ ```javascript
70
+ import OMD from 'omd-library';
71
+
72
+ const equation = new omd.omdEquationNode(...);
73
+ const display = new omd.omdDisplay(...);
74
+ ```
75
+
76
+ ## Example Usage
77
+
78
+ ```javascript
79
+ import { omdDisplay, omdEquationNode, omdHelpers } from 'omd-library';
80
+
81
+ // Create an equation using a helper
82
+ const equation = omdHelpers.createEquation('2x + 5 = 15');
83
+
84
+ // Create a display and render the equation
85
+ const displayContainer = document.getElementById('math-container');
86
+ const display = new omdDisplay(displayContainer);
87
+ display.render(equation);
88
+
89
+ // You can also directly access node classes
90
+ const constant = new omdConstantNode({ value: 10 });
91
+ ```