aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/InkingStroke.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-12-29 17:01:40 -0500
committerbobzel <zzzman@gmail.com>2023-12-29 17:01:40 -0500
commit9b9f54a43793ca6ffb26c56f962d11ba8325abd2 (patch)
tree026063b95da59556eb0a416b5f6fafd2ebccd737 /src/client/views/InkingStroke.tsx
parenta567eb1b6469db202d41d4d54f2c96137e49ea9c (diff)
cleaned up imports, mobx observable initialization and some compile errors.
Diffstat (limited to 'src/client/views/InkingStroke.tsx')
-rw-r--r--src/client/views/InkingStroke.tsx76
1 files changed, 27 insertions, 49 deletions
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 9c96b4563..95c677845 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -20,9 +20,9 @@
Most of the operations that can be performed on an InkStroke (eg delete a point, rotate, stretch) are implemented in the InkStrokeProperties helper class
*/
-import * as React from 'react';
import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
+import * as React from 'react';
import { Doc } from '../../fields/Doc';
import { InkData, InkField } from '../../fields/InkField';
import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types';
@@ -32,7 +32,6 @@ import { CognitiveServices } from '../cognitive_services/CognitiveServices';
import { Docs } from '../documents/Documents';
import { InteractionUtils } from '../util/InteractionUtils';
import { SnappingManager } from '../util/SnappingManager';
-import { Transform } from '../util/Transform';
import { UndoManager } from '../util/UndoManager';
import { ContextMenu } from './ContextMenu';
import { ViewBoxBaseComponent } from './DocComponent';
@@ -59,14 +58,14 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
private _handledClick = false; // flag denoting whether ink stroke has handled a psuedo-click onPointerUp so that the real onClick event can be stopPropagated
private _disposers: { [key: string]: IReactionDisposer } = {};
- @observable _nearestSeg?: number; // nearest Bezier segment along the ink stroke to the cursor (used for displaying the Add Point highlight)
- @observable _nearestT?: number; // nearest t value within the nearest Bezier segment "
+ @observable _nearestSeg?: number = undefined; // nearest Bezier segment along the ink stroke to the cursor (used for displaying the Add Point highlight)
+ @observable _nearestT?: number = undefined; // nearest t value within the nearest Bezier segment "
@observable _nearestScrPt?: { X: number; Y: number }; // nearst screen point on the ink stroke ""
componentDidMount() {
- this.props.setContentView?.(this);
+ this._props.setContentView?.(this);
this._disposers.selfDisper = reaction(
- () => this.props.isSelected(), // react to stroke being deselected by turning off ink handles
+ () => this._props.isSelected(), // react to stroke being deselected by turning off ink handles
selected => !selected && (InkStrokeProperties.Instance._controlButton = false)
);
}
@@ -76,7 +75,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
// transform is the inherited screentolocal xf plus any scaling that was done to make the stroke
// fit within its panel (e.g., for content fitting views like Lightbox or multicolumn, etc)
- screenToLocal = () => this.props.ScreenToLocalTransform().scale(this.props.NativeDimScaling?.() || 1);
+ screenToLocal = () => this._props.ScreenToLocalTransform().scale(this._props.NativeDimScaling?.() || 1);
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
const subAnchor = this._subContentView?.getAnchor?.(addAsAnnotation);
@@ -101,27 +100,6 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
};
/**
- * @returns the center of the ink stroke in the ink document's coordinate space (not screen space, and not the ink data coordinate space);
- * DocumentDecorations calls getBounds() on DocumentViews which call getCenter() if defined - in the case of ink it needs to be defined since
- * the center of the ink stroke changes as the stroke is rotated.
- */
- getCenter = (xf: Transform) => {
- const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData();
- const angle = -NumCast(this.layoutDoc.rotation);
- const newPoints = inkData.map(pt => {
- const newX = Math.cos(angle) * pt.X - (Math.sin(angle) * pt.Y * inkScaleY) / inkScaleX;
- const newY = (Math.sin(angle) * pt.X * inkScaleX) / inkScaleY + Math.cos(angle) * pt.Y;
- return { X: newX, Y: newY };
- });
- const crx = (Math.max(...newPoints.map(np => np.X)) + Math.min(...newPoints.map(np => np.X))) / 2;
- const cry = (Math.max(...newPoints.map(np => np.Y)) + Math.min(...newPoints.map(np => np.Y))) / 2;
- const cx = Math.cos(-angle) * crx - (Math.sin(-angle) * cry * inkScaleY) / inkScaleX;
- const cy = (Math.sin(-angle) * crx * inkScaleX) / inkScaleY + Math.cos(-angle) * cry;
- const tc = xf.transformPoint((cx - inkLeft - inkStrokeWidth / 2) * inkScaleX + inkStrokeWidth / 2, (cy - inkTop - inkStrokeWidth / 2) * inkScaleY + inkStrokeWidth / 2);
- return { X: tc[0], Y: tc[1] };
- };
-
- /**
* analyzes the ink stroke and saves the analysis of the stroke to the 'inkAnalysis' field,
* and the recognized words to the 'handwriting'
*/
@@ -147,7 +125,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
@action
onPointerDown = (e: React.PointerEvent) => {
this._handledClick = false;
- const inkView = this.props.docViewPath().lastElement();
+ const inkView = this._props.docViewPath().lastElement();
const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData();
const screenPts = inkData
.map(point =>
@@ -159,7 +137,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
const { nearestSeg } = InkStrokeProperties.nearestPtToStroke(screenPts, { X: e.clientX, Y: e.clientY });
const controlIndex = nearestSeg;
const wasSelected = InkStrokeProperties.Instance._currentPoint === controlIndex;
- const isEditing = InkStrokeProperties.Instance._controlButton && this.props.isSelected();
+ const isEditing = InkStrokeProperties.Instance._controlButton && this._props.isSelected();
this.controlUndo = undefined;
setupMoveUpEvents(
this,
@@ -187,7 +165,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
InkStrokeProperties.Instance._currentPoint = -1;
this._handledClick = true; // mark the double-click pseudo pointerevent so we can block the real mouse event from propagating to DocumentView
if (isEditing) {
- this._nearestT && this._nearestSeg !== undefined && InkStrokeProperties.Instance.addPoints(this.props.docViewPath().lastElement(), this._nearestT, this._nearestSeg, this.inkScaledData().inkData.slice());
+ this._nearestT && this._nearestSeg !== undefined && InkStrokeProperties.Instance.addPoints(this._props.docViewPath().lastElement(), this._nearestT, this._nearestSeg, this.inkScaledData().inkData.slice());
}
}
}),
@@ -258,8 +236,8 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
inkLeft,
inkWidth,
inkHeight,
- inkScaleX: (this.props.PanelWidth() - inkStrokeWidth) / (inkWidth - inkStrokeWidth || 1) || 1,
- inkScaleY: (this.props.PanelHeight() - inkStrokeWidth) / (inkHeight - inkStrokeWidth || 1) || 1,
+ inkScaleX: (this._props.PanelWidth() - inkStrokeWidth) / (inkWidth - inkStrokeWidth || 1) || 1,
+ inkScaleY: (this._props.PanelHeight() - inkStrokeWidth) / (inkHeight - inkStrokeWidth || 1) || 1,
};
};
@@ -311,7 +289,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
* @returns the JSX controls for displaying an editing UI for the stroke (control point & tangent handles)
*/
componentUI = (boundsLeft: number, boundsTop: number) => {
- const inkDoc = this.props.Document;
+ const inkDoc = this.Document;
const { inkData, inkStrokeWidth } = this.inkScaledData();
const screenSpaceCenterlineStrokeWidth = Math.min(3, inkStrokeWidth * this.screenToLocal().inverse().Scale); // the width of the blue line widget that shows the centerline of the ink stroke
@@ -321,7 +299,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
const endMarker = StrCast(this.layoutDoc.stroke_endMarker);
const markerScale = NumCast(this.layoutDoc.stroke_markerScale);
return SnappingManager.IsDragging ? null : !InkStrokeProperties.Instance._controlButton ? (
- !this.props.isSelected() || InkingStroke.IsClosed(inkData) ? null : (
+ !this._props.isSelected() || InkingStroke.IsClosed(inkData) ? null : (
<div className="inkstroke-UI" style={{ clip: `rect(${boundsTop}px, 10000px, 10000px, ${boundsLeft}px)` }}>
<InkEndPtHandles inkView={this} inkDoc={inkDoc} startPt={this.startPt} endPt={this.endPt} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} />
</div>
@@ -360,12 +338,12 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
setSubContentView = (doc: DocComponentView) => (this._subContentView = doc);
@computed get fillColor() {
const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask);
- return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FillColor) ?? 'transparent';
+ return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) ?? 'transparent';
}
@computed get strokeColor() {
const { inkData } = this.inkScaledData();
const fillColor = this.fillColor;
- return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color) ?? StrCast(this.layoutDoc.color);
+ return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) ?? StrCast(this.layoutDoc.color);
}
render() {
TraceMobx();
@@ -385,9 +363,9 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
this.layoutDoc._height = Math.round(NumCast(this.layoutDoc._height));
});
}
- const highlight = !this.controlUndo && this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Highlighting);
+ const highlight = !this.controlUndo && this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting);
const highlightIndex = highlight?.highlightIndex;
- const highlightColor = !this.props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined;
+ const highlightColor = !this._props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined;
const color = StrCast(this.layoutDoc.stroke_outlineColor, !closed && fillColor && fillColor !== 'transparent' ? StrCast(this.layoutDoc.color, 'transparent') : 'transparent');
// Visually renders the polygonal line made by the user.
@@ -437,7 +415,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
inkScaleX,
inkScaleY,
'',
- this.props.pointerEvents?.() ?? 'visiblepainted',
+ this._props.pointerEvents?.() ?? 'visiblepainted',
0.0,
false,
downHdlr,
@@ -450,7 +428,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
const lineHeightGuess = +getComputedStyle(document.body).lineHeight.replace('px', '') / +getComputedStyle(document.body).fontSize.replace('px', '');
const interactions = {
onPointerLeave: action(() => (this._nearestScrPt = undefined)),
- onPointerMove: this.props.isSelected() ? this.onPointerMove : undefined,
+ onPointerMove: this._props.isSelected() ? this.onPointerMove : undefined,
onClick: (e: React.MouseEvent) => this._handledClick && e.stopPropagation(),
onContextMenu: () => {
const cm = ContextMenu.Instance;
@@ -464,27 +442,27 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
<svg
className="inkStroke"
style={{
- transform: isInkMask ? `rotate(-${NumCast(this.props.CollectionFreeFormDocumentView?.()._props.w_Rotation?.() ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
+ transform: isInkMask ? `rotate(-${NumCast(this._props.CollectionFreeFormDocumentView?.()._props.w_Rotation?.() ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
// mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? 'multiply' : 'unset',
- cursor: this.props.isSelected() ? 'default' : undefined,
+ cursor: this._props.isSelected() ? 'default' : undefined,
}}
{...interactions}>
{clickableLine(this.onPointerDown, isInkMask)}
{isInkMask ? null : inkLine}
</svg>
- {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this.props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (
+ {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this._props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (
<div
className="inkStroke-text"
style={{
color: StrCast(this.layoutDoc.textColor, 'black'),
- pointerEvents: this.props.isDocumentActive?.() ? 'all' : undefined,
+ pointerEvents: this._props.isDocumentActive?.() ? 'all' : undefined,
width: NumCast(this.layoutDoc._width),
- transform: `scale(${this.props.NativeDimScaling?.() || 1})`,
+ transform: `scale(${this._props.NativeDimScaling?.() || 1})`,
transformOrigin: 'top left',
- //top: (this.props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this.props.NativeDimScaling?.() || 1)) / 2,
+ //top: (this._props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this._props.NativeDimScaling?.() || 1)) / 2,
}}>
<FormattedTextBox
- {...this.props}
+ {...this._props}
setHeight={undefined}
setContentView={this.setSubContentView} // this makes the inkingStroke the "dominant" component - ie, it will show the inking UI when selected (not text)
yPadding={10}
@@ -493,7 +471,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
dontRegisterView={true}
noSidebar={true}
dontScale={true}
- isContentActive={this.props.isContentActive}
+ isContentActive={this._props.isContentActive}
/>
</div>
)}