From b96281d18a9c4ca0ea7f8360d7f69d12c325fada Mon Sep 17 00:00:00 2001 From: yipstanley Date: Tue, 11 Jun 2019 19:02:00 -0400 Subject: pin annotations --- src/client/views/nodes/PDFBox.tsx | 1 + src/client/views/pdf/PDFViewer.tsx | 136 +++++++++++++++++++++++++++++-------- src/client/views/pdf/Page.tsx | 4 +- 3 files changed, 110 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index de75c67cf..5b118185b 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -50,6 +50,7 @@ export class PDFBox extends DocComponent(PdfDocumen trace(); // uses mozilla pdf as default const pdfUrl = Cast(this.props.Document.data, PdfField, new PdfField(window.origin + RouteStore.corsProxy + "/https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf")); + console.log(pdfUrl); let classname = "pdfBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !this._alt ? "-interactive" : ""); return (
{ @action componentDidMount() { const pdfUrl = this.props.url; + console.log("pdf starting to load") let promise = Pdfjs.getDocument(pdfUrl).promise; promise.then((pdf: Pdfjs.PDFDocumentProxy) => { - runInAction(() => this._pdf = pdf); + runInAction(() => { + console.log("pdf url received"); + this._pdf = pdf; + }); }); } @@ -77,8 +85,16 @@ class Viewer extends React.Component { @observable private _annotations: Doc[] = []; private _pageBuffer: number = 1; + private _annotationLayer: React.RefObject; private _reactionDisposer?: IReactionDisposer; private _annotationReactionDisposer?: IReactionDisposer; + private _pagesLoaded: number = 0; + + constructor(props: IViewerProps) { + super(props); + + this._annotationLayer = React.createRef(); + } componentDidMount = () => { let wasSelected = this.props.parent.props.isSelected(); @@ -112,8 +128,9 @@ class Viewer extends React.Component { ); } - // On load, render pdf - setTimeout(() => this.renderPages(this.startIndex, this.endIndex, true), 1000); + setTimeout(() => { + this.renderPages(this.startIndex, this.endIndex, true); + }, 1000); } componentWillUnmount = () => { @@ -150,7 +167,7 @@ class Viewer extends React.Component { } @computed get endIndex(): number { - let width = this._pageSizes.map(i => i.width); + let width = this._pageSizes.map(i => i ? i.width : 0); return Math.min(this.props.pdf ? this.props.pdf.numPages - 1 : 0, this.getIndex(this.scrollY + Math.max(...width)) + this._pageBuffer); } @@ -185,6 +202,10 @@ class Viewer extends React.Component { return; } + if (this._pageSizes.length !== numPages) { + this._pageSizes = new Array(numPages).map(i => ({ width: 0, height: 0 })); + } + // this is only for an initial render to get all of the pages rendered if (this._visibleElements.length !== numPages) { let divs = Array.from(Array(numPages).keys()).map(i => ( @@ -248,14 +269,14 @@ class Viewer extends React.Component { return; } - createPinAnnotation = (x: number, y: number): void => { - let targetDoc = Docs.TextDocument({ title: "New Pin Annotation" }); + createPinAnnotation = (x: number, y: number, page: number): void => { + let targetDoc = Docs.TextDocument({ width: 100, height: 50, title: "New Pin Annotation" }); let pinAnno = new Doc(); pinAnno.x = x; pinAnno.y = y; pinAnno.width = pinAnno.height = PinRadius; - pinAnno.page = this.getIndex(y); + pinAnno.page = page; pinAnno.target = targetDoc; pinAnno.type = AnnotationTypes.Pin; // this._annotations.push(pinAnno); @@ -301,18 +322,18 @@ class Viewer extends React.Component { } let numPages = this.props.pdf ? this.props.pdf.numPages : 0; this.props.loaded(page.width, page.height); - if (index > this._pageSizes.length) { - this._pageSizes.push({ width: page.width, height: page.height }); - } - else { - this._pageSizes[index - 1] = { width: page.width, height: page.height }; - } - if (index === numPages) { + this._pageSizes[index - 1] = { width: page.width, height: page.height }; + this._pagesLoaded++; + if (this._pagesLoaded === numPages) { this._loaded = true; let divs = Array.from(Array(numPages).keys()).map(i => (
)); this._visibleElements = new Array(...divs); + // On load, render pdf + // setTimeout(() => { + this.renderPages(this.startIndex, this.endIndex, true); + // }, 1000); } } @@ -332,21 +353,38 @@ class Viewer extends React.Component { let type = NumCast(anno.type); switch (type) { case AnnotationTypes.Pin: - return ; + return ; case AnnotationTypes.Region: - return ; + return ; default: return
; } } + onDrop = (e: React.DragEvent) => { + console.log("Dropped!"); + } + + // ScreenToLocalTransform = (): Transform => { + // if (this._annotationLayer.current) { + // let boundingRect = this._annotationLayer.current.getBoundingClientRect(); + // let x = boundingRect.left; + // let y = boundingRect.top; + // let scale = NumCast(this.props.parent.Document.nativeWidth) / boundingRect.width; + // let t = new Transform(x, y, scale); + // return t; + // } + // return Transform.Identity(); + // } + render() { + trace(); return ( -
+
{this._visibleElements}
-
+
{this._annotations.map(anno => this.renderAnnotation(anno))}
@@ -365,25 +403,65 @@ interface IAnnotationProps { y: number; width: number; height: number; + parent: Viewer; document: Doc; } +@observer class PinAnnotation extends React.Component { - @observable private _backgroundColor: string = "red"; + @observable private _backgroundColor: string = "green"; + @observable private _display: string = "initial"; - pointerDown = (e: React.PointerEvent) => { + private _selected: boolean = true; + @action + pointerDown = (e: React.PointerEvent) => { + if (this._selected) { + this._backgroundColor = "red"; + this._display = "none"; + this._selected = false; + } + else { + this._backgroundColor = "green"; + this._display = "initial"; + this._selected = true; + } + e.preventDefault(); + e.stopPropagation(); } render() { - let targetDoc = Cast(this.props.document.targetDoc, Doc, Docs.TextDocument({ title: "New Pin Annotation" })); - return ( -
- {/* */} -
- ); + let targetDoc = Cast(this.props.document.target, Doc); + if (targetDoc instanceof Doc) { + return ( +
+
+ 1} + PanelWidth={() => NumCast(this.props.parent.props.parent.Document.nativeWidth)} + PanelHeight={() => NumCast(this.props.parent.props.parent.Document.nativeHeight)} + focus={emptyFunction} + selectOnLoad={false} + parentActive={this.props.parent.props.parent.props.active} + whenActiveChanged={this.props.parent.props.parent.props.whenActiveChanged} + bringToFront={emptyFunction} + addDocTab={this.props.parent.props.parent.props.addDocTab} + /> +
+
+ ); + } + return null; } } diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index fe7369aeb..73a7a93a0 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -23,7 +23,7 @@ interface IPageProps { pageLoaded: (index: number, page: Pdfjs.PDFPageViewport) => void; parent: PDFBox; renderAnnotations: (annotations: Doc[], removeOld: boolean) => void; - makePin: (x: number, y: number) => void; + makePin: (x: number, y: number, page: number) => void; } @observer @@ -378,7 +378,7 @@ export default class Page extends React.Component { let boundingRect = current.getBoundingClientRect(); let x = (e.clientX - boundingRect.left) * (current.offsetWidth / boundingRect.width); let y = (e.clientY - boundingRect.top) * (current.offsetHeight / boundingRect.height); - this.props.makePin(x, y); + this.props.makePin(x, y, this.props.page); } } -- cgit v1.2.3-70-g09d2