diff options
Diffstat (limited to 'src/client/views/nodes/ImageBox.tsx')
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 89 |
1 files changed, 50 insertions, 39 deletions
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 6913dfbc7..d668d332b 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -66,7 +66,7 @@ const uploadIcons = { @observer export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageDocument>(ImageDocument) { - protected multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined; + protected _multiTouchDisposer?: import("../../util/InteractionUtils").InteractionUtils.MultiTouchEventDisposer | undefined; public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ImageBox, fieldKey); } private _imgRef: React.RefObject<HTMLImageElement> = React.createRef(); private _dropDisposer?: DragManager.DragDropDisposer; @@ -120,7 +120,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD }); const files = await res.json(); const url = Utils.prepend(files[0].path); - // upload to server with known URL + // upload to server with known URL const audioDoc = Docs.Create.AudioDocument(url, { title: "audio test", _width: 200, _height: 32 }); audioDoc.treeViewExpandedView = "layout"; const audioAnnos = Cast(this.dataDoc[this.fieldKey + "-audioAnnotations"], listSpec(Doc)); @@ -157,42 +157,40 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD const field = Cast(this.dataDoc[this.fieldKey], ImageField); if (field) { const funcs: ContextMenuProps[] = []; - funcs.push({ description: "Rotate", event: this.rotate, icon: "expand-arrows-alt" }); - funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" }); - funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" }); - // funcs.push({ - // description: "Reset Native Dimensions", event: action(async () => { - // const curNW = NumCast(this.dataDoc[this.fieldKey + "-nativeWidth"]); - // const curNH = NumCast(this.dataDoc[this.fieldKey + "-nativeHeight"]); - // if (this.props.PanelWidth() / this.props.PanelHeight() > curNW / curNH) { - // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelHeight() * curNW / curNH; - // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelHeight(); - // } else { - // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelWidth(); - // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelWidth() * curNH / curNW; - // } - // }), icon: "expand-arrows-alt" - // }); - - const existingAnalyze = ContextMenu.Instance.findByDescription("Analyzers..."); - const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : []; - modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" }); - modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" }); - //modes.push({ description: "Recommend", event: this.extractText, icon: "brain" }); - !existingAnalyze && ContextMenu.Instance.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" }); - - ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); - - - const existingMore = ContextMenu.Instance.findByDescription("More..."); - const mores: ContextMenuProps[] = existingMore && "subitems" in existingMore ? existingMore.subitems : []; - !existingMore && ContextMenu.Instance.addItem({ description: "More...", subitems: mores, icon: "hand-point-right" }); + funcs.push({ description: "Rotate Clockwise 90", event: this.rotate, icon: "expand-arrows-alt" }); + funcs.push({ description: "Make Background", event: () => this.layoutDoc.isBackground = true, icon: "expand-arrows-alt" }); + if (!Doc.UserDoc().noviceMode) { + funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" }); + funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" }); + // funcs.push({ + // description: "Reset Native Dimensions", event: action(async () => { + // const curNW = NumCast(this.dataDoc[this.fieldKey + "-nativeWidth"]); + // const curNH = NumCast(this.dataDoc[this.fieldKey + "-nativeHeight"]); + // if (this.props.PanelWidth() / this.props.PanelHeight() > curNW / curNH) { + // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelHeight() * curNW / curNH; + // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelHeight(); + // } else { + // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelWidth(); + // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelWidth() * curNH / curNW; + // } + // }), icon: "expand-arrows-alt" + // }); + + const existingAnalyze = ContextMenu.Instance?.findByDescription("Analyzers..."); + const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : []; + modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" }); + modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" }); + //modes.push({ description: "Recommend", event: this.extractText, icon: "brain" }); + !existingAnalyze && ContextMenu.Instance?.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" }); + } + + ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); } } extractFaces = () => { const converter = (results: any) => { - return results.map((face: CognitiveServices.Image.Face) => Docs.Get.FromJson({ data: face, title: `Face: ${face.faceId}` })!); + return results.map((face: CognitiveServices.Image.Face) => Doc.Get.FromJson({ data: face, title: `Face: ${face.faceId}` })!); }; this.url && CognitiveServices.Image.Appliers.ProcessImage(this.dataDoc, [this.fieldKey + "-faces"], this.url, Service.Face, converter); } @@ -241,6 +239,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD if (this._curSuffix === "_m") this._mediumRetryCount++; if (this._curSuffix === "_l") this._largeRetryCount++; } + @action onError = (error: any) => { const timeout = this._curSuffix === "_s" ? this._smallRetryCount : this._curSuffix === "_m" ? this._mediumRetryCount : this._largeRetryCount; if (timeout < 5) { @@ -317,7 +316,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD considerGooglePhotosLink = () => { const remoteUrl = this.dataDoc.googlePhotosUrl; - return !remoteUrl ? (null) : (<img + return !remoteUrl ? (null) : (<img draggable={false} style={{ transform: `scale(${this.props.ContentScaling()})`, transformOrigin: "bottom right" }} id={"google-photos"} src={"/assets/google_photos.png"} @@ -342,7 +341,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD } return ( <img - id={"upload-icon"} + id={"upload-icon"} draggable={false} style={{ transform: `scale(${1 / this.props.ContentScaling()})`, transformOrigin: "bottom right" }} src={`/assets/${this.uploadIcon}`} onClick={async () => { @@ -401,12 +400,23 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD const aspect = (rotation % 180) ? nativeHeight / nativeWidth : 1; const shift = (rotation % 180) ? (nativeHeight - nativeWidth) * (1 - 1 / aspect) : 0; this.resize(srcpath); + let transformOrigin = "center center"; + let transform = `translate(0%, 0%) rotate(${rotation}deg) scale(${aspect})`; + if (rotation === 90 || rotation === -270) { + transformOrigin = "top left"; + transform = `translate(100%, 0%) rotate(${rotation}deg) scale(${aspect})`; + } else if (rotation === 180) { + transform = `rotate(${rotation}deg) scale(${aspect})`; + } else if (rotation === 270 || rotation === -90) { + transformOrigin = "right top"; + transform = `translate(-100%, 0%) rotate(${rotation}deg) scale(${aspect})`; + } return <div className="imageBox-cont" key={this.layoutDoc[Id]} ref={this.createDropTarget}> <div className="imageBox-fader" > <img key={this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys src={srcpath} - style={{ transform: `scale(${aspect}) translate(0px, ${shift}px) rotate(${rotation}deg)` }} + style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} ref={this._imgRef} onError={this.onError} /> @@ -414,7 +424,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD <img className="imageBox-fadeaway" key={"fadeaway" + this._smallRetryCount + (this._mediumRetryCount << 4) + (this._largeRetryCount << 8)} // force cache to update on retrys src={fadepath} - style={{ transform: `translate(0px, ${shift}px) rotate(${rotation}deg) scale(${aspect})`, }} + style={{ transform, transformOrigin }} draggable={false} width={nativeWidth} ref={this._imgRef} onError={this.onError} /></div>} @@ -452,7 +462,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD TraceMobx(); return (<div className={`imageBox`} onContextMenu={this.specificContextMenu} style={{ - transform: this.props.PanelWidth() ? `translate(0px, ${this.ycenter}px)` : `scale(${this.props.ContentScaling()})`, + transform: this.props.PanelWidth() ? undefined : `scale(${this.props.ContentScaling()})`, width: this.props.PanelWidth() ? undefined : `${100 / this.props.ContentScaling()}%`, height: this.props.PanelWidth() ? undefined : `${100 / this.props.ContentScaling()}%`, pointerEvents: this.layoutDoc.isBackground ? "none" : undefined, @@ -478,9 +488,10 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD CollectionView={undefined} ScreenToLocalTransform={this.screenToLocalTransform} renderDepth={this.props.renderDepth + 1} + docFilters={this.props.docFilters} ContainingCollectionDoc={this.props.ContainingCollectionDoc}> {this.contentFunc} </CollectionFreeFormView> </div >); } -}
\ No newline at end of file +} |