aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/DocumentDecorations.scss28
-rw-r--r--src/client/views/DocumentDecorations.tsx41
-rw-r--r--src/client/views/GestureOverlay.tsx21
-rw-r--r--src/client/views/StyleProvider.scss18
-rw-r--r--src/client/views/StyleProvider.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx58
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx5
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx20
-rw-r--r--src/pen-gestures/GestureUtils.ts2
-rw-r--r--src/pen-gestures/ndollar.ts88
11 files changed, 148 insertions, 137 deletions
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index 5c8dd36cc..4e0b061a6 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -1,7 +1,7 @@
@import 'global/globalCssVariables';
$linkGap: 3px;
-$headerHeight: 20px;
+$headerHeight: 25px;
$resizeHandler: 8px;
.documentDecorations-Dark,
@@ -54,6 +54,8 @@ $resizeHandler: 8px;
grid-column-end: 4;
flex-direction: row;
gap: 2px;
+ pointer-events: all;
+ cursor: move;
.documentDecorations-openButton {
display: flex;
@@ -236,8 +238,8 @@ $resizeHandler: 8px;
.documentDecorations-borderRadius {
position: absolute;
border-radius: 100%;
- left: 3px;
- top: 23px;
+ left: 7px;
+ top: 27px;
background: $medium-gray;
height: 10;
width: 10;
@@ -245,6 +247,21 @@ $resizeHandler: 8px;
cursor: nwse-resize;
}
+ .documentDecorations-lock {
+ position: absolute;
+ background: black;
+ right: 11;
+ top: 30px;
+ color: gray;
+ height: 14;
+ width: 14;
+ pointer-events: all;
+ margin: auto;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ }
+
.documentDecorations-rotationPath {
position: absolute;
width: 100%;
@@ -260,6 +277,7 @@ $resizeHandler: 8px;
cursor: nwse-resize;
background: unset;
opacity: 1;
+ transform: scale(2);
}
.documentDecorations-topLeftResizer {
@@ -314,6 +332,7 @@ $resizeHandler: 8px;
.documentDecorations-topLeftResizer:hover,
.documentDecorations-bottomRightResizer:hover {
opacity: 1;
+ background: black;
}
.documentDecorations-bottomRightResizer {
@@ -325,6 +344,7 @@ $resizeHandler: 8px;
cursor: nesw-resize;
background: unset;
opacity: 1;
+ transform: scale(2);
}
.documentDecorations-topRightResizer {
@@ -339,7 +359,6 @@ $resizeHandler: 8px;
.documentDecorations-topRightResizer:hover,
.documentDecorations-bottomLeftResizer:hover {
- cursor: nesw-resize;
background: black;
opacity: 1;
}
@@ -392,6 +411,7 @@ $resizeHandler: 8px;
justify-content: center;
align-items: center;
gap: 5px;
+ top: 4px;
background: $light-gray;
}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 9881ef9f1..6cf7df357 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -140,6 +140,16 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
}
};
+ @action onContainerDown = (e: React.PointerEvent): void => {
+ setupMoveUpEvents(
+ this,
+ e,
+ e => this.onBackgroundMove(true, e),
+ e => {},
+ emptyFunction
+ );
+ };
+
@action onTitleDown = (e: React.PointerEvent): void => {
setupMoveUpEvents(
this,
@@ -311,6 +321,27 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
);
};
+ @action
+ onLockDown = (e: React.PointerEvent): void => {
+ // Call util move event function
+ setupMoveUpEvents(
+ this, // target
+ e, // pointerEvent
+ returnFalse, // moveEvent
+ emptyFunction, // upEvent
+ e => {
+ UndoManager.RunInBatch(
+ () =>
+ SelectionManager.Views().map(dv => {
+ dv.rootDoc._lockedPosition = !dv.rootDoc._lockedPosition;
+ dv.rootDoc._pointerEvents = dv.rootDoc._lockedPosition ? 'none' : undefined;
+ }),
+ 'toggleBackground'
+ );
+ } // clickEvent
+ );
+ };
+
setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => {
const newloccentern = seldocview.props.ScreenToLocalTransform().transformPoint(rotCenter[0], rotCenter[1]);
const newlocenter = [newloccentern[0] - NumCast(seldocview.layoutDoc._width) / 2, newloccentern[1] - NumCast(seldocview.layoutDoc._height) / 2];
@@ -791,7 +822,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
width: bounds.r - bounds.x + this._resizeBorderWidth + 'px',
height: bounds.b - bounds.y + this._resizeBorderWidth + this._titleHeight + 'px',
}}>
- <div className="documentDecorations-topbar">
+ <div className="documentDecorations-topbar" onPointerDown={this.onContainerDown}>
{hideDeleteButton ? <div /> : topBtn('close', 'times', undefined, e => this.onCloseClick(true), 'Close')}
{hideResizers || hideDeleteButton ? <div /> : topBtn('minimize', 'window-maximize', undefined, e => this.onCloseClick(undefined), 'Minimize')}
{hideResizers ? <div /> : titleArea}
@@ -817,21 +848,23 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
key="rad"
style={{
background: `${this._isRounding ? Colors.MEDIUM_BLUE : undefined}`,
- left: `${radiusHandleLocation + 3}`,
- top: `${radiusHandleLocation + 23}`,
+ transform: `translate(${radiusHandleLocation}px, ${radiusHandleLocation}px)`,
}}
className={`documentDecorations-borderRadius`}
onPointerDown={this.onRadiusDown}
onContextMenu={e => e.preventDefault()}
/>
)}
+ <div key="lock" className="documentDecorations-lock" style={{ color: seldocview.rootDoc._lockedPosition ? 'red' : undefined }} onPointerDown={this.onLockDown} onContextMenu={e => e.preventDefault()}>
+ <FontAwesomeIcon size="sm" icon="lock" />
+ </div>
{hideDocumentButtonBar ? null : (
<div
className="link-button-container"
key="links"
style={{
- transform: ` translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
+ transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
}}>
<DocumentButtonBar views={SelectionManager.Views} />
</div>
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 23b03bc50..362aa3c86 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -1,7 +1,7 @@
import React = require('react');
import * as fitCurve from 'fit-curve';
import { action, computed, observable, runInAction, trace } from 'mobx';
-import { Doc } from '../../fields/Doc';
+import { Doc, Opt } from '../../fields/Doc';
import { InkData, InkTool } from '../../fields/InkField';
import { List } from '../../fields/List';
import { ScriptField } from '../../fields/ScriptField';
@@ -49,7 +49,7 @@ interface GestureOverlayProps {
export class GestureOverlay extends Touchable<GestureOverlayProps> {
static Instance: GestureOverlay;
- @observable public InkShape: string = '';
+ @observable public InkShape: Opt<GestureUtils.Gestures>;
@observable public SavedColor?: string;
@observable public SavedWidth?: number;
@observable public Tool: ToolglassTools = ToolglassTools.None;
@@ -644,8 +644,6 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> {
if (this._points.length > 1) {
const B = this.svgBounds;
const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
- //push first points to so interactionUtil knows pointer is up
- this._points.push({ X: this._points[0].X, Y: this._points[0].Y });
const initialPoint = this._points[0];
const xInGlass = initialPoint.X > (this._thumbX ?? Number.MAX_SAFE_INTEGER) && initialPoint.X < (this._thumbX ?? Number.MAX_SAFE_INTEGER) + this.height;
@@ -685,10 +683,10 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> {
//if any of the shape is activated in the CollectionFreeFormViewChrome
else if (this.InkShape) {
this.makeBezierPolygon(this.InkShape, false);
- this.dispatchGesture(GestureUtils.Gestures.Stroke);
+ this.dispatchGesture(this.InkShape);
this._points.length = 0;
if (!CollectionFreeFormViewChrome.Instance?._keepPrimitiveMode) {
- this.InkShape = '';
+ this.InkShape = undefined;
Doc.ActiveTool = InkTool.None;
}
}
@@ -703,12 +701,13 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> {
case GestureUtils.Gestures.Rectangle:
case GestureUtils.Gestures.Circle:
this.makeBezierPolygon(result.Name, true);
- case GestureUtils.Gestures.StartBracket:
- case GestureUtils.Gestures.EndBracket:
actionPerformed = this.dispatchGesture(result.Name);
break;
case GestureUtils.Gestures.Line:
- actionPerformed = this.handleLineGesture();
+ if (!(actionPerformed = this.handleLineGesture())) {
+ this.makeBezierPolygon(result.Name, true);
+ actionPerformed = this.dispatchGesture(GestureUtils.Gestures.Stroke);
+ }
break;
case GestureUtils.Gestures.Scribble:
console.log('scribble');
@@ -972,7 +971,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> {
ActiveDash(),
1,
1,
- this.InkShape,
+ this.InkShape ?? '',
'none',
1.0,
false
@@ -999,7 +998,7 @@ export class GestureOverlay extends Touchable<GestureOverlayProps> {
ActiveDash(),
1,
1,
- this.InkShape,
+ this.InkShape ?? '',
'none',
1.0,
false
diff --git a/src/client/views/StyleProvider.scss b/src/client/views/StyleProvider.scss
index 8929954c8..b1c97164a 100644
--- a/src/client/views/StyleProvider.scss
+++ b/src/client/views/StyleProvider.scss
@@ -1,11 +1,11 @@
.styleProvider-lock {
- font-size: 12px;
- width: 20;
- height: 20;
- position: absolute;
- right: -25;
- top: -5;
- background: transparent;
+ font-size: 10;
+ width: 15;
+ height: 15;
+ position: absolute;
+ right: -0;
+ top: 0;
+ background: black;
pointer-events: all;
opacity: 0.3;
display: flex;
@@ -15,7 +15,7 @@
cursor: default;
}
.styleProvider-lock:hover {
- opacity:1;
+ opacity: 1;
}
.styleProvider-treeView-icon,
@@ -26,4 +26,4 @@
.styleProvider-treeView-icon {
opacity: 0;
-} \ No newline at end of file
+}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index aadcd7169..a5a886f42 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -276,7 +276,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
case StyleProp.Decorations:
if (props?.ContainingCollectionDoc?._viewType === CollectionViewType.Freeform || doc?.x !== undefined || doc?.y !== undefined) {
return doc &&
- (isBackground() || selected) &&
+ isBackground() &&
!Doc.IsSystem(doc) &&
(props?.renderDepth || 0) > 0 &&
((doc.type === DocumentType.COL && doc._viewType !== CollectionViewType.Pile) || [DocumentType.RTF, DocumentType.IMG, DocumentType.INK].includes(doc.type as DocumentType)) ? (
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index daf69d4f6..983cf4f9b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -568,6 +568,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@undoBatch
onGesture = (e: Event, ge: GestureUtils.GestureEvent) => {
switch (ge.gesture) {
+ case GestureUtils.Gestures.Line:
+ break;
default:
case GestureUtils.Gestures.Circle:
case GestureUtils.Gestures.Rectangle:
@@ -602,33 +604,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
e.stopPropagation();
break;
case GestureUtils.Gestures.Rectangle:
- const lt = this.getTransform().transformPoint(Math.min(...ge.points.map(p => p.X)), Math.min(...ge.points.map(p => p.Y)));
- const rb = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y)));
- const bounds = { x: lt[0], r: rb[0], y: lt[1], b: rb[1] };
- const bWidth = bounds.r - bounds.x;
- const bHeight = bounds.b - bounds.y;
- const sel = this.getActiveDocuments().filter(doc => {
- const l = NumCast(doc.x);
- const r = l + doc[WidthSym]();
- const t = NumCast(doc.y);
- const b = t + doc[HeightSym]();
- const pass = !(bounds.x > r || bounds.r < l || bounds.y > b || bounds.b < t);
- if (pass) {
- doc.x = l - bounds.x - bWidth / 2;
- doc.y = t - bounds.y - bHeight / 2;
- }
- return pass;
- });
- this.addDocument(Docs.Create.FreeformDocument(sel, { title: 'nested collection', x: bounds.x, y: bounds.y, _width: bWidth, _height: bHeight, _panX: 0, _panY: 0 }));
- sel.forEach(d => this.props.removeDocument?.(d));
- e.stopPropagation();
- break;
- case GestureUtils.Gestures.StartBracket:
- const start = this.getTransform().transformPoint(Math.min(...ge.points.map(p => p.X)), Math.min(...ge.points.map(p => p.Y)));
- this._inkToTextStartX = start[0];
- this._inkToTextStartY = start[1];
- break;
- case GestureUtils.Gestures.EndBracket:
if (this._inkToTextStartX && this._inkToTextStartY) {
const end = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y)));
const setDocs = this.getActiveDocuments().filter(s => s.proto?.type === 'rtf' && s.color);
@@ -805,15 +780,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const prevPointInkSpace = inkStroke.ptFromScreen(lastPoint);
const currPointInkSpace = inkStroke.ptFromScreen(currPoint);
for (var i = 0; i < inkData.length - 3; i += 4) {
- const intersects = Array.from(
- new Set(
- InkField.Segment(inkData, i).intersects({
- // compute all unique intersections
- p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y },
- p2: { x: currPointInkSpace.X, y: currPointInkSpace.Y },
- }) as (number | string)[]
- )
- ); // convert to more manageable union array type
+ const rawIntersects = InkField.Segment(inkData, i).intersects({
+ // compute all unique intersections
+ p1: { x: prevPointInkSpace.X, y: prevPointInkSpace.Y },
+ p2: { x: currPointInkSpace.X, y: currPointInkSpace.Y },
+ });
+ const intersects = Array.from(new Set(rawIntersects as (number | string)[])); // convert to more manageable union array type
+ if (intersects.length) {
+ console.log();
+ }
// return tuples of the inkingStroke intersected, and the t value of the intersection
intersections.push(...intersects.map(t => ({ inkView, t: +t + Math.floor(i / 4) }))); // convert string t's to numbers and add start of curve segment to convert from local t value to t value along complete curve
}
@@ -862,6 +837,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return segments;
};
+ // for some reason bezier.js doesn't handle the case of intersecting a linear curve, so we wrap the intersection
+ // call in a test for linearity
+ bintersects = (curve: Bezier, otherCurve: Bezier) => {
+ if ((otherCurve as any)._linear) {
+ return curve.lineIntersects({ p1: otherCurve.points[0], p2: otherCurve.points[3] });
+ }
+ return curve.intersects(otherCurve);
+ };
+
/**
* Determines all possible intersections of the current curve of the intersected ink stroke with all other curves of all
* ink strokes in the current collection.
@@ -886,7 +870,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
if (ink?.Document === otherInk.props.Document && neighboringSegment) continue;
const otherCurve = new Bezier(otherCtrlPts.slice(j, j + 4).map(p => ({ x: p.X, y: p.Y })));
- curve.intersects(otherCurve).forEach((val: string | number, i: number) => {
+ this.bintersects(curve, otherCurve).forEach((val: string | number, i: number) => {
// Converting the Bezier.js Split type to a t-value number.
const t = +val.toString().split('/')[0];
if (i % 2 === 0 && !tVals.includes(t)) tVals.push(t); // bcz: Hack! don't know why but intersection points are doubled from bezier.js (but not identical).
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1c48d47e9..040e03150 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1082,7 +1082,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
<DocumentLinksButton
View={this.props.DocumentView()}
scaling={this.linkButtonInverseScaling}
- Offset={[this.topMost ? 0 : !this.props.isSelected() ? -15 : -36, undefined, undefined, this.topMost ? 10 : !this.props.isSelected() ? -15 : -28]}
+ Offset={[this.topMost ? 0 : !this.props.isSelected() ? -15 : -36, undefined, undefined, this.topMost ? 10 : !this.props.isSelected() ? -15 : -32]}
/>
)}
{audioView}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 959c641a8..461d6984d 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -8,7 +8,7 @@ import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { createSchema } from '../../../fields/Schema';
import { ComputedField } from '../../../fields/ScriptField';
-import { Cast, NumCast } from '../../../fields/Types';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
import { emptyFunction, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../Utils';
@@ -77,10 +77,11 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
({ forceFull, scrSize, selected }) => (this._curSuffix = selected ? '_o' : this.fieldKey === 'icon' ? '_m' : forceFull ? '_o' : scrSize < 0.25 ? '_s' : scrSize < 0.5 ? '_m' : scrSize < 0.8 ? '_l' : '_o'),
{ fireImmediately: true, delay: 1000 }
);
+ const layoutDoc = this.layoutDoc;
this._disposers.path = reaction(
() => ({ nativeSize: this.nativeSize, width: this.layoutDoc[WidthSym]() }),
({ nativeSize, width }) => {
- if (true || !this.layoutDoc._height) {
+ if (layoutDoc === this.layoutDoc || !this.layoutDoc._height) {
this.layoutDoc._height = (width * nativeSize.nativeHeight) / nativeSize.nativeWidth;
}
},
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 6eaf3c31a..fd0c0d141 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -771,36 +771,26 @@ export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) {
CollectionFreeFormView.collectionsWithUnprocessedInk.clear();
}
-/** INK
- * setActiveTool
- * setStrokeWidth
- * setStrokeColor
- **/
-
-ScriptingGlobals.add(function setActiveTool(tool: string, checkResult?: boolean) {
+ScriptingGlobals.add(function setActiveTool(tool: InkTool | GestureUtils.Gestures, checkResult?: boolean) {
InkTranscription.Instance?.createInkGroup();
if (checkResult) {
return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool ? Colors.MEDIUM_BLUE : 'transparent';
}
- if ([GestureUtils.Gestures.Circle, GestureUtils.Gestures.Rectangle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Triangle].includes(tool as any)) {
+ if (Object.values(GestureUtils.Gestures).includes(tool as any)) {
if (GestureOverlay.Instance.InkShape === tool) {
Doc.ActiveTool = InkTool.None;
- GestureOverlay.Instance.InkShape = InkTool.None;
+ GestureOverlay.Instance.InkShape = undefined;
} else {
Doc.ActiveTool = InkTool.Pen;
- GestureOverlay.Instance.InkShape = tool;
+ GestureOverlay.Instance.InkShape = tool as GestureUtils.Gestures;
}
} else if (tool) {
// pen or eraser
if (Doc.ActiveTool === tool && !GestureOverlay.Instance.InkShape) {
Doc.ActiveTool = InkTool.None;
- } else if (tool == InkTool.Write) {
- // console.log("write mode selected - create groupDoc here!", tool)
- Doc.ActiveTool = tool;
- GestureOverlay.Instance.InkShape = '';
} else {
Doc.ActiveTool = tool as any;
- GestureOverlay.Instance.InkShape = '';
+ GestureOverlay.Instance.InkShape = undefined;
}
} else {
Doc.ActiveTool = InkTool.None;
diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts
index 2d3b1fdb8..41917aac9 100644
--- a/src/pen-gestures/GestureUtils.ts
+++ b/src/pen-gestures/GestureUtils.ts
@@ -19,8 +19,6 @@ export namespace GestureUtils {
export enum Gestures {
Line = 'line',
- StartBracket = 'startbracket',
- EndBracket = 'endbracket',
Stroke = 'stroke',
Scribble = 'scribble',
Text = 'text',
diff --git a/src/pen-gestures/ndollar.ts b/src/pen-gestures/ndollar.ts
index b10a9da17..3ee9506cb 100644
--- a/src/pen-gestures/ndollar.ts
+++ b/src/pen-gestures/ndollar.ts
@@ -145,7 +145,7 @@ export class Result {
//
// NDollarRecognizer constants
//
-const NumMultistrokes = 6;
+let NumMultistrokes = 0;
const NumPoints = 96;
const SquareSize = 250.0;
const OneDThreshold = 0.25; // customize to desired gesture set (usually 0.20 - 0.35)
@@ -162,73 +162,59 @@ const AngleSimilarityThreshold = Deg2Rad(30.0);
// NDollarRecognizer class
//
export class NDollarRecognizer {
- public Multistrokes: Multistroke[];
+ public Multistrokes: Multistroke[] = [];
- /**
- * @IMPORTANT - IF YOU'RE ADDING A NEW GESTURE, BE SURE TO INCREMENT THE NumMultiStrokes CONST RIGHT ABOVE THIS CLASS.
- */
constructor(
useBoundedRotationInvariance: boolean // constructor
) {
//
// one predefined multistroke for each multistroke type
//
- this.Multistrokes = new Array(NumMultistrokes);
- this.Multistrokes[0] = new Multistroke(
- GestureUtils.Gestures.Rectangle,
- useBoundedRotationInvariance,
- new Array(
+ this.Multistrokes.push(
+ new Multistroke(
+ GestureUtils.Gestures.Rectangle,
+ useBoundedRotationInvariance,
new Array(
- new Point(30, 146), //new Point(29, 160), new Point(30, 180), new Point(31, 200),
- new Point(30, 222), //new Point(50, 219), new Point(70, 225), new Point(90, 230),
- new Point(106, 225), //new Point(100, 200), new Point(106, 180), new Point(110, 160),
- new Point(106, 146), //new Point(80, 150), new Point(50, 146),
- new Point(30, 143)
+ new Array(
+ new Point(30, 146), //new Point(29, 160), new Point(30, 180), new Point(31, 200),
+ new Point(30, 222), //new Point(50, 219), new Point(70, 225), new Point(90, 230),
+ new Point(106, 225), //new Point(100, 200), new Point(106, 180), new Point(110, 160),
+ new Point(106, 146), //new Point(80, 150), new Point(50, 146),
+ new Point(30, 143)
+ )
)
)
);
- this.Multistrokes[1] = new Multistroke(GestureUtils.Gestures.Line, useBoundedRotationInvariance, new Array(new Array(new Point(12, 347), new Point(119, 347))));
- this.Multistrokes[2] = new Multistroke(
- GestureUtils.Gestures.StartBracket,
- useBoundedRotationInvariance,
- new Array(
- // new Array(new Point(145, 20), new Point(30, 21), new Point(34, 150))
- new Array(new Point(31, 25), new Point(145, 20), new Point(31, 25), new Point(34, 150))
+ this.Multistrokes.push(new Multistroke(GestureUtils.Gestures.Line, useBoundedRotationInvariance, new Array(new Array(new Point(12, 347), new Point(119, 347)))));
+ this.Multistrokes.push(
+ new Multistroke(
+ GestureUtils.Gestures.Triangle, // equilateral
+ useBoundedRotationInvariance,
+ new Array(new Array(new Point(40, 100), new Point(100, 200), new Point(140, 102), new Point(42, 100)))
)
);
- this.Multistrokes[3] = new Multistroke(
- GestureUtils.Gestures.EndBracket,
- useBoundedRotationInvariance,
- new Array(
- // new Array(new Point(150, 21), new Point(149, 150), new Point(26, 152))
- // new Array(new Point(150, 150), new Point(150, 0), new Point(150, 150), new Point(0, 150))
- new Array(new Point(10, 100), new Point(100, 100), new Point(150, 12), new Point(200, 103), new Point(300, 100))
- )
- );
- this.Multistrokes[4] = new Multistroke(
- GestureUtils.Gestures.Triangle, // equilateral
- useBoundedRotationInvariance,
- new Array(new Array(new Point(40, 100), new Point(100, 200), new Point(140, 102), new Point(42, 100)))
- );
- this.Multistrokes[5] = new Multistroke(
- GestureUtils.Gestures.Circle,
- useBoundedRotationInvariance,
- new Array(
+ this.Multistrokes.push(
+ new Multistroke(
+ GestureUtils.Gestures.Circle,
+ useBoundedRotationInvariance,
new Array(
- new Point(200, 250),
- new Point(240, 230),
- new Point(248, 210),
- new Point(248, 190),
- new Point(240, 170),
- new Point(200, 150),
- new Point(160, 170),
- new Point(151, 190),
- new Point(151, 210),
- new Point(160, 230),
- new Point(201, 250)
+ new Array(
+ new Point(200, 250),
+ new Point(240, 230),
+ new Point(248, 210),
+ new Point(248, 190),
+ new Point(240, 170),
+ new Point(200, 150),
+ new Point(160, 170),
+ new Point(151, 190),
+ new Point(151, 210),
+ new Point(160, 230),
+ new Point(201, 250)
+ )
)
)
);
+ NumMultistrokes = this.Multistrokes.length; // NumMultistrokes flags the end of the non user-defined gstures strokes
//
// PREDEFINED STROKES
//