diff options
| author | laurawilsonri <laura_wilson@brown.edu> | 2019-04-08 19:10:03 -0400 |
|---|---|---|
| committer | laurawilsonri <laura_wilson@brown.edu> | 2019-04-08 19:10:03 -0400 |
| commit | 74411165f21b6c616fa98e0676c6f4568c2d4564 (patch) | |
| tree | 38079f721f8cdeba25e7bc0439aa5d6523927f1c /src/client/views/InkingCanvas.tsx | |
| parent | 5d4414e8d2a17c75c808bce9343dba85fbb32440 (diff) | |
| parent | a72fcdd0ebc06a3c851007c6ed89ab13a9a0d835 (diff) | |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into richTextEditor
Diffstat (limited to 'src/client/views/InkingCanvas.tsx')
| -rw-r--r-- | src/client/views/InkingCanvas.tsx | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index 3189e8a5f..45ca52d00 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -1,4 +1,4 @@ -import { action, computed, trace } from "mobx"; +import { action, computed, trace, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../fields/Document"; import { FieldWaiting } from "../../fields/Field"; @@ -14,26 +14,40 @@ import React = require("react"); interface InkCanvasProps { getScreenTransform: () => Transform; Document: Document; + children: () => JSX.Element[]; } @observer export class InkingCanvas extends React.Component<InkCanvasProps> { - static InkOffset: number = 50000; + maxCanvasDim = 8192 / 2; // 1/2 of the maximum canvas dimension for Chrome + @observable inkMidX: number = 0; + @observable inkMidY: number = 0; private _currentStrokeId: string = ""; public static IntersectStrokeRect(stroke: StrokeData, selRect: { left: number, top: number, width: number, height: number }): boolean { - return stroke.pathData.reduce((inside, val) => inside || - (selRect.left < val.x - InkingCanvas.InkOffset && selRect.left + selRect.width > val.x - InkingCanvas.InkOffset && - selRect.top < val.y - InkingCanvas.InkOffset && selRect.top + selRect.height > val.y - InkingCanvas.InkOffset) - , false as boolean); + return stroke.pathData.reduce((inside: boolean, val) => inside || + (selRect.left < val.x && selRect.left + selRect.width > val.x && + selRect.top < val.y && selRect.top + selRect.height > val.y) + , false); + } + + componentDidMount() { + this.props.Document.GetTAsync(KeyStore.Ink, InkField, ink => runInAction(() => { + if (ink) { + let bounds = Array.from(ink.Data).reduce(([mix, max, miy, may], [id, strokeData]) => + strokeData.pathData.reduce(([mix, max, miy, may], p) => + [Math.min(mix, p.x), Math.max(max, p.x), Math.min(miy, p.y), Math.max(may, p.y)], + [mix, max, miy, may]), + [Number.MAX_VALUE, Number.MIN_VALUE, Number.MAX_VALUE, Number.MIN_VALUE]); + this.inkMidX = (bounds[0] + bounds[1]) / 2; + this.inkMidY = (bounds[2] + bounds[3]) / 2; + } + })); } @computed get inkData(): StrokeMap { let map = this.props.Document.GetT(KeyStore.Ink, InkField); - if (!map || map === FieldWaiting) { - return new Map; - } - return new Map(map.Data); + return !map || map === FieldWaiting ? new Map : new Map(map.Data); } set inkData(value: StrokeMap) { @@ -63,9 +77,15 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { } } + @action onPointerUp = (e: PointerEvent): void => { document.removeEventListener("pointermove", this.onPointerMove, true); document.removeEventListener("pointerup", this.onPointerUp, true); + let coord = this.relativeCoordinatesForEvent(e.clientX, e.clientY); + if (Math.abs(coord.x - this.inkMidX) > 500 || Math.abs(coord.y - this.inkMidY) > 500) { + this.inkMidX = coord.x; + this.inkMidY = coord.y; + } e.stopPropagation(); e.preventDefault(); } @@ -87,8 +107,6 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { relativeCoordinatesForEvent = (ex: number, ey: number): { x: number, y: number } => { let [x, y] = this.props.getScreenTransform().transformPoint(ex, ey); - x += InkingCanvas.InkOffset; - y += InkingCanvas.InkOffset; return { x, y }; } @@ -101,30 +119,32 @@ export class InkingCanvas extends React.Component<InkCanvasProps> { @computed get drawnPaths() { - // parse data from server let curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1) let paths = Array.from(this.inkData).reduce((paths, [id, strokeData]) => { if (strokeData.page == -1 || strokeData.page == curPage) paths.push(<InkingStroke key={id} id={id} line={strokeData.pathData} + offsetX={this.maxCanvasDim - this.inkMidX} + offsetY={this.maxCanvasDim - this.inkMidY} color={strokeData.color} width={strokeData.width} tool={strokeData.tool} deleteCallback={this.removeLine} />) return paths; }, [] as JSX.Element[]); - return [<svg className={`inkingCanvas-paths-markers`} key="Markers" > + return [<svg className={`inkingCanvas-paths-markers`} key="Markers" + style={{ left: `${this.inkMidX - this.maxCanvasDim}px`, top: `${this.inkMidY - this.maxCanvasDim}px` }} > {paths.filter(path => path.props.tool == InkTool.Highlighter)} </svg>, - <svg className={`inkingCanvas-paths-ink`} key="Pens" > + <svg className={`inkingCanvas-paths-ink`} key="Pens" + style={{ left: `${this.inkMidX - this.maxCanvasDim}px`, top: `${this.inkMidY - this.maxCanvasDim}px` }}> {paths.filter(path => path.props.tool != InkTool.Highlighter)} </svg>]; } render() { let svgCanvasStyle = InkingControl.Instance.selectedTool != InkTool.None ? "canSelect" : "noSelect"; - return ( <div className="inkingCanvas" > - <svg className={`inkingCanvas-${svgCanvasStyle}`} onPointerDown={this.onPointerDown} /> - {(this.props.children as any)() /* bcz: is there a better way to know that children is a function? */} + <div className={`inkingCanvas-${svgCanvasStyle}`} onPointerDown={this.onPointerDown} /> + {this.props.children()} {this.drawnPaths} </div > ) |
