diff options
-rw-r--r-- | src/client/views/InkingCanvas.tsx | 35 | ||||
-rw-r--r-- | src/client/views/Touchable.tsx | 20 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 15 |
3 files changed, 57 insertions, 13 deletions
diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 7651060af..2f3083cfe 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -10,6 +10,8 @@ import { UndoManager } from "../util/UndoManager"; import { StrokeData, InkField, InkTool } from "../../new_fields/InkField"; import { Doc } from "../../new_fields/Doc"; import { Cast, PromiseValue, NumCast } from "../../new_fields/Types"; +import { Touchable } from "./Touchable"; +import { InteractionUtils } from "../util/InteractionUtils"; interface InkCanvasProps { getScreenTransform: () => Transform; @@ -20,7 +22,7 @@ interface InkCanvasProps { } @observer -export class InkingCanvas extends React.Component<InkCanvasProps> { +export class InkingCanvas extends Touchable<InkCanvasProps> { maxCanvasDim = 8192 / 2; // 1/2 of the maximum canvas dimension for Chrome @observable inkMidX: number = 0; @observable inkMidY: number = 0; @@ -94,6 +96,18 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { } @action + handle1PointerMove = (e: TouchEvent) => { + e.stopPropagation(); + e.preventDefault(); + let pointer = e.targetTouches.item(0); + if (pointer) { + this.handleMove(pointer.clientX, pointer.clientY); + } + } + + handle2PointersMove = () => { } + + @action onPointerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onPointerMove, true); document.removeEventListener("pointerup", this.onPointerUp, true); @@ -116,21 +130,28 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { batch.end(); } - @action - onPointerMove = (e: PointerEvent): void => { - e.stopPropagation(); - e.preventDefault(); + handleMove = (x: number, y: number) => { if (InkingControl.Instance.selectedTool !== InkTool.Eraser) { let data = this.inkData; // add points to new line as it is being drawn let strokeData = data.get(this._currentStrokeId); if (strokeData) { - strokeData.pathData.push(this.relativeCoordinatesForEvent(e.clientX, e.clientY)); + strokeData.pathData.push(this.relativeCoordinatesForEvent(x, y)); data.set(this._currentStrokeId, strokeData); } this.inkData = data; } } + @action + onPointerMove = (e: PointerEvent): void => { + if (InteractionUtils.IsType(e, InteractionUtils.TOUCH)) { + return; + } + e.stopPropagation(); + e.preventDefault(); + this.handleMove(e.clientX, e.clientY); + } + relativeCoordinatesForEvent = (ex: number, ey: number): { x: number, y: number } => { let [x, y] = this.props.getScreenTransform().transformPoint(ex, ey); return { x, y }; @@ -183,7 +204,7 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { let svgCanvasStyle = InkingControl.Instance.selectedTool !== InkTool.None && !this.props.Document.isBackground ? "canSelect" : "noSelect"; return ( <div className="inkingCanvas"> - <div className={`inkingCanvas-${svgCanvasStyle}`} onPointerDown={this.onPointerDown} onTouchStart={(e) => e.stopPropagation()} /> + <div className={`inkingCanvas-${svgCanvasStyle}`} onPointerDown={this.onPointerDown} onTouchStart={this.onTouchStart} /> {this.props.children()} {this.drawnPaths} </div > diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx index e9671ab8b..4955129ba 100644 --- a/src/client/views/Touchable.tsx +++ b/src/client/views/Touchable.tsx @@ -20,6 +20,15 @@ export abstract class Touchable<T> extends React.Component<T> { let pt = e.targetTouches.item(i); this.prevPoints.set(pt.identifier, pt); } + + switch (e.targetTouches.length) { + case 1: + this.handle1PointerDown(); + break; + case 2: + this.handle2PointersDown(e); + } + document.removeEventListener("touchmove", this.onTouch); document.addEventListener("touchmove", this.onTouch); document.removeEventListener("touchend", this.onTouchEnd); @@ -36,10 +45,10 @@ export abstract class Touchable<T> extends React.Component<T> { this._touchDrag = true; switch (e.targetTouches.length) { case 1: - this.handle1Pointer(e) + this.handle1PointerMove(e) break; case 2: - this.handle2Pointers(e); + this.handle2PointersMove(e); break; } } @@ -70,13 +79,16 @@ export abstract class Touchable<T> extends React.Component<T> { document.removeEventListener("touchend", this.onTouchEnd); } - handle1Pointer = (e: TouchEvent): any => { + handle1PointerMove = (e: TouchEvent): any => { e.stopPropagation(); e.preventDefault(); } - handle2Pointers = (e: TouchEvent): any => { + handle2PointersMove = (e: TouchEvent): any => { e.stopPropagation(); e.preventDefault(); } + + handle1PointerDown = (): any => { }; + handle2PointersDown = (e: React.TouchEvent): any => { }; }
\ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 440a0a8e5..123941b03 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -356,7 +356,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } } - handle1Pointer = (e: TouchEvent) => { + handle1PointerMove = (e: TouchEvent) => { // panning a workspace if (!e.cancelBubble && this.props.active()) { let pt = e.targetTouches.item(0); @@ -368,7 +368,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { } } - handle2Pointers = (e: TouchEvent) => { + handle2PointersMove = (e: TouchEvent) => { // pinch zooming if (!e.cancelBubble) { let pt1: Touch | null = e.targetTouches.item(0); @@ -413,6 +413,17 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { e.preventDefault(); } + handle2PointersDown = (e: React.TouchEvent) => { + let pt1: React.Touch | null = e.targetTouches.item(0); + let pt2: React.Touch | null = e.targetTouches.item(1); + if (!pt1 || !pt2) return; + + let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2; + let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2; + this._lastX = centerX; + this._lastY = centerY; + } + cleanUpInteractions = () => { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); |