aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-03-31 22:45:43 -0400
committerBob Zeleznik <zzzman@gmail.com>2019-03-31 22:45:43 -0400
commit2ac86b53d28abb8be2f3abd501b801e543973e28 (patch)
treeaed62f96be9241cd25234eae97e3521ff5c89194
parenteb220da697e2383b1e368dee743613158994746e (diff)
restructured inkingCanvas and linksViews
-rw-r--r--src/client/views/InkingCanvas.scss164
-rw-r--r--src/client/views/InkingCanvas.tsx121
-rw-r--r--src/client/views/InkingControl.scss135
-rw-r--r--src/client/views/InkingControl.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx9
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss10
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx10
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx6
-rw-r--r--src/client/views/nodes/PDFBox.tsx10
10 files changed, 233 insertions, 238 deletions
diff --git a/src/client/views/InkingCanvas.scss b/src/client/views/InkingCanvas.scss
index e79b146b9..6d7821cd2 100644
--- a/src/client/views/InkingCanvas.scss
+++ b/src/client/views/InkingCanvas.scss
@@ -1,149 +1,25 @@
@import "global_variables";
-.inking-canvas {
+
+.inkingCanvas-paths, .inkingCanvas-paths-none {
position: absolute;
top: -50000px;
- left: -50000px; // z-index: 99; //overlays ink on top of everything
- svg {
- position:absolute;
- width: 100000px;
- height: 100000px;
- .highlight {
- mix-blend-mode: multiply;
- }
- }
+ left: -50000px;
+ width: 100000px;
+ height: 100000px;
+ //z-index: 10000; // z-index: 99; //overlays ink on top of everything but that messes up blending and events don't propagate down to nested collections
+ .highlight {
+ mix-blend-mode: multiply;
+ }
+ .inkingCanvas-children {
+ transform: translate(50000px, 50000px);
+ pointer-events: none;
+ }
+ cursor:"crosshair";
+ pointer-events: auto;
+
+}
+.inkingCanvas-paths-none {
+ pointer-events: none;
+ cursor: "arrow";
}
-.inking-control {
- position: absolute;
- left: 70px;
- bottom: 70px;
- margin: 0;
- padding: 0;
- display: flex;
- label,
- input,
- option {
- font-size: 12px;
- }
- input[type="range"] {
- -webkit-appearance: none;
- background-color: transparent;
- vertical-align: middle;
- margin-top: 8px;
- &:focus {
- outline: none;
- }
- &::-webkit-slider-runnable-track {
- width: 100%;
- height: 3px;
- border-radius: 1.5px;
- cursor: pointer;
- background: $intermediate-color;
- }
- &::-webkit-slider-thumb {
- height: 12px;
- width: 12px;
- border: 1px solid $intermediate-color;
- border-radius: 6px;
- background: $light-color;
- cursor: pointer;
- -webkit-appearance: none;
- margin-top: -4px;
- }
- &::-moz-range-track {
- width: 100%;
- height: 3px;
- border-radius: 1.5px;
- cursor: pointer;
- background: $light-color;
- }
- &::-moz-range-thumb {
- height: 12px;
- width: 12px;
- border: 1px solid $intermediate-color;
- border-radius: 6px;
- background: $light-color;
- cursor: pointer;
- -webkit-appearance: none;
- margin-top: -4px;
- }
- }
- input[type="text"] {
- border: none;
- padding: 0 0px;
- background: transparent;
- color: $dark-color;
- font-size: 12px;
- margin-top: 4px;
- }
- .ink-panel {
- margin: 6px 12px 6px 0;
- height: 30px;
- vertical-align: middle;
- line-height: 36px;
- padding: 0 10px;
- color: $intermediate-color;
- &:first {
- margin-top: 0;
- }
- }
- .ink-tools {
- display: flex;
- background-color: transparent;
- border-radius: 0;
- padding: 0;
- button {
- height: 36px;
- padding: 0px;
- padding-bottom: 3px;
- margin-left: 10px;
- background-color: transparent;
- color: $intermediate-color;
- }
- button:hover {
- transform: scale(1.15);
- }
- }
- .ink-size {
- display: flex;
- justify-content: space-between;
- input[type="text"] {
- width: 42px;
- }
- >* {
- margin-right: 6px;
- &:last-child {
- margin-right: 0;
- }
- }
- }
- .ink-color {
- display: flex;
- position: relative;
- padding-right: 0;
- label {
- margin-right: 6px;
- }
- .ink-color-display {
- border-radius: 11px;
- width: 22px;
- height: 22px;
- margin-top: 6px;
- cursor: pointer;
- text-align: center; // span {
- // color: $light-color;
- // font-size: 8px;
- // user-select: none;
- // }
- }
- .ink-color-picker {
- background-color: $light-color;
- border-radius: 5px;
- padding: 12px;
- position: absolute;
- bottom: 36px;
- left: -3px;
- box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw;
- }
- }
-} \ No newline at end of file
diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx
index 8fb74ec48..a971264b9 100644
--- a/src/client/views/InkingCanvas.tsx
+++ b/src/client/views/InkingCanvas.tsx
@@ -57,51 +57,62 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
}
@action
- handleMouseDown = (e: React.PointerEvent): void => {
- if (e.button != 0 ||
+ onPointerDown = (e: React.PointerEvent): void => {
+ this._isDrawing = false;
+ if (e.button != 0 || e.altKey || e.ctrlKey ||
InkingControl.Instance.selectedTool === InkTool.None) {
return;
}
- e.stopPropagation()
- if (InkingControl.Instance.selectedTool === InkTool.Eraser) {
- return
- }
- const point = this.relativeCoordinatesForEvent(e);
-
- // start the new line, saves a uuid to represent the field of the stroke
- this._idGenerator = Utils.GenerateGuid();
- this.inkData.set(this._idGenerator,
- {
- pathData: [point],
- color: InkingControl.Instance.selectedColor,
- width: InkingControl.Instance.selectedWidth,
- tool: InkingControl.Instance.selectedTool,
- page: this.props.Document.GetNumber(KeyStore.CurPage, -1)
- });
+ document.addEventListener("pointermove", this.onPointerMove, true);
+ document.addEventListener("pointerup", this.onPointerUp, true);
+ e.stopPropagation();
+
this._isDrawing = true;
+ if (InkingControl.Instance.selectedTool != InkTool.Eraser) {
+ const point = this.relativeCoordinatesForEvent(e.clientX, e.clientY);
+
+ // start the new line, saves a uuid to represent the field of the stroke
+ this._idGenerator = Utils.GenerateGuid();
+ this.inkData.set(this._idGenerator,
+ {
+ pathData: [point],
+ color: InkingControl.Instance.selectedColor,
+ width: InkingControl.Instance.selectedWidth,
+ tool: InkingControl.Instance.selectedTool,
+ page: this.props.Document.GetNumber(KeyStore.CurPage, -1)
+ });
+ }
}
- @action
- handleMouseMove = (e: React.PointerEvent): void => {
- if (!this._isDrawing ||
- InkingControl.Instance.selectedTool === InkTool.None) {
- return;
+ onPointerUp = (e: PointerEvent): void => {
+ if (this._isDrawing) {
+ document.removeEventListener("pointermove", this.onPointerMove);
+ document.removeEventListener("pointerup", this.onPointerUp);
+ this._isDrawing = false;
+ e.stopPropagation();
}
- e.stopPropagation()
- if (InkingControl.Instance.selectedTool === InkTool.Eraser) {
- return
- }
- const point = this.relativeCoordinatesForEvent(e);
+ }
- // add points to new line as it is being drawn
- let data = this.inkData;
- let strokeData = data.get(this._idGenerator);
- if (strokeData) {
- strokeData.pathData.push(point);
- data.set(this._idGenerator, strokeData);
+ @action
+ onPointerMove = (e: PointerEvent): void => {
+ if (this._isDrawing) {
+ e.stopPropagation()
+ e.preventDefault();
+ if (InkingControl.Instance.selectedTool === InkTool.Eraser) {
+ return
+ }
+ const point = this.relativeCoordinatesForEvent(e.clientX, e.clientY);
+
+ // add points to new line as it is being drawn
+ let data = this.inkData;
+ let strokeData = data.get(this._idGenerator);
+ if (strokeData) {
+ strokeData.pathData.push(point);
+ data.set(this._idGenerator, strokeData);
+ }
+
+ this.inkData = data;
}
-
- this.inkData = data;
}
@action
@@ -109,8 +120,8 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
this._isDrawing = false;
}
- relativeCoordinatesForEvent = (e: React.MouseEvent): { x: number, y: number } => {
- let [x, y] = this.props.getScreenTransform().transformPoint(e.clientX, e.clientY);
+ 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 };
@@ -124,32 +135,9 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
}
render() {
- // styling for cursor
- let canvasStyle = {};
- if (InkingControl.Instance.selectedTool === InkTool.None) {
- canvasStyle = { pointerEvents: "none" };
- } else {
- canvasStyle = { pointerEvents: "auto", cursor: "crosshair" };
- }
-
- // get data from server
- // let inkField = this.props.Document.GetT(KeyStore.Ink, InkField);
- // if (!inkField || inkField == FieldWaiting) {
- // return (<div className="inking-canvas" style={canvasStyle}
- // onMouseDown={this.handleMouseDown} onMouseMove={this.handleMouseMove} >
- // <svg>
- // </svg>
- // </div >)
- // }
-
- let lines = this.inkData;
-
// parse data from server
- let paths: Array<JSX.Element> = []
let curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1)
- Array.from(lines).map(item => {
- let id = item[0];
- let strokeData = item[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}
@@ -157,13 +145,16 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
width={strokeData.width}
tool={strokeData.tool}
deleteCallback={this.removeLine} />)
- })
+ return paths;
+ }, [] as JSX.Element[]);
+ let svgCanvasStyle = InkingControl.Instance.selectedTool == InkTool.None ? "-none" : "";
return (
- <div className="inking-canvas" style={canvasStyle} onPointerDown={this.handleMouseDown} onPointerMove={this.handleMouseMove} >
- <svg>
+ <div className="inkingCanvas" >
+ <svg className={`inkingCanvas-paths${svgCanvasStyle}`} onPointerDown={this.onPointerDown} >
{paths}
</svg>
+ {this.props.children}
</div >
)
}
diff --git a/src/client/views/InkingControl.scss b/src/client/views/InkingControl.scss
new file mode 100644
index 000000000..0d8fd8784
--- /dev/null
+++ b/src/client/views/InkingControl.scss
@@ -0,0 +1,135 @@
+@import "global_variables";
+.inking-control {
+ position: absolute;
+ left: 70px;
+ bottom: 70px;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ label,
+ input,
+ option {
+ font-size: 12px;
+ }
+ input[type="range"] {
+ -webkit-appearance: none;
+ background-color: transparent;
+ vertical-align: middle;
+ margin-top: 8px;
+ &:focus {
+ outline: none;
+ }
+ &::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 3px;
+ border-radius: 1.5px;
+ cursor: pointer;
+ background: $intermediate-color;
+ }
+ &::-webkit-slider-thumb {
+ height: 12px;
+ width: 12px;
+ border: 1px solid $intermediate-color;
+ border-radius: 6px;
+ background: $light-color;
+ cursor: pointer;
+ -webkit-appearance: none;
+ margin-top: -4px;
+ }
+ &::-moz-range-track {
+ width: 100%;
+ height: 3px;
+ border-radius: 1.5px;
+ cursor: pointer;
+ background: $light-color;
+ }
+ &::-moz-range-thumb {
+ height: 12px;
+ width: 12px;
+ border: 1px solid $intermediate-color;
+ border-radius: 6px;
+ background: $light-color;
+ cursor: pointer;
+ -webkit-appearance: none;
+ margin-top: -4px;
+ }
+ }
+ input[type="text"] {
+ border: none;
+ padding: 0 0px;
+ background: transparent;
+ color: $dark-color;
+ font-size: 12px;
+ margin-top: 4px;
+ }
+ .ink-panel {
+ margin: 6px 12px 6px 0;
+ height: 30px;
+ vertical-align: middle;
+ line-height: 36px;
+ padding: 0 10px;
+ color: $intermediate-color;
+ &:first {
+ margin-top: 0;
+ }
+ }
+ .ink-tools {
+ display: flex;
+ background-color: transparent;
+ border-radius: 0;
+ padding: 0;
+ button {
+ height: 36px;
+ padding: 0px;
+ padding-bottom: 3px;
+ margin-left: 10px;
+ background-color: transparent;
+ color: $intermediate-color;
+ }
+ button:hover {
+ transform: scale(1.15);
+ }
+ }
+ .ink-size {
+ display: flex;
+ justify-content: space-between;
+ input[type="text"] {
+ width: 42px;
+ }
+ >* {
+ margin-right: 6px;
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+ .ink-color {
+ display: flex;
+ position: relative;
+ padding-right: 0;
+ label {
+ margin-right: 6px;
+ }
+ .ink-color-display {
+ border-radius: 11px;
+ width: 22px;
+ height: 22px;
+ margin-top: 6px;
+ cursor: pointer;
+ text-align: center; // span {
+ // color: $light-color;
+ // font-size: 8px;
+ // user-select: none;
+ // }
+ }
+ .ink-color-picker {
+ background-color: $light-color;
+ border-radius: 5px;
+ padding: 12px;
+ position: absolute;
+ bottom: 36px;
+ left: -3px;
+ box-shadow: $intermediate-color 0.2vw 0.2vw 0.8vw;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index eb2172d03..c1519dff8 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -2,10 +2,9 @@ import { observable, action, computed } from "mobx";
import { CirclePicker, ColorResult } from 'react-color'
import React = require("react");
-import "./InkingCanvas.scss"
import { InkTool } from "../../fields/InkField";
import { observer } from "mobx-react";
-import "./InkingCanvas.scss"
+import "./InkingControl.scss"
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPen, faHighlighter, faEraser, faBan } from '@fortawesome/free-solid-svg-icons';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
index 9af0df7f5..4341c82f7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.scss
@@ -4,4 +4,7 @@
width: 20000px;
height: 20000px;
pointer-events: none;
+ }
+ .collectionfreeformlinksview-container {
+ pointer-events: none;
} \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index ea392eaea..ef60aa672 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -94,9 +94,12 @@ export class CollectionFreeFormLinksView extends React.Component<CollectionViewP
render() {
return (
- <svg className="collectionfreeformlinksview-svgCanvas">
- {this.uniqueConnections.map(c => <CollectionFreeFormLinkView key={Utils.GenerateGuid()} A={c.a} B={c.b} LinkDocs={c.l} />)}
+ <div className="collectionfreeformlinksview-container">
+ <svg className="collectionfreeformlinksview-svgCanvas">
+ {this.uniqueConnections.map(c => <CollectionFreeFormLinkView key={Utils.GenerateGuid()} A={c.a} B={c.b} LinkDocs={c.l} />)}
+ </svg>
{this.props.children}
- </svg>);
+ </div>
+ );
}
} \ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index c979b27a9..81d21d89a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -7,9 +7,6 @@
width: 100%;
height: 100%;
transform-origin: left top;
- .inking-canvas {
- transform-origin: 50000px 50000px;
- }
}
.collectionfreeformview-container {
.collectionfreeformview > .jsx-parser {
@@ -18,9 +15,6 @@
width: 100%;
}
- .inking-canvas {
- transform-origin: 50000px 50000px;
- }
//nested freeform views
// .collectionfreeformview-container {
// background-image: linear-gradient(to right, $light-color-secondary 1px, transparent 1px),
@@ -48,10 +42,6 @@
background: $light-color-secondary;
}
- .inking-canvas {
- transform-origin: 50000px 50000px;
- }
-
opacity: 0.99;
border: 0px solid transparent;
border-radius: $border-radius;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index cdc5bdfb0..ae1c775e6 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -314,16 +314,18 @@ export class CollectionFreeFormView extends CollectionViewBase {
<div className={`collectionfreeformview${this.isAnnotationOverlay ? "-overlay" : "-container"}`}
onPointerDown={this.onPointerDown} onPointerMove={(e) => super.setCursorPosition(this.getTransform().transformPoint(e.clientX, e.clientY))}
onDrop={this.onDrop.bind(this)} onDragOver={this.onDragOver} onWheel={this.onPointerWheel}
- style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} tabIndex={0} ref={this.createDropTarget}>
+ style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px` }} ref={this.createDropTarget}>
<MarqueeView container={this} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments}
addDocument={this.addDocument} removeDocument={this.props.removeDocument} addLiveTextDocument={this.addLiveTextBox}
getContainerTransform={this.getContainerTransform} getTransform={this.getTransform}>
<div className="collectionfreeformview" ref={this._canvasRef}
style={{ transform: `translate(${dx}px, ${dy}px) scale(${this.zoomScaling}, ${this.zoomScaling}) translate(${panx}px, ${pany}px)` }}>
{this.backgroundView}
- <CollectionFreeFormLinksView {...this.props} />
- {this.views}
- <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} />
+ <CollectionFreeFormLinksView {...this.props}>
+ <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} >
+ {this.views}
+ </InkingCanvas>
+ </CollectionFreeFormLinksView>
{super.getCursors().map(entry => {
if (entry.Data.length > 0) {
let id = entry.Data[0][0];
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 7f951864e..d52b662bd 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -1,4 +1,4 @@
-import { computed, trace, reaction, runInAction, observable } from "mobx";
+import { computed } from "mobx";
import { observer } from "mobx-react";
import { KeyStore } from "../../../fields/KeyStore";
import { NumberField } from "../../../fields/NumberField";
@@ -6,8 +6,7 @@ import { Transform } from "../../util/Transform";
import { DocumentView, DocumentViewProps } from "./DocumentView";
import "./DocumentView.scss";
import React = require("react");
-import { Document } from "../../../fields/Document";
-import { DocumentManager } from "../../util/DocumentManager";
+import { thisExpression } from "babel-types";
@observer
@@ -75,6 +74,7 @@ export class CollectionFreeFormDocumentView extends React.Component<DocumentView
<div className="collectionFreeFormDocumentView-container" ref={this._mainCont} style={{
transformOrigin: "left top",
transform: this.transform,
+ pointerEvents: "all",
width: this.width,
height: this.height,
position: "absolute",
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index e273b0b4f..28a1f9757 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -87,7 +87,7 @@ export class PDFBox extends React.Component<FieldViewProps> {
@observable private _interactive: boolean = false;
@observable private _loaded: boolean = false;
- @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, -1); }
+ @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, 1); }
@computed private get thumbnailPage() { return this.props.doc.GetNumber(KeyStore.ThumbnailPage, -1); }
componentDidMount() {
@@ -435,8 +435,6 @@ export class PDFBox extends React.Component<FieldViewProps> {
@computed
get pdfContent() {
let page = this.curPage;
- if (page == 0)
- page = 1;
const renderHeight = 2400;
let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField);
let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight;
@@ -463,10 +461,8 @@ export class PDFBox extends React.Component<FieldViewProps> {
return [
this._pageInfo.area.filter(() => this._pageInfo.area).map((element: any) => element),
this._currAnno.map((element: any) => element),
- <div key="pdfBox-contentShell">
- {this.pdfContent}
- {proxy}
- </div>
+ this.pdfContent,
+ proxy
];
}