diff options
author | bobzel <zzzman@gmail.com> | 2021-09-02 14:57:28 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2021-09-02 14:57:28 -0400 |
commit | 24c1290cfe41ba9b7c1f1e0a9442f03b4af70c58 (patch) | |
tree | 2032ddbb58194e2b928ce23973663f0f14e4f6c9 /src | |
parent | 57243cb00f2fd575e5d5d6a79108cb97793bc01c (diff) |
corrected fix to drawing ink stroke in doc decorations overlay.
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 51 | ||||
-rw-r--r-- | src/client/views/InkingStroke.tsx | 54 |
2 files changed, 52 insertions, 53 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index a615d8b26..ce33f488a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -3,33 +3,33 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from '@material-ui/core'; import { action, computed, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; +import { DateField } from '../../fields/DateField'; import { AclAdmin, AclEdit, DataSym, Doc, Field, HeightSym, WidthSym } from "../../fields/Doc"; import { Document } from '../../fields/documentSchemas'; -import { HtmlField } from '../../fields/HtmlField'; import { InkField } from "../../fields/InkField"; import { ScriptField } from '../../fields/ScriptField'; import { Cast, NumCast, StrCast } from "../../fields/Types"; import { GetEffectiveAcl } from '../../fields/util'; -import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils"; -import { Docs, DocUtils } from "../documents/Documents"; +import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../Utils"; +import { Docs } from "../documents/Documents"; import { DocumentType } from '../documents/DocumentTypes'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; import { DragManager } from "../util/DragManager"; +import { InteractionUtils } from '../util/InteractionUtils'; import { SelectionManager } from "../util/SelectionManager"; import { SnappingManager } from '../util/SnappingManager'; import { undoBatch, UndoManager } from "../util/UndoManager"; import { CollectionDockingView } from './collections/CollectionDockingView'; import { DocumentButtonBar } from './DocumentButtonBar'; import './DocumentDecorations.scss'; +import { Colors } from './global/globalEnums'; import { KeyManager } from './GlobalKeyHandler'; +import { InkingStroke } from './InkingStroke'; import { InkStrokeProperties } from './InkStrokeProperties'; import { LightboxView } from './LightboxView'; import { DocumentView } from "./nodes/DocumentView"; -import React = require("react"); import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; -import { DateField } from '../../fields/DateField'; -import { InteractionUtils } from '../util/InteractionUtils'; -import { Colors } from './global/globalEnums'; +import React = require("react"); @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number, PanelHeight: number, boundsLeft: number, boundsTop: number }, { value: string }> { @@ -457,32 +457,23 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight)); const useRotation = seldoc.rootDoc.type === DocumentType.INK; - const docView = SelectionManager.Views().lastElement().docView; + const docView = seldoc.docView; let selectedLine = null; if (useRotation && docView) { - const inkData = Cast(SelectionManager.Views().lastElement().rootDoc.data, InkField)?.inkData ?? [{ X: 0, Y: 0 }]; - const inkDoc = SelectionManager.Views().lastElement().layoutDoc; - const swidth = docView.screenToLocal().inverse().transformDirection(NumCast(seldoc.props.Document.strokeWidth, 1), NumCast(seldoc.props.Document.strokeWidth, 1)); - - const points = inkData.map((point) => docView.screenToLocal().inverse().transformPoint(point.X, point.Y)).map(p => ({ X: p[0], Y: p[1] })); - - const strokeWidth = 1; - const lineTop = Math.min(...points.map(p => p.Y)) - swidth[0] / 2; - const lineBottom = Math.max(...points.map(p => p.Y)) + swidth[0] / 2; - const lineLeft = Math.min(...points.map(p => p.X)) - swidth[0] / 2; - const lineRight = Math.max(...points.map(p => p.X)) + swidth[0] / 2; - const left = lineLeft; - const top = lineTop; - const right = lineRight; - const bottom = lineBottom; - const width = Math.max(1, right - left); - const height = Math.max(1, bottom - top); - const scaleX = width === strokeWidth ? 1 : (bounds.r - bounds.x) / (width - strokeWidth); - const scaleY = height === strokeWidth ? 1 : (bounds.b - bounds.y) / (height - strokeWidth); - - selectedLine = InteractionUtils.CreatePolyline(points, left, top, Colors.MEDIUM_BLUE, strokeWidth, strokeWidth, StrCast(inkDoc.strokeBezier), StrCast(inkDoc.fillColor, "none"), - StrCast(inkDoc.strokeStartMarker), StrCast(inkDoc.strokeEndMarker), StrCast(inkDoc.strokeDash), scaleX, scaleY, "", "none", 1.0, false); + const inkData = Cast(seldoc.rootDoc.data, InkField)?.inkData ?? [{ X: 0, Y: 0 }]; + const inkDoc = seldoc.layoutDoc; + const overlayInkWidth = 10; + + const { inkScaleX, inkScaleY, inkStrokeWidth } = InkingStroke.inkScaling(inkDoc, inkData, docView.props.PanelWidth(), docView.props.PanelHeight()); + + const screenInkWidth = docView.screenToLocal().inverse().transformDirection(inkStrokeWidth, inkStrokeWidth); + const screenPts = inkData.map(point => docView.screenToLocal().inverse().transformPoint(point.X * inkScaleX, point.Y * inkScaleY)).map(p => ({ X: p[0], Y: p[1] })); + const screenTop = Math.min(...screenPts.map(p => p.Y)) - screenInkWidth[0] / 2; + const screenLeft = Math.min(...screenPts.map(p => p.X)) - screenInkWidth[0] / 2; + + selectedLine = InteractionUtils.CreatePolyline(screenPts, screenLeft, screenTop, Colors.MEDIUM_BLUE, overlayInkWidth, overlayInkWidth, StrCast(inkDoc.strokeBezier), StrCast(inkDoc.fillColor, "none"), + StrCast(inkDoc.strokeStartMarker), StrCast(inkDoc.strokeEndMarker), StrCast(inkDoc.strokeDash), 1, 1, "", "none", 1.0, false); } return (<div className="documentDecorations" style={{ background: CurrentUserUtils.ActiveDashboard?.darkScheme ? "dimgray" : "" }} > diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index b619f858e..b8ab0c4d8 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -5,7 +5,7 @@ import { Doc } from "../../fields/Doc"; import { documentSchema } from "../../fields/documentSchemas"; import { InkData, InkField, InkTool } from "../../fields/InkField"; import { makeInterface } from "../../fields/Schema"; -import { Cast, StrCast } from "../../fields/Types"; +import { Cast, StrCast, NumCast } from "../../fields/Types"; import { TraceMobx } from "../../fields/util"; import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils"; import { CognitiveServices } from "../cognitive_services/CognitiveServices"; @@ -88,6 +88,24 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume // } } + public static inkScaling(inkDoc: Doc, inkData: InkData, panelWidth: number, panelHeight: number) { + const inkStrokeWidth = NumCast(inkDoc.strokeWidth, 1); + const inkTop = Math.min(...inkData.map(p => p.Y)) - inkStrokeWidth / 2; + const inkBottom = Math.max(...inkData.map(p => p.Y)) + inkStrokeWidth / 2; + const inkLeft = Math.min(...inkData.map(p => p.X)) - inkStrokeWidth / 2; + const inkRight = Math.max(...inkData.map(p => p.X)) + inkStrokeWidth / 2; + const inkWidth = Math.max(1, inkRight - inkLeft); + const inkHeight = Math.max(1, inkBottom - inkTop); + return { + inkStrokeWidth, + inkTop, + inkLeft, + inkWidth, + inkHeight, + inkScaleX: inkHeight === inkStrokeWidth ? 1 : (panelWidth - inkStrokeWidth) / (inkWidth - inkStrokeWidth), + inkScaleY: inkWidth === inkStrokeWidth ? 1 : (panelHeight - inkStrokeWidth) / (inkHeight - inkStrokeWidth) + }; + } render() { TraceMobx(); this.toggleControlButton(); @@ -95,34 +113,24 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume // Extracting the ink data and formatting information of the current ink stroke. const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? []; const inkDoc: Doc = this.layoutDoc; - const strokeWidth = Number(this.layoutDoc.strokeWidth); - const lineTop = Math.min(...data.map(p => p.Y)); - const lineBottom = Math.max(...data.map(p => p.Y)); - const lineLeft = Math.min(...data.map(p => p.X)); - const lineRight = Math.max(...data.map(p => p.X)); - const left = lineLeft - strokeWidth / 2; - const top = lineTop - strokeWidth / 2; - const right = lineRight + strokeWidth / 2; - const bottom = lineBottom + strokeWidth / 2; - const width = Math.max(1, right - left); - const height = Math.max(1, bottom - top); - const scaleX = width === strokeWidth ? 1 : (this.props.PanelWidth() - strokeWidth) / (width - strokeWidth); - const scaleY = height === strokeWidth ? 1 : (this.props.PanelHeight() - strokeWidth) / (height - strokeWidth); + + const { inkStrokeWidth, inkLeft, inkTop, inkScaleX, inkScaleY, inkWidth, inkHeight } = InkingStroke.inkScaling(inkDoc, data, this.props.PanelWidth(), this.props.PanelHeight()); + const strokeColor = StrCast(this.layoutDoc.color, ""); - const dotsize = Math.max(width * scaleX, height * scaleY) / 40; + const dotsize = Math.max(inkWidth * inkScaleX, inkHeight * inkScaleY) / 40; // Visually renders the polygonal line made by the user. - const inkLine = InteractionUtils.CreatePolyline(data, left, top, strokeColor, strokeWidth, strokeWidth, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), StrCast(this.layoutDoc.strokeStartMarker), - StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", 1.0, false); + const inkLine = InteractionUtils.CreatePolyline(data, inkLeft, inkTop, strokeColor, inkStrokeWidth, inkStrokeWidth, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), StrCast(this.layoutDoc.strokeStartMarker), + StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), inkScaleX, inkScaleY, "", "none", 1.0, false); // Thin blue line indicating that the current ink stroke is selected. // const selectedLine = InteractionUtils.CreatePolyline(data, left, top, Colors.MEDIUM_BLUE, strokeWidth, strokeWidth / 6, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), // StrCast(this.layoutDoc.strokeStartMarker), StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", 1.0, false); // Invisible polygonal line that enables the ink to be selected by the user. - const clickableLine = InteractionUtils.CreatePolyline(data, left, top, "transparent", strokeWidth, strokeWidth + 15, StrCast(this.layoutDoc.strokeBezier), - StrCast(this.layoutDoc.fillColor, "none"), "none", "none", undefined, scaleX, scaleY, "", this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted", 0.0, true); + const clickableLine = InteractionUtils.CreatePolyline(data, inkLeft, inkTop, "transparent", inkStrokeWidth, inkStrokeWidth + 15, StrCast(this.layoutDoc.strokeBezier), + StrCast(this.layoutDoc.fillColor, "none"), "none", "none", undefined, inkScaleX, inkScaleY, "", this.props.layerProvider?.(this.props.Document) === false ? "none" : "visiblepainted", 0.0, true); // Set of points rendered upon the ink that can be added if a user clicks on one. - const addedPoints = InteractionUtils.CreatePoints(data, left, top, strokeColor, strokeWidth, strokeWidth, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), StrCast(this.layoutDoc.strokeStartMarker), - StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), scaleX, scaleY, "", "none", this.props.isSelected() && strokeWidth <= 5, false); + const addedPoints = InteractionUtils.CreatePoints(data, inkLeft, inkTop, strokeColor, inkStrokeWidth, inkStrokeWidth, StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "none"), StrCast(this.layoutDoc.strokeStartMarker), + StrCast(this.layoutDoc.strokeEndMarker), StrCast(this.layoutDoc.strokeDash), inkScaleX, inkScaleY, "", "none", this.props.isSelected() && inkStrokeWidth <= 5, false); return ( <svg className="inkStroke" @@ -152,12 +160,12 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume inkDoc={inkDoc} data={data} addedPoints={addedPoints} - format={[left, top, scaleX, scaleY, strokeWidth]} + format={[lineLeft, lineTop, scaleX, scaleY, inkStrokeWidth]} ScreenToLocalTransform={this.props.ScreenToLocalTransform} /> <InkHandles inkDoc={inkDoc} data={data} - format={[left, top, scaleX, scaleY, strokeWidth]} + format={[lineLeft, lineTop, scaleX, scaleY, inkStrokeWidth]} ScreenToLocalTransform={this.props.ScreenToLocalTransform} /> </> : ""} </svg> |