aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/pdf/PDFViewer.scss6
-rw-r--r--src/client/views/pdf/PDFViewer.tsx76
-rw-r--r--src/client/views/pdf/Page.tsx44
3 files changed, 81 insertions, 45 deletions
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index cb1aef410..831e6add1 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -28,4 +28,10 @@
position: absolute;
background-color: red;
opacity: 0.1;
+}
+
+.pdfViewer-annotationLayer {
+ position: absolute;
+ top: 0;
+ overflow: visible hidden;
} \ No newline at end of file
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 0a6886878..1152587a4 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -2,11 +2,12 @@ import { observer } from "mobx-react";
import React = require("react");
import { observable, action, runInAction, computed, IReactionDisposer, reaction } from "mobx";
import * as Pdfjs from "pdfjs-dist";
-import { Opt } from "../../../new_fields/Doc";
+import { Opt, HeightSym, WidthSym, Doc, DocListCast } from "../../../new_fields/Doc";
import "./PDFViewer.scss";
import "pdfjs-dist/web/pdf_viewer.css";
import { PDFBox } from "../nodes/PDFBox";
import Page from "./Page";
+import { NumCast } from "../../../new_fields/Types";
interface IPDFViewerProps {
url: string;
@@ -65,9 +66,11 @@ class Viewer extends React.Component<IViewerProps> {
@observable private _endIndex: number = 1;
@observable private _loaded: boolean = false;
@observable private _pdf: Opt<Pdfjs.PDFDocumentProxy>;
+ @observable private _annotations: Doc[] = [];
private _pageBuffer: number = 1;
private _reactionDisposer?: IReactionDisposer;
+ private _annotationReactionDisposer?: IReactionDisposer;
componentDidMount = () => {
let wasSelected = this.props.parent.props.isSelected();
@@ -88,6 +91,19 @@ class Viewer extends React.Component<IViewerProps> {
{ fireImmediately: true }
);
+ if (this.props.parent.Document) {
+ this._annotationReactionDisposer = reaction(
+ () => DocListCast(this.props.parent.Document.annotations),
+ () => {
+ let annotations = DocListCast(this.props.parent.Document.annotations);
+ if (annotations && annotations.length) {
+ this.renderAnnotations(annotations, true);
+ }
+ },
+ { fireImmediately: true }
+ );
+ }
+
// On load, render pdf
setTimeout(() => this.renderPages(this.startIndex, this.endIndex, true), 1000);
}
@@ -96,6 +112,9 @@ class Viewer extends React.Component<IViewerProps> {
if (this._reactionDisposer) {
this._reactionDisposer();
}
+ if (this._annotationReactionDisposer) {
+ this._annotationReactionDisposer();
+ }
}
@action
@@ -135,6 +154,17 @@ class Viewer extends React.Component<IViewerProps> {
}
}
+ @action
+ private renderAnnotations = (annotations: Doc[], removeOldAnnotations: boolean): void => {
+ if (removeOldAnnotations) {
+ this._annotations = annotations;
+ }
+ else {
+ this._annotations.push(...annotations);
+ this._annotations = new Array<Doc>(...this._annotations);
+ }
+ }
+
/**
* @param startIndex: where to start rendering pages
* @param endIndex: where to end rendering pages
@@ -158,6 +188,7 @@ class Viewer extends React.Component<IViewerProps> {
name={`${this.props.pdf ? this.props.pdf.fingerprint + `-page${i + 1}` : "undefined"}`}
pageLoaded={this.pageLoaded}
parent={this.props.parent}
+ renderAnnotations={this.renderAnnotations}
{...this.props} />
));
let arr = Array.from(Array(numPages).keys()).map(() => false);
@@ -194,6 +225,7 @@ class Viewer extends React.Component<IViewerProps> {
name={`${this.props.pdf ? this.props.pdf.fingerprint + `-page${i + 1}` : "undefined"}`}
pageLoaded={this.pageLoaded}
parent={this.props.parent}
+ renderAnnotations={this.renderAnnotations}
{...this.props} />
);
this._isPage[i] = true;
@@ -247,11 +279,49 @@ class Viewer extends React.Component<IViewerProps> {
}
}
+ getPageHeight = (index: number): number => {
+ let counter = 0;
+ if (this.props.pdf && index < this.props.pdf.numPages) {
+ for (let i = 0; i < index; i++) {
+ if (this._pageSizes[i]) {
+ counter += this._pageSizes[i].height;
+ }
+ }
+ }
+ return counter;
+ }
+
render() {
return (
- <div className="viewer">
- {this._visibleElements}
+ <div>
+ <div className="viewer">
+ {this._visibleElements}
+ </div>
+ <div className="pdfViewer-annotationLayer" style={{ height: this.props.parent.Document.nativeHeight }}>
+ <div className="pdfViewer-annotationLayer-subCont" style={{ transform: `translateY(${-this.scrollY}px)` }}>
+ {this._annotations.map(anno => <RegionAnnotation x={NumCast(anno.x)} y={NumCast(anno.y) + this.getPageHeight(NumCast(anno.page))} width={anno[WidthSym]()} height={anno[HeightSym]()} />)}
+ </div>
+ </div>
</div>
);
}
}
+
+interface IAnnotation {
+ x: number;
+ y: number;
+ width: number;
+ height: number;
+}
+
+class RegionAnnotation extends React.Component<IAnnotation> {
+ onPointerDown = (e: React.PointerEvent) => {
+ console.log("clicked!");
+ }
+
+ render() {
+ return (
+ <div className="pdfViewer-annotationBox" onPointerDown={this.onPointerDown} style={{ top: this.props.y, left: this.props.x, width: this.props.width, height: this.props.height }}></div>
+ );
+ }
+} \ No newline at end of file
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 5269f448b..5738889c4 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -21,6 +21,7 @@ interface IPageProps {
page: number;
pageLoaded: (index: number, page: Pdfjs.PDFPageViewport) => void;
parent: PDFBox;
+ renderAnnotations: (annotations: Doc[], removeOld: boolean) => void;
}
@observer
@@ -35,7 +36,6 @@ export default class Page extends React.Component<IPageProps> {
@observable private _marqueeWidth: number = 0;
@observable private _marqueeHeight: number = 0;
@observable private _rotate: string = "";
- @observable private _annotations: Doc[] = [];
private _canvas: React.RefObject<HTMLCanvasElement>;
private _textLayer: React.RefObject<HTMLDivElement>;
@@ -60,19 +60,6 @@ export default class Page extends React.Component<IPageProps> {
if (this.props.pdf) {
this.update(this.props.pdf);
- if (this.props.parent.Document) {
- this._reactionDisposer = reaction(
- () => DocListCast(this.props.parent.Document.annotations),
- () => {
- let annotations = DocListCast(this.props.parent.Document.annotations);
- if (annotations && annotations.length) {
- annotations = annotations.filter(anno => NumCast(anno.page) === this.props.page);
- this.renderAnnotations(annotations, true);
- }
- },
- { fireImmediately: true }
- );
- }
}
}
@@ -109,17 +96,6 @@ export default class Page extends React.Component<IPageProps> {
}
@action
- private renderAnnotations = (annotations: Doc[], removeOldAnnotations: boolean): void => {
- if (removeOldAnnotations) {
- this._annotations = annotations;
- }
- else {
- this._annotations.push(...annotations);
- this._annotations = new Array<Doc>(...this._annotations);
- }
- }
-
- @action
private renderPage = (page: Pdfjs.PDFPageProxy): void => {
// lower scale = easier to read at small sizes, higher scale = easier to read at large sizes
let scale = 2;
@@ -407,30 +383,14 @@ export default class Page extends React.Component<IPageProps> {
<div className="canvasContainer">
<canvas ref={this._canvas} />
</div>
- <div className="pdfAnnotationLayer-cont" ref={this._annotationLayer} style={{ width: "100%", height: "100%", position: "relative", top: "-100%" }}>
+ <div className="pdfInkingLayer-cont" ref={this._annotationLayer} style={{ width: "100%", height: "100%", position: "relative", top: "-100%" }}>
<div className="pdfViewer-annotationBox" ref={this._marquee}
style={{ left: `${this._marqueeX}px`, top: `${this._marqueeY}px`, width: `${this._marqueeWidth}px`, height: `${this._marqueeHeight}px`, background: "transparent" }}>
<img ref={this._curly} src="https://static.thenounproject.com/png/331760-200.png" style={{ width: "100%", height: "100%", transform: `${this._rotate}` }} />
</div>
- {this._annotations.map(anno => <RegionAnnotation x={NumCast(anno.x)} y={NumCast(anno.y)} width={anno[WidthSym]()} height={anno[HeightSym]()} />)}
</div>
<div className="textlayer" ref={this._textLayer} style={{ "position": "relative", "top": `-${2 * this._height}px`, "height": `${this._height}px` }} />
</div>
);
}
}
-
-interface IAnnotation {
- x: number;
- y: number;
- width: number;
- height: number;
-}
-
-class RegionAnnotation extends React.Component<IAnnotation> {
- render() {
- return (
- <div className="pdfViewer-annotationBox" style={{ top: this.props.y, left: this.props.x, width: this.props.width, height: this.props.height }}></div>
- );
- }
-} \ No newline at end of file