UNPKG

@teachinglab/omd

Version:

omd

192 lines (134 loc) 9.99 kB
# omdPopup The `omdPopup` class handles the creation and management of interactive popups for node overlays. These popups can be used for text input or for drawing with a pen tool, often integrated with a transcription service for converting handwriting to text. ## Class Definition ```javascript export class omdPopup ``` ## Constructor ### `new omdPopup(targetNode, parentElement, [options])` Creates a new `omdPopup` instance. - **`targetNode`** (`omdNode`): The OMD node to which the popup is logically attached. Its dimensions can influence the popup's size. - **`parentElement`** (`jsvgElement`): The parent `jsvgElement` (or `jsvgGroup`) to which the popup's SVG elements will be added. - **`options`** (`object`, optional): Configuration options for the popup: - `editable` (`boolean`): Whether the popup's input area is editable. Default: `true`. - `animationDuration` (`number`): The duration of the show/hide animation in milliseconds. Default: `200`. ## Public Properties - **`popup`** (`jsvgLayoutGroup`): The main SVG group element that contains all popup components. - **`popupBackground`** (`jsvgRect`): The background rectangle of the popup. - **`popupTextInput`** (`jsvgTextInput`): The text input field element (active in `'text'` mode). - **`penCanvas`** (`omdCanvas`): The drawing canvas instance (active in `'pen'` mode). - **`penCanvasCleanup`** (`function`): A cleanup function for the `penCanvas`. - **`currentMode`** (`string`): The current mode of the popup (`'text'` or `'pen'`). - **`popupAnimationId`** (`number`): The ID of the current animation frame request. - **`penButton`** (`jsvgButton`): The button to switch to `'pen'` mode. - **`textButton`** (`jsvgButton`): The button to switch to `'text'` mode. - **`clearButton`** (`jsvgButton`): The button to clear the current input. - **`submitButton`** (`jsvgButton`): The button to submit the input. - **`onValidateCallback`** (`function`): The callback function to execute when the user submits input. - **`onClearCallback`** (`function`): The callback function to execute when the user clears input. - **`popupWidth`** (`number`): The fixed width of the popup. - **`buttonSize`** (`number`): The size (width and height) of the control buttons. - **`margin`** (`number`): General margin/padding value used for layout. - **`buttonSpacing`** (`number`): Spacing between buttons. - **`canvasMinWidth`** (`number`): Minimum width for the pen canvas. - **`canvasMinHeight`** (`number`): Minimum height for the pen canvas. - **`popupHeightMultiplier`** (`number`): Multiplier for the target node's height to determine popup height. - **`targetNodeDefaultHeight`** (`number`): Default height for the target node if not available. - **`canvasTopOffset`** (`number`): Vertical offset for the pen canvas within the popup. - **`canvasLeftOffset`** (`number`): Horizontal offset for the pen canvas within the popup. - **`transcribedText`** (`string` | `null`): Stores the text result from pen-to-text transcription. ## Public Methods ### `show(x, y)` Creates and displays the popup at the specified coordinates with an animation. - **`x`** (`number`): The x-coordinate for the popup's top-left corner. - **`y`** (`number`): The y-coordinate for the popup's top-left corner. - **Returns**: `Promise` - A promise that resolves when the show animation is complete. ### `hide()` Hides the popup with an animation and performs cleanup. - **Returns**: `Promise` - A promise that resolves when the hide animation is complete. ### `toggle(x, y)` Toggles the visibility of the popup. If visible, it hides; otherwise, it shows. - **`x`** (`number`): The x-coordinate for showing the popup. - **`y`** (`number`): The y-coordinate for showing the popup. - **Returns**: `Promise` - A promise that resolves when the animation is complete. ### `setValidationCallback(callback)` Sets the callback function to be invoked when the user submits their input (e.g., by clicking the submit button). - **`callback`** (`Function`): The function to call for validation. ### `setClearCallback(callback)` Sets the callback function to be invoked when the user clears the input (e.g., by clicking the clear button). - **`callback`** (`Function`): The function to call when clearing. ### `getValue()` Retrieves the current input value from the popup. If in pen mode, it returns the last transcribed text and then clears it. - **Returns**: `string` - The current input value. ### `setValue(value)` Sets the input value of the popup's text field. - **`value`** (`string`): The value to set. ### `switchToMode(mode)` Switches the popup between `'text'` and `'pen'` input modes. This updates the visible input area and button states. - **`mode`** (`string`): The mode to switch to. Can be `'text'` or `'pen'`. ### `flashValidation(isValid)` Flashes the popup background (and associated elements) to visually indicate whether the user's input was valid or invalid. - **`isValid`** (`boolean`): `true` for a success flash (greenish), `false` for an error flash (reddish). ### `areExpressionsEquivalent(expr1, expr2)` Compares two mathematical expressions for equivalence. It uses `math.js` to simplify and evaluate expressions with random variable assignments to robustly check for mathematical equality. - **`expr1`** (`string`): The first expression string. - **`expr2`** (`string`): The second expression string. - **Returns**: `boolean` - `true` if the expressions are mathematically equivalent, `false` otherwise. ### `destroy()` Completely destroys the popup, removing all associated DOM elements, event listeners, and internal references. This method calls `hide()` internally to ensure a clean animated exit. ### `repositionCanvasRelativeToPopup()` Manually triggers an update to the pen canvas's position to ensure it remains correctly aligned with the popup, especially after layout changes. ## Internal Methods - **`_createPopup()`**: Creates the main `jsvgLayoutGroup` for the popup, its background, and initializes buttons and input areas. - **`_createButtons(popupWidth, popupHeight, buttonSize, margin, buttonSpacing)`**: Creates and positions the clear, submit, pen, and text mode switch buttons. - **`_createTextInput(popupWidth, popupHeight, margin)`**: Creates and styles the `jsvgTextInput` element for text input mode. - **`_createPenCanvas()`**: Initializes the `omdCanvas` instance for drawing in pen mode. It handles embedding the HTML canvas within an SVG `foreignObject` if necessary. - **`_showPenMode()`**: Activates the pen drawing mode, hiding the text input and showing/creating the pen canvas. - **`_showTextMode()`**: Activates the text input mode, hiding the pen canvas and showing the text input. - **`_addCanvasToParent(element)`**: Adds the pen canvas's DOM element (or its `foreignObject` wrapper) to the appropriate parent, handling positioning. - **`_updateButtonStates()`**: Updates the visual appearance of the mode switch buttons to reflect the `currentMode`. - **`_positionPopup(x, y)`**: Sets the absolute position of the main popup SVG group. - **`_animateOpacity(fromOpacity, toOpacity, duration)`**: Handles the smooth opacity animation for showing and hiding the popup. - **`_flashAllElements(flashColor)`**: Applies a temporary background color flash to all relevant popup elements (background, canvas) to indicate validation feedback. - **`_downloadCanvasAsBitmap()`**: Converts the content of the pen canvas to a PNG bitmap and initiates the transcription process. - **`_transcribeCanvas(imageBlob)`**: Sends the pen canvas image data to the `omdTranscriptionService` for handwriting recognition. - **`_setSubmitButtonLoading(isLoading)`**: Controls the loading state of the submit button, including a blinking animation. - **`_startBlinkingAnimation()`**: Initiates the blinking animation for the submit button. - **`_stopBlinkingAnimation()`**: Stops the blinking animation for the submit button. - **`_setupResizeObserver()`**: Sets up a `ResizeObserver` to monitor changes in the popup's dimensions and reposition the pen canvas accordingly. - **`_updateCanvasPosition()`**: Recalculates and applies the correct position and size for the pen canvas within the popup's content area. - **`_cleanup()`**: Performs comprehensive cleanup of all popup-related DOM elements, event listeners, and internal references. ## Modes The `omdPopup` has two primary interaction modes: - **Text Mode**: This is the default mode, providing a standard text input field (`jsvgTextInput`). - **Pen Mode**: This mode allows the user to draw directly inside the popup using an embedded `omdCanvas`. The drawing can then be transcribed to text using an external OCR service (via `omdTranscriptionService`). Users can switch between modes using the `'T'` (Text) and `'P'` (Pen) buttons on the popup. ## Example Usage ```javascript import { omdPopup } from '@teachinglab/omd'; import { omdNode } from '@teachinglab/omd'; // Assuming you have an omdNode instance import { jsvgGroup } from '@teachinglab/jsvg'; // Assuming a parent jsvgElement // Create a dummy node and parent element for demonstration const targetNode = new omdNode({}); const parentElement = new jsvgGroup(); // Create a popup for a node const popup = new omdPopup(targetNode, parentElement); // Set a validation callback popup.setValidationCallback(() => { const value = popup.getValue(); if (popup.areExpressionsEquivalent(value, 'correct')) { popup.flashValidation(true); popup.hide(); } else { popup.flashValidation(false); } }); // Set a clear callback popup.setClearCallback(() => { console.log('Popup input cleared!'); }); // Show the popup at a specific position // popup.show(100, 100); // To add the parentElement to the DOM for actual display: // document.body.appendChild(parentElement.svgObject); ```