@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.
- package/README.md +138 -0
- package/canvas/core/canvasConfig.js +203 -0
- package/canvas/core/omdCanvas.js +475 -0
- package/canvas/drawing/segment.js +168 -0
- package/canvas/drawing/stroke.js +386 -0
- package/canvas/events/eventManager.js +435 -0
- package/canvas/events/pointerEventHandler.js +263 -0
- package/canvas/features/focusFrameManager.js +287 -0
- package/canvas/index.js +49 -0
- package/canvas/tools/eraserTool.js +322 -0
- package/canvas/tools/pencilTool.js +319 -0
- package/canvas/tools/selectTool.js +457 -0
- package/canvas/tools/tool.js +223 -0
- package/canvas/tools/toolManager.js +394 -0
- package/canvas/ui/cursor.js +438 -0
- package/canvas/ui/toolbar.js +304 -0
- package/canvas/utils/boundingBox.js +378 -0
- package/canvas/utils/mathUtils.js +259 -0
- package/docs/api/configuration-options.md +104 -0
- package/docs/api/eventManager.md +68 -0
- package/docs/api/focusFrameManager.md +150 -0
- package/docs/api/index.md +91 -0
- package/docs/api/main.md +58 -0
- package/docs/api/omdBinaryExpressionNode.md +227 -0
- package/docs/api/omdCanvas.md +142 -0
- package/docs/api/omdConfigManager.md +192 -0
- package/docs/api/omdConstantNode.md +117 -0
- package/docs/api/omdDisplay.md +121 -0
- package/docs/api/omdEquationNode.md +161 -0
- package/docs/api/omdEquationSequenceNode.md +301 -0
- package/docs/api/omdEquationStack.md +139 -0
- package/docs/api/omdFunctionNode.md +141 -0
- package/docs/api/omdGroupNode.md +182 -0
- package/docs/api/omdHelpers.md +96 -0
- package/docs/api/omdLeafNode.md +163 -0
- package/docs/api/omdNode.md +101 -0
- package/docs/api/omdOperationDisplayNode.md +139 -0
- package/docs/api/omdOperatorNode.md +127 -0
- package/docs/api/omdParenthesisNode.md +122 -0
- package/docs/api/omdPopup.md +117 -0
- package/docs/api/omdPowerNode.md +127 -0
- package/docs/api/omdRationalNode.md +128 -0
- package/docs/api/omdSequenceNode.md +128 -0
- package/docs/api/omdSimplification.md +110 -0
- package/docs/api/omdSqrtNode.md +79 -0
- package/docs/api/omdStepVisualizer.md +115 -0
- package/docs/api/omdStepVisualizerHighlighting.md +61 -0
- package/docs/api/omdStepVisualizerInteractiveSteps.md +129 -0
- package/docs/api/omdStepVisualizerLayout.md +60 -0
- package/docs/api/omdStepVisualizerNodeUtils.md +140 -0
- package/docs/api/omdStepVisualizerTextBoxes.md +68 -0
- package/docs/api/omdToolbar.md +102 -0
- package/docs/api/omdTranscriptionService.md +76 -0
- package/docs/api/omdTreeDiff.md +134 -0
- package/docs/api/omdUnaryExpressionNode.md +174 -0
- package/docs/api/omdUtilities.md +70 -0
- package/docs/api/omdVariableNode.md +148 -0
- package/docs/api/selectTool.md +74 -0
- package/docs/api/simplificationEngine.md +98 -0
- package/docs/api/simplificationRules.md +77 -0
- package/docs/api/simplificationUtils.md +64 -0
- package/docs/api/transcribe.md +43 -0
- package/docs/api-reference.md +85 -0
- package/docs/index.html +454 -0
- package/docs/user-guide.md +9 -0
- package/index.js +67 -0
- package/omd/config/omdConfigManager.js +267 -0
- package/omd/core/index.js +150 -0
- package/omd/core/omdEquationStack.js +347 -0
- package/omd/core/omdUtilities.js +115 -0
- package/omd/display/omdDisplay.js +443 -0
- package/omd/display/omdToolbar.js +502 -0
- package/omd/nodes/omdBinaryExpressionNode.js +460 -0
- package/omd/nodes/omdConstantNode.js +142 -0
- package/omd/nodes/omdEquationNode.js +1223 -0
- package/omd/nodes/omdEquationSequenceNode.js +1273 -0
- package/omd/nodes/omdFunctionNode.js +352 -0
- package/omd/nodes/omdGroupNode.js +68 -0
- package/omd/nodes/omdLeafNode.js +77 -0
- package/omd/nodes/omdNode.js +557 -0
- package/omd/nodes/omdOperationDisplayNode.js +322 -0
- package/omd/nodes/omdOperatorNode.js +109 -0
- package/omd/nodes/omdParenthesisNode.js +293 -0
- package/omd/nodes/omdPowerNode.js +236 -0
- package/omd/nodes/omdRationalNode.js +295 -0
- package/omd/nodes/omdSqrtNode.js +308 -0
- package/omd/nodes/omdUnaryExpressionNode.js +178 -0
- package/omd/nodes/omdVariableNode.js +123 -0
- package/omd/simplification/omdSimplification.js +171 -0
- package/omd/simplification/omdSimplificationEngine.js +886 -0
- package/omd/simplification/package.json +6 -0
- package/omd/simplification/rules/binaryRules.js +1037 -0
- package/omd/simplification/rules/functionRules.js +111 -0
- package/omd/simplification/rules/index.js +48 -0
- package/omd/simplification/rules/parenthesisRules.js +19 -0
- package/omd/simplification/rules/powerRules.js +143 -0
- package/omd/simplification/rules/rationalRules.js +475 -0
- package/omd/simplification/rules/sqrtRules.js +48 -0
- package/omd/simplification/rules/unaryRules.js +37 -0
- package/omd/simplification/simplificationRules.js +32 -0
- package/omd/simplification/simplificationUtils.js +1056 -0
- package/omd/step-visualizer/omdStepVisualizer.js +597 -0
- package/omd/step-visualizer/omdStepVisualizerHighlighting.js +206 -0
- package/omd/step-visualizer/omdStepVisualizerLayout.js +245 -0
- package/omd/step-visualizer/omdStepVisualizerTextBoxes.js +163 -0
- package/omd/utils/omdNodeOverlay.js +638 -0
- package/omd/utils/omdPopup.js +1084 -0
- package/omd/utils/omdStepVisualizerInteractiveSteps.js +491 -0
- package/omd/utils/omdStepVisualizerNodeUtils.js +268 -0
- package/omd/utils/omdTranscriptionService.js +125 -0
- package/omd/utils/omdTreeDiff.js +734 -0
- package/package.json +46 -0
- package/src/index.js +62 -0
- package/src/json-schemas.md +109 -0
- package/src/omd-json-samples.js +115 -0
- package/src/omd.js +109 -0
- package/src/omdApp.js +391 -0
- package/src/omdAppCanvas.js +336 -0
- package/src/omdBalanceHanger.js +172 -0
- package/src/omdColor.js +13 -0
- package/src/omdCoordinatePlane.js +467 -0
- package/src/omdEquation.js +125 -0
- package/src/omdExpression.js +104 -0
- package/src/omdFunction.js +113 -0
- package/src/omdMetaExpression.js +287 -0
- package/src/omdNaturalExpression.js +564 -0
- package/src/omdNode.js +384 -0
- package/src/omdNumber.js +53 -0
- package/src/omdNumberLine.js +107 -0
- package/src/omdNumberTile.js +119 -0
- package/src/omdOperator.js +73 -0
- package/src/omdPowerExpression.js +92 -0
- package/src/omdProblem.js +55 -0
- package/src/omdRatioChart.js +232 -0
- package/src/omdRationalExpression.js +115 -0
- package/src/omdSampleData.js +215 -0
- package/src/omdShapes.js +476 -0
- package/src/omdSpinner.js +148 -0
- package/src/omdString.js +39 -0
- package/src/omdTable.js +369 -0
- package/src/omdTapeDiagram.js +245 -0
- package/src/omdTerm.js +92 -0
- package/src/omdTileEquation.js +349 -0
- package/src/omdVariable.js +51 -0
package/docs/api/main.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# main.js - OMD Testing Environment
|
|
2
|
+
|
|
3
|
+
This `main.js` file serves as the entry point for a testing environment designed to demonstrate the capabilities of the OMD (Open Math Display) library. It initializes the `omdDisplay` renderer, manages various UI elements, and provides functions for manipulating and visualizing mathematical expressions.
|
|
4
|
+
|
|
5
|
+
## Core Functionality
|
|
6
|
+
|
|
7
|
+
### Initialization
|
|
8
|
+
|
|
9
|
+
Upon DOM content loading, the script initializes an `omdDisplay` instance, attaching it to the `renderPanel` element. It also sets up references to various UI elements (input fields, buttons, checkboxes) used for interaction.
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
document.addEventListener('DOMContentLoaded', async () => {
|
|
13
|
+
const renderer = new omdDisplay(document.getElementById('renderPanel'), {
|
|
14
|
+
fontSize: 32,
|
|
15
|
+
centerContent: true,
|
|
16
|
+
topMargin: 40
|
|
17
|
+
});
|
|
18
|
+
// ... UI element setup ...
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Expression Rendering
|
|
23
|
+
|
|
24
|
+
The `renderExpression` function takes an expression from the `expressionInput` field, creates an `omdEquationStack` from it, and renders it using the `omdDisplay` instance.
|
|
25
|
+
|
|
26
|
+
### Simplification
|
|
27
|
+
|
|
28
|
+
The `simplify` function (and `simplifyAll`) applies simplification rules to the currently rendered equation sequence. It updates a history list with the simplification steps and messages.
|
|
29
|
+
|
|
30
|
+
### Equation Operations
|
|
31
|
+
|
|
32
|
+
Functions like `applyOperation` (for `+`, `-`, `*`, `/`) and `applyFunction` allow users to perform mathematical operations or apply functions to both sides of an equation. These operations modify the `omdEquationSequenceNode` and trigger re-rendering.
|
|
33
|
+
|
|
34
|
+
### Expression Evaluation
|
|
35
|
+
|
|
36
|
+
`evaluateExpression` takes an expression and optional variable assignments from the UI, then calls the library's evaluation method. The result is typically logged to the console.
|
|
37
|
+
|
|
38
|
+
### Step Filtering
|
|
39
|
+
|
|
40
|
+
`applyStepFilter` controls the visibility of simplification steps based on checkboxes (level 0, 1, 2), allowing users to focus on specific stages of the simplification process.
|
|
41
|
+
|
|
42
|
+
### Event Listeners
|
|
43
|
+
|
|
44
|
+
The script attaches event listeners to various UI buttons to trigger the corresponding functions (e.g., `renderButton` calls `renderExpression`, `simplifyButton` calls `simplify`).
|
|
45
|
+
|
|
46
|
+
### Node Overlays (`window.demoOverlays`)
|
|
47
|
+
|
|
48
|
+
A global `window.demoOverlays` object is exposed for demonstrating `omdNodeOverlay` functionality. It includes:
|
|
49
|
+
|
|
50
|
+
* **`hideLeft()`**: Hides the left side of the bottom-most equation in the sequence with an editable text overlay.
|
|
51
|
+
* **`hideRight()`**: Hides the right side of the bottom-most equation in the sequence with an editable text overlay.
|
|
52
|
+
* **`clearAll()`**: Recursively finds and destroys all `omdNodeOverlay` instances within the current equation sequence.
|
|
53
|
+
|
|
54
|
+
These functions showcase how parts of a mathematical expression can be interactively covered or revealed, potentially for educational or problem-solving purposes.
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
This `main.js` is intended to be used with an `index.html` file that provides the necessary UI elements (input fields, buttons, and a `renderPanel` div). Users can input mathematical expressions, apply operations, simplify, and observe the visual changes and step-by-step history.
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# omdBinaryExpressionNode
|
|
2
|
+
|
|
3
|
+
Represents binary operations (addition, subtraction, multiplication, division) in mathematical expressions.
|
|
4
|
+
|
|
5
|
+
## Class: `omdBinaryExpressionNode extends omdNode`
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import { omdBinaryExpressionNode } from './omd/nodes/omdBinaryExpressionNode.js';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Constructor
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
new omdBinaryExpressionNode(ast)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Parameters:**
|
|
18
|
+
- `ast` {Object} - The AST node containing:
|
|
19
|
+
- `args`: Array of at least 2 operand AST nodes
|
|
20
|
+
- `op`: Operator symbol
|
|
21
|
+
- `implicit`: Optional boolean for implicit multiplication
|
|
22
|
+
|
|
23
|
+
**Description:**
|
|
24
|
+
Creates a node representing a binary operation like `a + b`, `x * y`, etc.
|
|
25
|
+
|
|
26
|
+
### Properties
|
|
27
|
+
|
|
28
|
+
Inherits all properties from [omdNode](./omdNode.md), plus:
|
|
29
|
+
|
|
30
|
+
#### `left`
|
|
31
|
+
- **Type:** [omdNode](./omdNode.md)
|
|
32
|
+
- **Description:** The left operand node
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
#### `operation`
|
|
36
|
+
- **Type:** string
|
|
37
|
+
- **Description:** The function name for the operation (e.g., 'add', 'multiply', 'subtract', 'divide').
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
#### `op`
|
|
41
|
+
- **Type:** [omdOperatorNode](./omdOperatorNode.md) | null
|
|
42
|
+
- **Description:** The operator node (null for implicit multiplication). For multiplication, this may be removed and replaced with implicit multiplication based on configuration.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#### `isImplicit`
|
|
46
|
+
- **Type:** boolean
|
|
47
|
+
- **Description:** Whether multiplication is implicit (e.g., `2x`). Determined by AST or configuration.
|
|
48
|
+
|
|
49
|
+
#### `right`
|
|
50
|
+
- **Type:** [omdNode](./omdNode.md)
|
|
51
|
+
- **Description:** The right operand node
|
|
52
|
+
|
|
53
|
+
### Methods
|
|
54
|
+
|
|
55
|
+
Inherits all methods from [omdNode](./omdNode.md), plus:
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
#### `parseOperation()`
|
|
59
|
+
Internal method to extract the function name for the operation from the AST.
|
|
60
|
+
- **Returns:** string - Function name (e.g., 'add', 'multiply', etc.)
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
#### `createExpressionNode(ast)`
|
|
66
|
+
Internal method to create operand nodes.
|
|
67
|
+
- `ast` {Object} - The AST for the operand
|
|
68
|
+
- **Returns:** omdNode
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
#### `createOperatorNode(ast)`
|
|
74
|
+
Internal method to create operator node.
|
|
75
|
+
- `ast` {Object} - The AST with operator info
|
|
76
|
+
- **Returns:** omdOperatorNode
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
#### `computeDimensions()`
|
|
81
|
+
Calculates dimensions of expression.
|
|
82
|
+
- Computes dimensions of all parts
|
|
83
|
+
- Adds spacing between operator and operands
|
|
84
|
+
- Sets total width and height
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
#### `updateLayout()`
|
|
89
|
+
Updates positions of all elements.
|
|
90
|
+
- Aligns operands and operator on baseline
|
|
91
|
+
- Handles spacing for implicit multiplication
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
#### `getAlignmentBaseline()`
|
|
97
|
+
Gets vertical alignment point.
|
|
98
|
+
- **Returns:** number - Y-coordinate based on:
|
|
99
|
+
- Operator baseline if explicit
|
|
100
|
+
- Max child baseline if implicit
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
#### `clone()`
|
|
106
|
+
Creates a deep clone of the expression.
|
|
107
|
+
- **Returns:** omdBinaryExpressionNode - A new instance with:
|
|
108
|
+
- Cloned operands and operator
|
|
109
|
+
- Rebuilt argument list
|
|
110
|
+
- Copied AST data and operation
|
|
111
|
+
- Original node's ID added to provenance array
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
#### `getSpacing()`
|
|
117
|
+
Gets horizontal spacing between elements.
|
|
118
|
+
- **Returns:** number - 0 for implicit multiplication, otherwise scales with font size.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
#### `_shouldUseImplicitMultiplication(left, right)` (internal)
|
|
125
|
+
Internal method to check if multiplication should be implicit.
|
|
126
|
+
- Based on configuration and operand types
|
|
127
|
+
- **Returns:** boolean
|
|
128
|
+
> Note: This method is intended for internal use and may change without notice.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
#### `_shouldReorderMultiplication(left, right)` (internal)
|
|
134
|
+
Internal method to check if operands should be reordered for coefficient multiplication (e.g., x*2 → 2*x).
|
|
135
|
+
- **Returns:** boolean
|
|
136
|
+
> Note: This method is intended for internal use and may change without notice.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
#### `toMathJSNode()`
|
|
142
|
+
Converts to math.js AST format.
|
|
143
|
+
- **Returns:** Object - A math.js-compatible AST node with:
|
|
144
|
+
- `type`: "OperatorNode"
|
|
145
|
+
- `op`: Operator symbol
|
|
146
|
+
- `fn`: Function name
|
|
147
|
+
- `args`: Operand ASTs
|
|
148
|
+
- `implicit`: Boolean flag
|
|
149
|
+
- `id`: Node ID
|
|
150
|
+
- `provenance`: Provenance array
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
#### `toString()`
|
|
156
|
+
Convert to string representation.
|
|
157
|
+
- **Returns:** string - Format depends on operation. Handles implicit multiplication and adds parentheses as needed for precedence.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
#### `evaluate(variables)`
|
|
164
|
+
Evaluate the expression.
|
|
165
|
+
- `variables` {Object} - Variable name to value mapping
|
|
166
|
+
- **Returns:** number - The evaluated result
|
|
167
|
+
- **Throws:** Error if division by zero is encountered or if the operation is unsupported.
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
#### `needsParentheses()`
|
|
171
|
+
Determines if parentheses are needed based on parent operator precedence.
|
|
172
|
+
- **Returns:** boolean
|
|
173
|
+
|
|
174
|
+
### Examples
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
// Create from AST
|
|
178
|
+
const node = new omdBinaryExpressionNode({
|
|
179
|
+
type: 'OperatorNode',
|
|
180
|
+
op: '+',
|
|
181
|
+
fn: 'add',
|
|
182
|
+
args: [
|
|
183
|
+
{ type: 'SymbolNode', name: 'x' },
|
|
184
|
+
{ type: 'ConstantNode', value: 2 }
|
|
185
|
+
]
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Implicit multiplication
|
|
189
|
+
const implicitMult = new omdBinaryExpressionNode({
|
|
190
|
+
type: 'OperatorNode',
|
|
191
|
+
op: '*',
|
|
192
|
+
fn: 'multiply',
|
|
193
|
+
args: [
|
|
194
|
+
{ type: 'ConstantNode', value: 2 },
|
|
195
|
+
{ type: 'SymbolNode', name: 'x' }
|
|
196
|
+
],
|
|
197
|
+
implicit: true
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Division by zero (throws error)
|
|
201
|
+
try {
|
|
202
|
+
const divByZero = new omdBinaryExpressionNode({
|
|
203
|
+
type: 'OperatorNode',
|
|
204
|
+
op: '/',
|
|
205
|
+
fn: 'divide',
|
|
206
|
+
args: [
|
|
207
|
+
{ type: 'ConstantNode', value: 5 },
|
|
208
|
+
{ type: 'ConstantNode', value: 0 }
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
divByZero.evaluate();
|
|
212
|
+
} catch (e) {
|
|
213
|
+
console.error('Error:', e.message); // Error: Division by zero.
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Render with proper spacing
|
|
217
|
+
node.setFontSize(24);
|
|
218
|
+
node.computeDimensions();
|
|
219
|
+
node.updateLayout();
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### See Also
|
|
223
|
+
|
|
224
|
+
- [omdNode](./omdNode.md) - Parent class
|
|
225
|
+
- [omdOperatorNode](./omdOperatorNode.md) - For operators
|
|
226
|
+
- [omdConstantNode](./omdConstantNode.md) - For numeric operands
|
|
227
|
+
- [omdVariableNode](./omdVariableNode.md) - For variable operands
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# omdCanvas
|
|
2
|
+
|
|
3
|
+
The `omdCanvas` class is the core component for creating and managing a drawing canvas. It provides the primary interface for interacting with the canvas, including drawing, selecting, and managing strokes, as well as handling events and integrating with various tools and features.
|
|
4
|
+
|
|
5
|
+
## Class Definition
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
export class omdCanvas {
|
|
9
|
+
// ...
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Constructor
|
|
14
|
+
|
|
15
|
+
### `new omdCanvas(container, [options])`
|
|
16
|
+
|
|
17
|
+
Creates a new `omdCanvas` instance.
|
|
18
|
+
|
|
19
|
+
* **container** (`HTMLElement` or `string`): The HTML element or a CSS selector string for the container where the canvas will be rendered.
|
|
20
|
+
* **[options]** (`object`, optional): Configuration options for the canvas. These options are passed to `CanvasConfig`.
|
|
21
|
+
|
|
22
|
+
## Properties
|
|
23
|
+
|
|
24
|
+
* **container** (`HTMLElement`): The HTML container element for the canvas.
|
|
25
|
+
* **config** (`CanvasConfig`): The configuration object for the canvas.
|
|
26
|
+
* **svg** (`SVGElement`): The main SVG element representing the canvas.
|
|
27
|
+
* **backgroundLayer** (`SVGGElement`): The SVG group element for background elements (e.g., grid).
|
|
28
|
+
* **drawingLayer** (`SVGGElement`): The SVG group element for drawing strokes.
|
|
29
|
+
* **uiLayer** (`SVGGElement`): The SVG group element for UI elements (e.g., selection boxes).
|
|
30
|
+
* **focusFrameLayer** (`SVGGElement`): The SVG group element for focus frames.
|
|
31
|
+
* **strokes** (`Map<string, Stroke>`): A map of all strokes on the canvas, keyed by their ID.
|
|
32
|
+
* **selectedStrokes** (`Set<string>`): A set of IDs of currently selected strokes.
|
|
33
|
+
* **toolManager** (`ToolManager`): Manages the active drawing tools.
|
|
34
|
+
* **eventManager** (`EventManager`): Manages all user input events.
|
|
35
|
+
* **cursor** (`Cursor`): Manages the custom canvas cursor.
|
|
36
|
+
* **toolbar** (`Toolbar`): The canvas toolbar (if enabled).
|
|
37
|
+
* **focusFrameManager** (`FocusFrameManager`): Manages focus frames (if enabled).
|
|
38
|
+
|
|
39
|
+
## Public Methods
|
|
40
|
+
|
|
41
|
+
### `addStroke(stroke)`
|
|
42
|
+
|
|
43
|
+
Adds a stroke to the canvas.
|
|
44
|
+
|
|
45
|
+
* **stroke** (`Stroke`): The stroke object to add.
|
|
46
|
+
* **Returns**: `string` - The ID of the added stroke.
|
|
47
|
+
|
|
48
|
+
### `removeStroke(strokeId)`
|
|
49
|
+
|
|
50
|
+
Removes a stroke from the canvas.
|
|
51
|
+
|
|
52
|
+
* **strokeId** (`string`): The ID of the stroke to remove.
|
|
53
|
+
* **Returns**: `boolean` - `true` if the stroke was removed, `false` otherwise.
|
|
54
|
+
|
|
55
|
+
### `clear()`
|
|
56
|
+
|
|
57
|
+
Clears all strokes from the canvas.
|
|
58
|
+
|
|
59
|
+
### `selectStrokes(strokeIds)`
|
|
60
|
+
|
|
61
|
+
Selects a set of strokes by their IDs.
|
|
62
|
+
|
|
63
|
+
* **strokeIds** (`Array<string>`): An array of stroke IDs to select.
|
|
64
|
+
|
|
65
|
+
### `clientToSVG(clientX, clientY)`
|
|
66
|
+
|
|
67
|
+
Converts client (screen) coordinates to SVG (canvas) coordinates.
|
|
68
|
+
|
|
69
|
+
* **clientX** (`number`): The client X coordinate.
|
|
70
|
+
* **clientY** (`number`): The client Y coordinate.
|
|
71
|
+
* **Returns**: `object` - An object with `x` and `y` properties representing the SVG coordinates.
|
|
72
|
+
|
|
73
|
+
### `exportSVG()`
|
|
74
|
+
|
|
75
|
+
Exports the canvas content as an SVG string. UI elements like selection boxes and focus frames are excluded from the export.
|
|
76
|
+
|
|
77
|
+
* **Returns**: `string` - The SVG content of the canvas.
|
|
78
|
+
|
|
79
|
+
### `exportImage([format], [quality])`
|
|
80
|
+
|
|
81
|
+
Exports the canvas content as an image (PNG, JPEG, or WebP).
|
|
82
|
+
|
|
83
|
+
* **[format]** (`string`, optional): The image format (`'png'`, `'jpeg'`, `'webp'`). Defaults to `'png'`.
|
|
84
|
+
* **[quality]** (`number`, optional): The image quality (0-1) for JPEG/WebP. Defaults to `1`.
|
|
85
|
+
* **Returns**: `Promise<Blob>` - A promise that resolves with the image data as a `Blob`.
|
|
86
|
+
|
|
87
|
+
### `resize(width, height)`
|
|
88
|
+
|
|
89
|
+
Resizes the canvas to the specified dimensions.
|
|
90
|
+
|
|
91
|
+
* **width** (`number`): The new width of the canvas.
|
|
92
|
+
* **height** (`number`): The new height of the canvas.
|
|
93
|
+
|
|
94
|
+
### `toggleGrid()`
|
|
95
|
+
|
|
96
|
+
Toggles the visibility of the background grid.
|
|
97
|
+
|
|
98
|
+
### `on(event, callback)`
|
|
99
|
+
|
|
100
|
+
Registers an event listener for a custom canvas event.
|
|
101
|
+
|
|
102
|
+
* **event** (`string`): The name of the event to listen for.
|
|
103
|
+
* **callback** (`Function`): The callback function to execute when the event is emitted.
|
|
104
|
+
|
|
105
|
+
### `off(event, callback)`
|
|
106
|
+
|
|
107
|
+
Removes an event listener.
|
|
108
|
+
|
|
109
|
+
* **event** (`string`): The name of the event.
|
|
110
|
+
* **callback** (`Function`): The callback function to remove.
|
|
111
|
+
|
|
112
|
+
### `emit(event, [data])`
|
|
113
|
+
|
|
114
|
+
Emits a custom canvas event.
|
|
115
|
+
|
|
116
|
+
* **event** (`string`): The name of the event to emit.
|
|
117
|
+
* **[data]** (`object`, optional): Optional data to pass with the event.
|
|
118
|
+
|
|
119
|
+
### `getInfo()`
|
|
120
|
+
|
|
121
|
+
Gets information about the current state of the canvas.
|
|
122
|
+
|
|
123
|
+
* **Returns**: `object` - An object containing canvas dimensions, stroke counts, active tool, and other status information.
|
|
124
|
+
|
|
125
|
+
### `destroy()`
|
|
126
|
+
|
|
127
|
+
Destroys the canvas instance, removes all DOM elements, and cleans up event listeners and managers.
|
|
128
|
+
|
|
129
|
+
## Events
|
|
130
|
+
|
|
131
|
+
The `omdCanvas` emits the following custom events:
|
|
132
|
+
|
|
133
|
+
* `strokeAdded`: Fired when a new stroke is added to the canvas.
|
|
134
|
+
* `strokeRemoved`: Fired when a stroke is removed from the canvas.
|
|
135
|
+
* `cleared`: Fired when all strokes are cleared from the canvas.
|
|
136
|
+
* `selectionChanged`: Fired when the selection of strokes changes.
|
|
137
|
+
* `resized`: Fired when the canvas is resized.
|
|
138
|
+
* `pointerDown`, `pointerMove`, `pointerUp`, `pointerCancel`, `pointerEnter`, `pointerLeave`: Pointer events, normalized to canvas coordinates.
|
|
139
|
+
* `keyDown`, `keyUp`: Keyboard events.
|
|
140
|
+
* `wheel`: Wheel events.
|
|
141
|
+
* `focusFrameCreated`, `focusFrameRemoved`, `focusFrameActivated`, `focusFramesCleared`: Events related to focus frame management.
|
|
142
|
+
* `destroyed`: Fired when the canvas instance is destroyed.
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# omdConfigManager
|
|
2
|
+
|
|
3
|
+
A module for managing the configuration of the OMD library. It handles loading settings from a JSON file, providing default values, and allowing runtime modifications.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The configuration is managed as a single JSON object. The system can be initialized with a path to a `omdConfig.json` file, or it will fall back to a default configuration. The manager supports both asynchronous and synchronous access to configuration values.
|
|
8
|
+
|
|
9
|
+
### Default Configuration
|
|
10
|
+
|
|
11
|
+
If no `omdConfig.json` is found, the following default structure is used:
|
|
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
|
+
## Core Functions
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
import {
|
|
50
|
+
initializeConfig,
|
|
51
|
+
getConfig,
|
|
52
|
+
getConfigSync,
|
|
53
|
+
setConfig,
|
|
54
|
+
getConfigValue,
|
|
55
|
+
setConfigValue,
|
|
56
|
+
getDefaultConfig,
|
|
57
|
+
isEnabled,
|
|
58
|
+
useImplicitMultiplication,
|
|
59
|
+
getMultiplicationSymbol,
|
|
60
|
+
updateConfig,
|
|
61
|
+
resetConfig,
|
|
62
|
+
reloadConfig,
|
|
63
|
+
getConfigAsync,
|
|
64
|
+
getDotRadius,
|
|
65
|
+
getFontWeight
|
|
66
|
+
} from 'omd-library';
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
#### `initializeConfig(configSource)`
|
|
71
|
+
Loads the configuration. This should be called once when your application starts.
|
|
72
|
+
- **Parameters:**
|
|
73
|
+
- `configSource` {string | Object} (optional) - A path to a JSON configuration file or a configuration object to use directly.
|
|
74
|
+
- **Returns:** `Promise<void>`
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
// Load from default path ('./omd/config/omdConfig.json')
|
|
78
|
+
await initializeConfig();
|
|
79
|
+
|
|
80
|
+
// Or load from a specific path
|
|
81
|
+
await initializeConfig('./my-custom-config.json');
|
|
82
|
+
|
|
83
|
+
// Or provide a config object directly
|
|
84
|
+
await initializeConfig({ multiplication: { symbol: '*' } });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
#### `getConfig()`
|
|
91
|
+
Asynchronously gets the entire configuration object. Loads it with defaults if it hasn't been loaded yet.
|
|
92
|
+
- **Returns:** `Promise<Object>` - A promise that resolves to the configuration object.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
#### `getConfigSync()`
|
|
98
|
+
Synchronously gets the entire configuration object. **Note:** If the configuration has not been loaded yet, this will return the default configuration.
|
|
99
|
+
- **Returns:** `Object` - The configuration object.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
#### `setConfig(config)`
|
|
105
|
+
Sets the entire configuration, merging it with the default values.
|
|
106
|
+
- **Parameters:**
|
|
107
|
+
- `config` {Object} - The configuration object to set.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
#### `getConfigValue(path)`
|
|
113
|
+
Gets a specific configuration value using a dot-separated path.
|
|
114
|
+
- **Parameters:**
|
|
115
|
+
- `path` {string} - The path to the value (e.g., `'multiplication.symbol'`).
|
|
116
|
+
- **Returns:** `any` - The value at the specified path.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
#### `setConfigValue(path, value)`
|
|
122
|
+
Sets a specific configuration value using a dot-separated path.
|
|
123
|
+
- **Parameters:**
|
|
124
|
+
- `path` {string} - The path to the value.
|
|
125
|
+
- `value` {any} - The new value to set.
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
## Utility Functions
|
|
129
|
+
|
|
130
|
+
#### `getMultiplicationSymbol()`
|
|
131
|
+
- **Returns:** `string` - The configured symbol for multiplication.
|
|
132
|
+
|
|
133
|
+
#### `useImplicitMultiplication(combination)`
|
|
134
|
+
- **Parameters:**
|
|
135
|
+
- `combination` {string} (optional) - The context of the multiplication (e.g., `'constantVariable'`).
|
|
136
|
+
- **Returns:** `boolean` - Whether to use implicit multiplication in that context or globally if no combination is provided.
|
|
137
|
+
|
|
138
|
+
#### `getDotRadius(level)`
|
|
139
|
+
- **Parameters:**
|
|
140
|
+
- `level` {number} - The step level (0, 1, or 2).
|
|
141
|
+
- **Returns:** `number` - The configured dot radius for that level in the step visualizer.
|
|
142
|
+
|
|
143
|
+
#### `getFontWeight(level)`
|
|
144
|
+
- **Parameters:**
|
|
145
|
+
- `level` {number} - The step level (0, 1, or 2).
|
|
146
|
+
- **Returns:** `number` - The configured font weight for that level.
|
|
147
|
+
#### `getDefaultConfig()`
|
|
148
|
+
- **Returns:** `Object` - The default configuration object.
|
|
149
|
+
|
|
150
|
+
#### `isEnabled(category, setting)`
|
|
151
|
+
- **Parameters:**
|
|
152
|
+
- `category` {string} - The configuration category (e.g., 'multiplication').
|
|
153
|
+
- `setting` {string} - The specific setting to check.
|
|
154
|
+
- **Returns:** `boolean` - Whether the setting is enabled.
|
|
155
|
+
|
|
156
|
+
#### `updateConfig(category, setting, value)`
|
|
157
|
+
- **Parameters:**
|
|
158
|
+
- `category` {string} - The configuration category.
|
|
159
|
+
- `setting` {string} - The setting to update.
|
|
160
|
+
- `value` {any} - The new value.
|
|
161
|
+
|
|
162
|
+
#### `resetConfig()`
|
|
163
|
+
- **Throws:** Always throws an error. (Direct file editing is required.)
|
|
164
|
+
|
|
165
|
+
#### `reloadConfig()`
|
|
166
|
+
- **Returns:** `Promise<Object>` - Promise that resolves to the reloaded configuration.
|
|
167
|
+
|
|
168
|
+
#### `getConfigAsync()`
|
|
169
|
+
- **Returns:** `Promise<Object>` - Promise that resolves to the configuration object.
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
## Example Usage
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
import { initializeConfig, getConfigValue, setConfigValue, getMultiplicationSymbol } from 'omd-library';
|
|
176
|
+
|
|
177
|
+
// Initialize at the start of your application
|
|
178
|
+
(async () => {
|
|
179
|
+
await initializeConfig();
|
|
180
|
+
|
|
181
|
+
// Get a specific value
|
|
182
|
+
const multSymbol = getConfigValue('multiplication.symbol');
|
|
183
|
+
console.log(`Multiplication symbol is: ${multSymbol}`); // Output: ·
|
|
184
|
+
|
|
185
|
+
// Or use a dedicated utility function
|
|
186
|
+
console.log(`Multiplication symbol is: ${getMultiplicationSymbol()}`); // Output: ·
|
|
187
|
+
|
|
188
|
+
// Change a value at runtime
|
|
189
|
+
setConfigValue('multiplication.symbol', '*');
|
|
190
|
+
console.log(`New multiplication symbol is: ${getMultiplicationSymbol()}`); // Output: *
|
|
191
|
+
})();
|
|
192
|
+
```
|