aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/MarqueeAnnotator.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-01-03 13:23:14 -0500
committerbobzel <zzzman@gmail.com>2024-01-03 13:23:14 -0500
commit3f7b73ee8a3f75cd688ee7ddc7b54d90b00bee67 (patch)
tree7334d2d4ce886b4ba990cab45d3945fc62502eef /src/client/views/MarqueeAnnotator.tsx
parentaf42d3061bd85907e3d987f0d794c250cfaded1c (diff)
fixed marquee annotator for lightbox with pdf and rotated documents.
Diffstat (limited to 'src/client/views/MarqueeAnnotator.tsx')
-rw-r--r--src/client/views/MarqueeAnnotator.tsx29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 3eb43dacf..9f3786d8e 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -22,11 +22,12 @@ export interface MarqueeAnnotatorProps {
Document: Doc;
down?: number[];
scrollTop: number;
+ isNativeScaled?: boolean;
scaling?: () => number;
annotationLayerScaling?: () => number;
annotationLayerScrollTop: number;
containerOffset?: () => number[];
- mainCont: HTMLDivElement;
+ marqueeContainer: HTMLDivElement;
docView: () => DocumentView;
savedAnnotations: () => ObservableMap<number, HTMLDivElement[]>;
selectionText: () => string;
@@ -147,20 +148,28 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
savedAnnotations.set(page, savedPage ?? [div]);
});
+ // this transforms a screen point into a local coordinate subject. It's complicated by documents that are rotated
+ // since the DOM's bounding rectangle is not rotated and Dash's ScreenToLocalTransform carries along a rotation value, but doesn't
+ // use it when transforming points.
+ // So the idea here is to reconstruct a local point by unrotating the screen point about the center of the bounding box. The approach is:
+ // 1) Get vector from the screen point to the center of the rotated bounding box in screens space
+ // 2) unrotate that vector in screen space
+ // 3) localize the unrotated vector by scaling into the marquee container's coordinates
+ // 4) reattach the vector to the center of the bounding box
getTransformedScreenPt = (down: number[]) => {
- const boundingRect = this.props.mainCont.getBoundingClientRect();
+ const marqueeContainer = this.props.marqueeContainer;
+ const containerXf = this.props.isNativeScaled ? this.props.docView().screenToNativeLocalTransform() : this.props.docView().props.ScreenToLocalTransform();
+ const boundingRect = marqueeContainer.getBoundingClientRect();
const center = { x: boundingRect.x + boundingRect.width / 2, y: boundingRect.y + boundingRect.height / 2 };
- const downPt = Utils.rotPt(down[0] - center.x, down[1] - center.y, NumCast(this.props.docView().screenToLocalTransform().Rotate));
- const scale = this.props.docView().props.ScreenToLocalTransform().Scale;
- const scalex = this.props.mainCont.offsetWidth / NumCast(this.props.Document.width);
- const scaley = this.props.mainCont.offsetHeight / NumCast(this.props.Document.height);
- // set marquee x and y positions to the spatially transformed position
- return { x: scalex * (downPt.x + NumCast(this.props.Document.width) / scale / 2) * scale,
- y: scaley * (downPt.y + NumCast(this.props.Document.height) / scale / 2) * scale + this.props.annotationLayerScrollTop }; // prettier-ignore
+ const downVec = Utils.rotPt(down[0] - center.x,
+ down[1] - center.y, NumCast(containerXf.Rotate)); // prettier-ignore
+ return { x: downVec.x * containerXf.Scale + marqueeContainer.offsetWidth /2,
+ y: downVec.y * containerXf.Scale + marqueeContainer.offsetHeight/2 + this.props.annotationLayerScrollTop }; // prettier-ignore
};
@action
public onInitiateSelection(down: number[]) {
+ console.log('DOWN = ' + down[0] + ' ' + down[1]);
this._width = this._height = 0;
this._start = this.getTransformedScreenPt(down);
@@ -242,7 +251,7 @@ export class MarqueeAnnotator extends ObservableReactComponent<MarqueeAnnotatorP
@action
onSelectEnd = (e: PointerEvent) => {
e.stopPropagation();
- const marquees = this.props.mainCont.getElementsByClassName('marqueeAnnotator-dragBox');
+ const marquees = this.props.marqueeContainer.getElementsByClassName('marqueeAnnotator-dragBox');
const marqueeStyle = (Array.from(marquees).lastElement() as HTMLDivElement)?.style;
if (!this.isEmpty && marqueeStyle) {
// configure and show the annotation/link menu if a the drag region is big enough