diff options
| author | bobzel <zzzman@gmail.com> | 2024-01-03 13:23:14 -0500 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-01-03 13:23:14 -0500 |
| commit | 3f7b73ee8a3f75cd688ee7ddc7b54d90b00bee67 (patch) | |
| tree | 7334d2d4ce886b4ba990cab45d3945fc62502eef /src/client/views/MarqueeAnnotator.tsx | |
| parent | af42d3061bd85907e3d987f0d794c250cfaded1c (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.tsx | 29 |
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 |
