aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/MarqueeAnnotator.tsx5
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.tsx1
-rw-r--r--src/client/views/nodes/ImageBox.tsx6
-rw-r--r--src/client/views/nodes/PDFBox.scss11
-rw-r--r--src/client/views/nodes/PDFBox.tsx34
-rw-r--r--src/client/views/nodes/VideoBox.tsx1
-rw-r--r--src/client/views/nodes/WebBox.tsx1
-rw-r--r--src/client/views/pdf/PDFViewer.tsx25
8 files changed, 48 insertions, 36 deletions
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index fa1123a2d..02516264c 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -15,18 +15,19 @@ import './MarqueeAnnotator.scss';
import { DocumentView } from './nodes/DocumentView';
import { ObservableReactComponent } from './ObservableReactComponent';
import { AnchorMenu } from './pdf/AnchorMenu';
+import { Transform } from '../util/Transform';
export interface MarqueeAnnotatorProps {
Document: Doc;
down?: number[];
scrollTop: number;
- isNativeScaled?: boolean;
scaling?: () => number;
annotationLayerScaling?: () => number;
annotationLayerScrollTop: number;
containerOffset?: () => number[];
marqueeContainer: HTMLDivElement;
docView: () => DocumentView;
+ screenTransform: () => Transform;
savedAnnotations: () => ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]>;
selectionText: () => string;
annotationLayer: HTMLDivElement;
@@ -157,7 +158,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
// 4) reattach the vector to the center of the bounding box
getTransformedScreenPt = (down: number[]) => {
const { marqueeContainer } = this.props;
- const containerXf = this.props.isNativeScaled ? this.props.docView().screenToContentsTransform() : this.props.docView().screenToViewTransform();
+ const containerXf = this.props.screenTransform();
const boundingRect = marqueeContainer.getBoundingClientRect();
const center = { x: boundingRect.x + boundingRect.width / 2, y: boundingRect.y + boundingRect.height / 2 };
const downVec = Utils.rotPt(down[0] - center.x,
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 7026c3b01..b874d077b 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -832,6 +832,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
annotationLayerScrollTop={NumCast(this.Document._layout_scrollTop)}
scaling={returnOne}
docView={this.DocumentView}
+ screenTransform={this.DocumentView().screenToViewTransform}
addDocument={this.sidebarAddDocument}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotations}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 423a73f44..de8a9ad21 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -39,7 +39,6 @@ import { FocusViewOptions } from './FocusViewOptions';
import './ImageBox.scss';
import { OpenWhere } from './OpenWhere';
import { Upload } from '../../../server/SharedMediaTypes';
-import { ImageUtils } from '../../util/Import & Export/ImageUtils';
export class ImageEditorData {
// eslint-disable-next-line no-use-before-define
@@ -268,7 +267,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const anchy = NumCast(cropping.y);
const anchw = NumCast(cropping._width);
const anchh = NumCast(cropping._height);
- const viewScale = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']) / anchw;
+ const viewScale = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']) / anchh;
cropping.title = 'crop: ' + this.Document.title;
cropping.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width);
cropping.y = NumCast(this.Document.y);
@@ -286,9 +285,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
croppingProto.data_nativeWidth = anchw;
croppingProto.data_nativeHeight = anchh;
croppingProto.freeform_scale = viewScale;
- croppingProto.freeform_scale_min = viewScale;
croppingProto.freeform_panX = anchx / viewScale;
croppingProto.freeform_panY = anchy / viewScale;
+ croppingProto.freeform_scale_min = viewScale;
croppingProto.freeform_panX_min = anchx / viewScale;
croppingProto.freeform_panX_max = anchw / viewScale;
croppingProto.freeform_panY_min = anchy / viewScale;
@@ -593,6 +592,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
annotationLayerScrollTop={0}
scaling={returnOne}
annotationLayerScaling={this._props.NativeDimScaling}
+ screenTransform={this.DocumentView().screenToViewTransform}
docView={this.DocumentView}
addDocument={this.addDocument}
finishMarquee={this.finishMarquee}
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index 7bca1230f..f6908d5fd 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -250,6 +250,17 @@
cursor: ew-resize;
background: lightGray;
}
+.pdfBox-container {
+ position: absolute;
+ transform-origin: top left;
+ top: 0;
+}
+.pdfBox-sidebarContainer {
+ position: absolute;
+ height: 100%;
+ right: 0;
+ top: 0;
+}
.pdfBox-interactive {
width: 100%;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 1de4d2512..06b75e243 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as Pdfjs from 'pdfjs-dist';
import 'pdfjs-dist/web/pdf_viewer.css';
@@ -40,8 +40,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(PDFBox, fieldKey);
}
+ static pdfcache = new Map<string, Pdfjs.PDFDocumentProxy>();
+ static pdfpromise = new Map<string, Promise<Pdfjs.PDFDocumentProxy>>();
public static openSidebarWidth = 250;
public static sidebarResizerWidth = 5;
+
private _searchString: string = '';
private _initialScrollTarget: Opt<Doc>;
private _pdfViewer: PDFViewer | undefined;
@@ -63,11 +66,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200;
!this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw));
if (this.pdfUrl) {
- if (PDFBox.pdfcache.get(this.pdfUrl.url.href))
- runInAction(() => {
- this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href);
- });
- else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href))
+ this._pdf = PDFBox.pdfcache.get(this.pdfUrl.url.href);
+ !this._pdf &&
PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(
action(pdf => {
this._pdf = pdf;
@@ -265,12 +265,12 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
};
@action
- loaded = (nw: number, nh: number, np: number) => {
- this.dataDoc[this._props.fieldKey + '_numPages'] = np;
- Doc.SetNativeWidth(this.dataDoc, Math.max(Doc.NativeWidth(this.dataDoc), nw));
- Doc.SetNativeHeight(this.dataDoc, nh);
+ loaded = (p: { width: number; height: number }, pages: number) => {
+ this.dataDoc[this._props.fieldKey + '_numPages'] = pages;
+ Doc.SetNativeWidth(this.dataDoc, Math.max(Doc.NativeWidth(this.dataDoc), p.width));
+ Doc.SetNativeHeight(this.dataDoc, p.height);
this.layoutDoc._height = NumCast(this.layoutDoc._width) / (Doc.NativeAspect(this.dataDoc) || 1);
- !this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw));
+ !this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (p.height / p.width));
};
override search = action((searchString: string, bwd?: boolean, clear: boolean = false) => {
@@ -596,13 +596,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}}>
<div className="pdfBox-background" onPointerDown={e => this.sidebarBtnDown(e, false)} />
<div
+ className="pdfBox-container"
style={{
width: `calc(${100 / viewScale}% - ${(this.sidebarWidth() / viewScale) * (this._previewWidth ? viewScale : 1)}px)`,
height: `${100 / viewScale}%`,
transform: `scale(${viewScale})`,
- position: 'absolute',
- transformOrigin: 'top left',
- top: 0,
}}>
<PDFViewer
{...this._props}
@@ -615,7 +613,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
focus={this.focus}
url={this.pdfUrl!.url.pathname}
anchorMenuClick={this.anchorMenuClick}
- loaded={!Doc.NativeAspect(this.dataDoc) ? this.loaded : undefined}
+ loaded={Doc.NativeAspect(this.dataDoc) ? emptyFunction : this.loaded}
setPdfViewer={this.setPdfViewer}
addDocument={this.addDocument}
moveDocument={this.moveDocument}
@@ -624,14 +622,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
crop={this.crop}
/>
</div>
- <div style={{ position: 'absolute', height: '100%', right: 0, top: 0, width: `calc(100 * ${this.sidebarWidth() / this._props.PanelWidth()}%` }}>{this.sidebarCollection}</div>
+ <div className="pdfBox-sidebarContainer" style={{ width: `calc(100 * ${this.sidebarWidth() / this._props.PanelWidth()}%` }}>
+ {this.sidebarCollection}
+ </div>
{this.settingsPanel()}
</div>
);
}
- static pdfcache = new Map<string, Pdfjs.PDFDocumentProxy>();
- static pdfpromise = new Map<string, Promise<Pdfjs.PDFDocumentProxy>>();
render() {
TraceMobx();
const pdfView = !this._pdf ? null : this.renderPdfView;
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 3bf7de2fe..9adee53e8 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -1023,6 +1023,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
scaling={returnOne}
annotationLayerScaling={this._props.NativeDimScaling}
docView={this.DocumentView}
+ screenTransform={this.DocumentView().screenToViewTransform}
containerOffset={this.marqueeOffset}
addDocument={this.addDocWithTimecode}
finishMarquee={this.finishMarquee}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index ffeb574e9..6026d9ca7 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1196,6 +1196,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
scaling={this._props.NativeDimScaling}
addDocument={this.addDocumentWrapper}
docView={this.DocumentView}
+ screenTransform={this.DocumentView().screenToViewTransform}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotationsCreator}
selectionText={this.selectionText}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 722492e8d..ca7f72811 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -30,6 +30,7 @@ import { GPTPopup } from './GPTPopup/GPTPopup';
import './PDFViewer.scss';
import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT';
import ReactLoading from 'react-loading';
+import { Transform } from '../../util/Transform';
interface IViewerProps extends FieldViewProps {
pdfBox: PDFBox;
@@ -40,7 +41,7 @@ interface IViewerProps extends FieldViewProps {
pdf: Pdfjs.PDFDocumentProxy;
url: string;
sidebarAddDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean;
- loaded?: (nw: number, nh: number, np: number) => void;
+ loaded: (p: { width: number; height: number }, pages: number) => void;
// eslint-disable-next-line no-use-before-define
setPdfViewer: (view: PDFViewer) => void;
anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
@@ -151,24 +152,21 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
}
initialLoad = () => {
+ const page0or180 = (page: { rotate: number }) => page.rotate === 0 || page.rotate === 180;
if (this._pageSizes.length === 0) {
const devicePixelRatio = window.devicePixelRatio;
document.documentElement?.style.setProperty('--devicePixelRatio', window.devicePixelRatio.toString()); // set so that css can use this to adjust various PDFJs divs
Promise.all(
numberRange(this._props.pdf.numPages).map(i =>
- this._props.pdf.getPage(i + 1).then(page => {
- const page0or180 = page.rotate === 0 || page.rotate === 180;
- return {
- width: page.view[page0or180 ? 2 : 3] * devicePixelRatio - page.view[page0or180 ? 0 : 1] * devicePixelRatio,
- height: page.view[page0or180 ? 3 : 2] * devicePixelRatio - page.view[page0or180 ? 1 : 0] * devicePixelRatio,
- };
- })
+ this._props.pdf.getPage(i + 1).then(page => ({
+ width: (page.view[page0or180(page) ? 2 : 3] - page.view[page0or180(page) ? 0 : 1]) * devicePixelRatio,
+ height: (page.view[page0or180(page) ? 3 : 2] - page.view[page0or180(page) ? 1 : 0]) * devicePixelRatio,
+ }))
)
).then(
action(pages => {
this._pageSizes = pages;
- const lastPage = pages.lastElement();
- this._props.loaded?.(lastPage.width, lastPage.height, this._props.pdf.numPages);
+ this._props.loaded(pages.lastElement(), this._props.pdf.numPages);
this.createPdfViewer();
})
);
@@ -599,6 +597,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
}
savedAnnotations = () => this._savedAnnotations;
addDocumentWrapper = (doc: Doc | Doc[]) => this._props.addDocument!(doc);
+ screenToMarqueeXf = () => this.props.pdfBox.DocumentView?.()?.screenToContentsTransform().scale(Pdfjs.PixelsPerInch.PDF_TO_CSS_UNITS) ?? Transform.Identity();
render() {
TraceMobx();
return (
@@ -618,17 +617,17 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
{this.annotationLayer}
{this.overlayLayer}
{this._showWaiting ? <img alt="" className="pdfViewerDash-waiting" src="/assets/loading.gif" /> : null}
- {!this._mainCont.current || !this._annotationLayer.current ? null : (
+ {!this._mainCont.current || !this._annotationLayer.current || !this.props.pdfBox.DocumentView ? null : (
<MarqueeAnnotator
ref={this._marqueeref}
Document={this._props.Document}
getPageFromScroll={this.getPageFromScroll}
anchorMenuClick={this._props.anchorMenuClick}
scrollTop={0}
- isNativeScaled
annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)}
addDocument={this.addDocumentWrapper}
- docView={this._props.pdfBox.DocumentView!}
+ docView={this.props.pdfBox.DocumentView}
+ screenTransform={this.screenToMarqueeXf}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotations}
selectionText={this.selectionText}